The BEST way to proxy your API in Nuxt

Поделиться
HTML-код
  • Опубликовано: 25 июл 2024
  • ➡️ Proxying routes to your back-end or third party APIs is a common practice! Over the last two years, various strategies came up in Nuxt. But not all of them work equally will. To figure out which two strategies are the recommended ones, we have a look at the four most common strategies, their shortcomings and which ones I would recommend to use!
    Key points:
    ✅ How a successful proxy strategy looks like
    🔢 All common strategies - From Vite's proxy to a Nitro proxy endpoint
    ‼️ Which strategies to use and how to implement them
    Links:
    📺 Nuxt vs. Nitro: • Nuxt vs. Nitro - What ...
    🔗 GH discussion around proxying: github.com/nuxt/nuxt/discussi...
    📺 Common runtimeConfig mistakes: • Nuxt's runtimeConfig -...
    🔗 H3 JSDoc: www.jsdocs.io/package/h3
    🔗 Code: github.com/manniL/alexander-l...
    Don't forget to hit that "Subscribe" button, ring the notification bell and give a thumbs up!
    🌐 Connect further:
    Website: www.lichter.io
    Twitter/X: / thealexlichter
    Twitch: / thealexlichter
    Chapters:
    00:00 Intro
    00:54 Discussion around proxying
    01:30 Setup & demo app
    02:57 Goals for our proxy solution
    04:14 Strategy 1 - Vite's proxy
    07:30 Strategy 2 - Nitro's devProxy
    10:16 Strategy 3 - Proxy routeRule
    13:30 Strategy 4 - Nitro proxy API endpoint
    19:28 Summary and what to use
  • НаукаНаука

Комментарии • 138

  • @TheAlexLichter
    @TheAlexLichter  6 месяцев назад +3

    Which strategy did you use so far? Any plans to switch now? 🙊

    • @moosesaid
      @moosesaid 6 месяцев назад +1

      Hey Alex, great work on your videos! Like your explanations so much
      But I guess there is another way to do this from Nuxt modules, right? Access `useRuntimeConfig()` from there and tweak routeRules.

    • @TheAlexLichter
      @TheAlexLichter  6 месяцев назад +1

      Hey Mostafa! Thanks 🙏🏻
      Interesting idea. I think it might but haven’t tried it yet. Will report back when I did! 👌🏻

    • @djpunisha29
      @djpunisha29 Месяц назад

      funny, no strategy works on my project :|
      any chance of reaching out to you? google meet call?

  • @ammarmughal91
    @ammarmughal91 6 месяцев назад +7

    I wish i was taught everything by you it would have saved me a lot of time. Great video!

    • @TheAlexLichter
      @TheAlexLichter  6 месяцев назад +1

      Thank you 🙏🏻
      No worries, more content is in the making 😊
      Is there anything specific that you want to learn about?

  • @chstappert
    @chstappert 6 месяцев назад +1

    This is very important and a pretty good idea ;-). Looking forward to implement!

  • @TheLoGgIDK
    @TheLoGgIDK 6 месяцев назад +2

    I needed this video a month ago, but nice to see that it is finely here . ^_^

    • @TheAlexLichter
      @TheAlexLichter  6 месяцев назад

      That’s unfortunate 🙈
      Anything you are stumped about right now though?

  • @laurencebarnes1322
    @laurencebarnes1322 6 месяцев назад

    Thank you for helping us understand why the other options didn't work, and how / why nitro work. I must admit I forgot to include the `server: true` prop in the $fetch options, and when testing the production version, the proxy wasn't working. Thankfully I realised my mistake and now everything is working smoothly finally!

    • @TheAlexLichter
      @TheAlexLichter  6 месяцев назад +2

      You are very welcome! Yeah, I only mentioned the "server: true" part (it is the default though) for useFetch, so that's a tiny bit on me. Glad it worked though 🙏

  • @olatunjiolakunle6908
    @olatunjiolakunle6908 6 месяцев назад +1

    Another good video. Thanks Alex.

  • @FrontendDays
    @FrontendDays 6 месяцев назад +1

    Thanks for the solution! You helped me a lot

    • @TheAlexLichter
      @TheAlexLichter  6 месяцев назад

      Glad to hear that! You are welcome ☺️🙌🏻

  • @hamedfaryabi1030
    @hamedfaryabi1030 6 месяцев назад +1

    Perfect solution! Thanks

  • @RIT_Edition
    @RIT_Edition 6 месяцев назад +8

    Please create a video to protect the server API endpoint from direct calls from other websites. Eg - Allow access to certain domains, and cors, add authentication and more security feature

  • @honzamrazek8581
    @honzamrazek8581 3 месяца назад

    Thank you for your content Alex, it is most helpful with my Bachelor thesis.💪

    • @TheAlexLichter
      @TheAlexLichter  3 месяца назад +2

      Glad to help! What are you writing about (also just finished my "master-equivalent" thesis)?

    • @honzamrazek8581
      @honzamrazek8581 3 месяца назад

      @@TheAlexLichter I am rewriting a section in one of the systems we use at school. It serves as a portal for submitting team projects that are divided into iterations. We are currently migrating from Django to .NET Core backend and Nuxt on frontend.
      I have to say that comming from Next.js, the DX of Nuxt combined with Nuxt UI is something else. It is amazing and I am very glad we chose this tech stack. It has an amazing community.
      What was your thesis about?

  • @timostolz
    @timostolz 3 месяца назад +2

    Thank you very much, this helps me a lot. Still, I need to know how to proxy websockets.

  • @oleggerasymeko676
    @oleggerasymeko676 2 месяца назад +1

    oh, wow. This is really helpful.

  • @Agboihip
    @Agboihip 6 месяцев назад +3

    Nice work, thanks.
    So far I call external api directly. But with your proxy approach now, how to deal with the authorisation, to serve the api token as the same time securing routers with middleware ? Do I use both server and application middlewares, bearer token saved in pinia’s store.

    • @TheAlexLichter
      @TheAlexLichter  6 месяцев назад +1

      Thanks 🙏🏻
      Yes, you'd call e.g. a `/api/XYZ` endpoint which is the shown Nitro proxy endpoint and ensure that the headers (e.g. for auth) are present in that call. `proxyRequest` will forward all headers automatically (except some ignored ones. - github.com/unjs/h3/blob/53703dc860f1ff6fe7ce71d543deff1cfa810b11/src/utils/proxy.ts#L24-L31)!

  • @SKOTSKOT
    @SKOTSKOT 15 дней назад

    Great video. could i also do this to proxy websocket endpoint ?

  • @dennismaa1103
    @dennismaa1103 3 месяца назад

    Hey Alex, thanks for the really informative and well explained video. I have one more question though, how would you handle the case where I only want to have this proxy during development. So I only use it to handle cors and cookie issues, but I don't need/want to have this proxy in production stage because that would mean an additional, unnecessary load on the server.

    • @TheAlexLichter
      @TheAlexLichter  2 месяца назад

      Use the env aware config - ruclips.net/video/DFZI2iVCrNc/видео.html

  • @user-qb7yc3qg3b
    @user-qb7yc3qg3b 10 дней назад

    what i can do if i have custom $fetch plugin, with base api url, JWT tokens, but i want to proxy it through nitro for some security reasons and send user-agent and ip to api?

  • @dexterstm
    @dexterstm 6 месяцев назад +4

    Another great video Alex, just a question, if I'm proxying my request to an external backend endpoint and I'm required to pass a Authorization Header. How should I go about implementing this? , will proxyRequest forwards the headers as well?

    • @TheAlexLichter
      @TheAlexLichter  6 месяцев назад

      Yes, it will! Compared to another helper called `sendProxy`, `proxyRequest` will merge the request headers for us. This happens here in the code: github.com/unjs/h3/blob/53703dc860f1ff6fe7ce71d543deff1cfa810b11/src/utils/proxy.ts#L54-L70

    • @dexterstm
      @dexterstm 6 месяцев назад

      @@TheAlexLichter Nice! another question, how would i set the Authorization Bearer Header?
      I tried using the setHeader helper but it didn't work.
      setHeader(event, 'Authorization', 'Bearer )

    • @TheAlexLichter
      @TheAlexLichter  6 месяцев назад

      I think you can set it through the 3rd parameter of proxyRequest via { headers: { Authorization: ‘token here' } }

  • @tomasprieto9746
    @tomasprieto9746 6 месяцев назад +1

    Great clip

  • @sushant_
    @sushant_ День назад

    Dont know why its not working in my case, I am using server/routes/[...].ts as my apis doesnt begin with api. It will also work in the same way right?

  • @youhan96
    @youhan96 3 месяца назад

    Thanks Alex. I used the routeRules proxy on my project couple month ago. I have a env variable on Vercel which is set to different URL for prod and preview, and routeRule proxy uses that. Do you suggest using runtimeConfig method for that?

    • @TheAlexLichter
      @TheAlexLichter  3 месяца назад

      Yes, absolutely! RuntimeConfig is the best option here 👌🏻

  • @Tarabass
    @Tarabass 6 месяцев назад +1

    Nice! Thx :)
    Offtipc; What I still hate about routerules is that headers are set only for response headers.

    • @TheAlexLichter
      @TheAlexLichter  6 месяцев назад +1

      You are welcome!
      I think that is a good candidate for a feature request issue 😁

    • @Tarabass
      @Tarabass 6 месяцев назад +1

      ​@@TheAlexLichter
      Again? I see a pattern lol 😅
      Will do, NP. Tomorrow 🎉

    • @TheAlexLichter
      @TheAlexLichter  6 месяцев назад

      @Tarabass good ideas = good issues I’d say 😁

    • @Tarabass
      @Tarabass 6 месяцев назад +1

      @@TheAlexLichter Issue #24971 opened

  • @bratiche
    @bratiche 6 месяцев назад +3

    Great video! i just have one question, what would be the advantages of proxying our requests vs calling the api directly?

    • @TheAlexLichter
      @TheAlexLichter  6 месяцев назад +3

      Avoid CORS and „hide“ the backend urls.
      Also load balancing and co if you have multiple URLs

    • @RockGonzo17
      @RockGonzo17 6 месяцев назад

      I've also added some more use cases in my comment if you want to check it out. :)

  • @saidinusah
    @saidinusah 4 месяца назад

    Hi, does the work in production mode? I tried the vite server approach last week but it didn't work in production. I proxied the API was due to an SSL certificate validation error.

    • @TheAlexLichter
      @TheAlexLichter  4 месяца назад

      Yes, the two shown techniques at the end work in prod :)

  • @silvesterwali6565
    @silvesterwali6565 6 месяцев назад

    Thank you for the great videos. Can you make a video on how to handle the auth with a proxy...

    • @TheAlexLichter
      @TheAlexLichter  6 месяцев назад

      I’ll add it to the list! Anything to cover specifically with regards to proxy and auth?

    • @silvesterwali6565
      @silvesterwali6565 6 месяцев назад

      @@TheAlexLichter maybe you have an idea how proxy handle token to passing every request.so on the frontend useFetch and $fetch will be clean. I'm using Laravel as an API. So far i end up using composable to manually handle authentication in every request like redirect ..get the token from cookies..and i think this is verbose . It will help if you have an idea for this

  • @oyedeji.oyewole
    @oyedeji.oyewole 6 месяцев назад +2

    Please can you explain what island components are, why and if we should use them?

    • @TheAlexLichter
      @TheAlexLichter  6 месяцев назад

      Is on the list for next year 🙌🏻

  • @oiluis
    @oiluis Месяц назад

    Hey Alex! Great stuff as usual! Let me know if I am overthinking, but after reading all comments I didn’t see any mentions on performance. Let’s suppose I have a backend API on another server / port written on another language / framework than ts & nuxt … if I understood your approach correctly after implementing it on my app you just added a simple proxy that forwards the request to “maybe” another proxy or whatsoever … wouldn’t be faster / easier to just create a custom fetch wrapper that uses nuxt config to point to the “right” proxy? For me the proposed approach seems to be another layer / bottleneck that can potentially generate errors or who knows what in a scenario of high volume of transactions… am I missing something here?

    • @TheAlexLichter
      @TheAlexLichter  Месяц назад

      Hey Luis! Thanks for the comment.
      Perf-wise, the overhead should be rather small + you *can* also apply route rules or custom caching to it to even improve performance! A good example @ x.com/Atinux/status/1798294901559546038
      But if you don't need the proxy (no caching wanted, no CORS issues etc. etc.) you are free to not proxy at all 👌

    • @oiluis
      @oiluis Месяц назад

      @@TheAlexLichter thank you for your prompt response … when you say
      “You are free to not proxy at all”
      This means that having a useCustomFetch with baseapi + headers rewrite seems to be a good option?

    • @TheAlexLichter
      @TheAlexLichter  Месяц назад

      Sure, you can hit the API directly + set the headers you need, absolutely

  • @CharlesCurrierR
    @CharlesCurrierR 6 месяцев назад +1

    What approach would you recommend for transforming the data received from the proxy. I tried saving the result of proxyRequest to a local variable, and returning something else but the data I get from the API route is always the data from proxyRequest.

    • @TheAlexLichter
      @TheAlexLichter  6 месяцев назад +1

      In this case you might consider using $fetch explicitly and transform the data afterwards 😊

  • @arnaudkinnoudo3351
    @arnaudkinnoudo3351 2 месяца назад

    Thank you for this great content.
    Please I remark that proxyRequest doesn't handle well the 422 errors from an external api. It returns 200 status code. Is there a way to handle that ?

    • @TheAlexLichter
      @TheAlexLichter  2 месяца назад +1

      That sounds like a bug! Can you reproduce that and raise an issue in the h3 repo?

  • @ericpodhorecki3593
    @ericpodhorecki3593 15 часов назад

    Will these techniques pass along any cookies that exist for the /api url ? If you have /api/login proxied to another api that actually handle the login. How will cookies be ahndled ? Cookies are super important but nobody seem to explain how to handle them !

  • @Tarabass
    @Tarabass 6 месяцев назад +1

    @TheAlexLichter
    What about putting the endpoint not in the `api` folder but instead put it in the `routes` folder? In that way there's no need for replacing 'api'.
    For me it's very unclear what the routes folder is all about. In some video's it's used to return html, strings and stuff.

    • @TheAlexLichter
      @TheAlexLichter  6 месяцев назад +1

      Would also work! I’ll make a video about that 🙊

    • @Tarabass
      @Tarabass 6 месяцев назад

      @@TheAlexLichter you're the best!

  • @Thr0nSK
    @Thr0nSK 6 месяцев назад +2

    What are the performance implications of using nuxt proxying, as opposed to calling the external backend endpoints directly?

    • @TheAlexLichter
      @TheAlexLichter  6 месяцев назад +1

      Should be a rather small overhead, especially because you commonly have to deal with CORS otherwise 👌🏻

    • @RIT_Edition
      @RIT_Edition 6 месяцев назад

      @@TheAlexLichter What if someone our proxied URL from different domain?

    • @TheAlexLichter
      @TheAlexLichter  6 месяцев назад

      You mean what if someone accesses that URL from another project?
      Well, then you could eg blacklist the IP (or domain)

    • @RIT_Edition
      @RIT_Edition 6 месяцев назад

      @@TheAlexLichter Instead of blacklisting how to allow access to certain domains or IP

  • @TheVlads
    @TheVlads 5 месяцев назад

    thank you for the explanation.. but how if we have more than one proxy base url? thank you

    • @TheAlexLichter
      @TheAlexLichter  5 месяцев назад

      No problem! Then add them both via runtimeConfig and choose the "correct one" based on your criteria, e.g. the URL path

  • @jingwang-0811
    @jingwang-0811 6 месяцев назад

    very nice!!

  • @adrianpdm
    @adrianpdm 3 месяца назад

    in a deployment platform like Railway, where cpu and egress is billed, wouldnt this result in unnecessary cost?

    • @TheAlexLichter
      @TheAlexLichter  3 месяца назад

      It’d be count into bandwidth, yes. CPU minimally, that should be negligible.

  • @conan_fans
    @conan_fans 3 месяца назад

    right on ❤‍🔥

  • @Mikhail_Kominov
    @Mikhail_Kominov 6 месяцев назад +1

    Alexander, will there be a video about caching nitro?

    • @TheAlexLichter
      @TheAlexLichter  6 месяцев назад

      Yes Mikhail, that's still on my list 😋

  • @sania3631
    @sania3631 6 месяцев назад +1

    Great video... thanks! I am wondering if it is possible to implement it with Apollo graphql.

    • @TheAlexLichter
      @TheAlexLichter  6 месяцев назад +1

      Yes, absolutely. I wouldn't see why not 😊

    • @sania3631
      @sania3631 6 месяцев назад

      @@TheAlexLichter I am using Apollo inside the Pinia store. Am I supposed to run it on the proxied server?

    • @TheAlexLichter
      @TheAlexLichter  6 месяцев назад +1

      @sania3631 not sure I understand. When you use Apollo, do you need a store then?
      Probably Nuxt GQL client would be a bit more lightweight. Then, use the path you wanna proxy as endpoint

    • @RockGonzo17
      @RockGonzo17 6 месяцев назад +1

      If you want to proxy requests to a GraphQL backend, that definitely works. You basically create the proxy and tell your Apollo client that the httpEndpoint is your proxy (instead of the URL to the actual GraphQL backend). I did that in a project and that works just fine.

  • @thibaultfae5589
    @thibaultfae5589 Месяц назад

    Thanks a lot for your video, helped me a lot but I have an issue for the past days: data are now received in binary instead of plain JSON text. Specifying the encoding helped me but I don't think this is the correct approach, any ideas ?

    • @TheAlexLichter
      @TheAlexLichter  Месяц назад

      Does the API set the correct „content-type“ header?

    • @thibaultfae5589
      @thibaultfae5589 Месяц назад

      @@TheAlexLichter thanks for your answer, it is a 3rd-party api: content-type is set to application/json
      thanks

    • @TheAlexLichter
      @TheAlexLichter  Месяц назад

      And does the fetch call sets a different `Accept` by any chance? Worst case, you can use $fetch to ensure the responseType will be json ☺️

    • @thibaultfae5589
      @thibaultfae5589 Месяц назад

      @@TheAlexLichter I will check it out, thanks a lot pal

  • @umbrellacoro9953
    @umbrellacoro9953 29 дней назад

    Hi Alex! Thank you for the video. I have a question. When I built a Nuxt 3 app, your strategy 4 did not work with $fetch. It did not replace the API URL. Do you have any suggestions on how to resolve this?

    • @TheAlexLichter
      @TheAlexLichter  29 дней назад

      How do you mean "it did not replace the API URL"? 🤔

    • @umbrellacoro9953
      @umbrellacoro9953 28 дней назад

      "When I make a request, it doesn't replace myProxyUrl with 'xx.xx.xx.xx' in nuxt.config.ts."

    • @umbrellacoro9953
      @umbrellacoro9953 28 дней назад

      @@TheAlexLichter "When I make a request, it doesn't replace myProxyUrl with in nuxt.config.ts."

    • @umbrellacoro9953
      @umbrellacoro9953 28 дней назад

      When I make a request, it doesn't replace myProxyUrl with in nuxt.config

  • @bruno.pbarbosa
    @bruno.pbarbosa 4 месяца назад

    Do you have any special recomendations if we're trying to proxy images and need to pass on auth headers? had this working on a nuxt 2 project but struggling to figure out how to get it going in nuxt 3

    • @TheAlexLichter
      @TheAlexLichter  4 месяца назад +1

      Should work the same way (with a nitro endpoint serving them). If not, hit me up with a "broken" example reproduction :)

    • @bruno.pbarbosa
      @bruno.pbarbosa 4 месяца назад +1

      @@TheAlexLichter Thanks! Managed to get it working, but had to do it differently - added a file to the /server/middleware/ folder, and here it worked (my endpoint isn't called api, so caused some issues figuring why it didn't work). Might be worth noting in case others struggle with the same case :)

  • @nested9301
    @nested9301 6 месяцев назад +1

    can you talk about swr in nuxt thank you great video!

  • @Vladimir-if1uk
    @Vladimir-if1uk 4 месяца назад

    Can we use Nginx to proxy? Is it better? what are the pros and cons

    • @TheAlexLichter
      @TheAlexLichter  4 месяца назад

      Sure, you can use NGINX for proxying! "Better" depends on your need. A simple API proxy should not make a big difference perf-wise but lots of rules could make a difference. Be aware that you still need to set up your dev proxy differently then (e.g. via Nuxt) ☺️

  • @fabricec2074
    @fabricec2074 6 месяцев назад +2

    Could you have used $fetch instead of proxyRequest ?

    • @olatunjiolakunle6908
      @olatunjiolakunle6908 6 месяцев назад +1

      Yes, just add the target as the path, proxyRequest is just help function provided by h3

    • @TheAlexLichter
      @TheAlexLichter  6 месяцев назад +2

      Would work (as commented before)! But proxyRequest passes all the headers and body of the incoming request, which is often desired
      with $fetch it is more like a BFF pattern (fetch + maybe transform the data)

  • @NamNam2412
    @NamNam2412 5 месяцев назад

    it's good for GET request, how about other methods like POST, PUT, DELETE? I've tried, but it's responsed with status 405 METHOD NOT ALLOWED :(

    • @TheAlexLichter
      @TheAlexLichter  5 месяцев назад

      Should also work when not using .get.ts as suffix ☺️

    • @NamNam2412
      @NamNam2412 5 месяцев назад

      @@TheAlexLichter I'm not using .get.ts, just [...] .ts like your video :(

    • @NamNam2412
      @NamNam2412 5 месяцев назад +1

      @@TheAlexLichter oh, my bad, that error is because of my BE response, not because of the proxy, thanks :D

  • @Code2Master
    @Code2Master 6 месяцев назад +1

    thanks man

  • @wailantirajoh3052
    @wailantirajoh3052 6 месяцев назад

    Somehow the [...].ts doesnt work on production build. only works on development mode

    • @TheAlexLichter
      @TheAlexLichter  6 месяцев назад

      How and where do you deploy? 🤔

    • @wailantirajoh3052
      @wailantirajoh3052 6 месяцев назад

      @@TheAlexLichter trying on local using pnpm build and then run `node .output/server/index.mjs`

    • @wailantirajoh3052
      @wailantirajoh3052 6 месяцев назад +1

      @@TheAlexLichter ill try to create minimal reprod latter and submit to nuxt issues i think

    • @wailantirajoh3052
      @wailantirajoh3052 6 месяцев назад +1

      Nevermind, while creating reproduction. it work as expected, let me check my code 🤧

    • @TheAlexLichter
      @TheAlexLichter  6 месяцев назад +1

      That's the best part of reproductions IMO! Happens to me so often 😋

  • @gihandilanka
    @gihandilanka 5 дней назад

    Thanks for the video, getting this 502 error
    at createError (./node_modules/h3/dist/index.mjs:78:15)at sendProxy (./node_modules/h3/dist/index.mjs:1168:11)at process.processTicksAndRejections (node:internal/process/task_queues:95:5)at async ./node_modules/h3/dist/index.mjs:1975:19at async Object.callAsync (./node_modules/unctx/dist/index.mjs:72:16)at async Server.toNodeHandle (./node_modules/h3/dist/index.mjs:2266:7)

    • @TheAlexLichter
      @TheAlexLichter  3 дня назад

      Are you sure that the API to proxy to is available?