Server Actions vs API Route Handlers In Next.js - When To Use Which
Jan 9, 2025 by Florian
I recently got a YouTube comment asking when to use server actions and when to use API route handlers in Next.js.
It's a good question. Because after all, they both create server endpoints where we can access our database and other sensitive resources.
So which one should you use? Do server actions make route handlers obsolete? Not at all!
Let's quickly go through the pros and cons of each:
👍 Server Actions Pros
Easy to create
Just add the "use server"
directive to the top of a function or a whole file. All functions exported from that file are automatically turned into server endpoints:
Arguments and return values are serialized automatically
This is my favorite feature. We don't have to stringify the data we send to server actions or wrap it into FormData. We just pass normal function arguments and they are automatically turned into a format that can be sent over the wire (and then turned back on the other side). This works even for files you send to server actions.
👎 Server Actions Cons
Only POST supported
Server actions are always POST endpoints. This means they are appropriate for creating or updating data (like submitting a new post) but not for fetching new data. That's what the body of server components is for. But if you need to fetch data from a client component, you're out of luck.
They don't create a public API
While it's possible to find out the URL of a server action and call it from a third-party client (I show how to do that here), they are not meant as public endpoints. You can really only call your server actions from your Next.js app. You can't use them as webhooks or as the backend for a mobile app.
Now let's take a look at Next.js route handlers:
👍 Route Handler Pros
All HTTP methods are supported
With route handlers, you can create POST endpoints too, but also GET, DELETE, PUT, and PATCH endpoints. Especially GET is important, because you can use it to fetch data client-side (this is how classic React works).
Note: You could fetch data from a POST endpoint too. But that's not a correct use of HTTP methods. Also, last time I checked, server actions in Next.js didn't run in parallel, making them unsuited for fetching data. That's another reason to stick to the correct HTTP verb.
They are public server endpoints
Next.js route handlers create classic server endpoints that can be reached under a public URL (like https://myapp.com/api/users). This means you can use them for webhooks (see: "What is a webhook") or as the backend for a mobile client.
👎 Route Handler Cons
They require more boilerplate code
Route handlers are more difficult to set up:
First, you create a route.ts file where you export functions for the different HTTP methods you want to use.
Any data you want to send between the front-end and a route handler has to be manually turned into a format like JSON or FormData and then turned back into its original type so that you can use it.
You also have to return a proper HTTP response with a status code.
Note: All of this happens in server actions too, but it's done automatically for you. The price is less flexibility (as explained above).
When to use which?
I use server actions whenever possible. And I try to fetch as much of my data as possible in server components.
I use route handlers for webhooks and when I need to fetch data client-side. A good example is infinite loading lists which can't really be done server-side. Check out my Next.js social media app tutorial to learn how to implement them.
I hope this clarified some questions!
Happy coding!
Florian
I send my best web dev tips to my free email newsletter. Sign up to stay ahead of the curve.
Subscribe Now