The Ultimate API Showdown: Server Actions, tRPC, GraphQL, and REST Compared!

Jack Herrington
20 Nov 202310:49

Summary

TLDRThis video provides a comprehensive comparison of four different paradigms for handling server-side operations in web development: Server Actions, tRPC (TypeSafe Remote Procedure Calls), GraphQL, and REST. The video analyzes various aspects, including ease of setup, ease of use, handling mutations and queries, type safety, compatibility with other clients, and the ability to work without JavaScript enabled. It offers insights into the advantages and disadvantages of each approach, helping developers choose the most suitable option based on their project's requirements. The video ultimately recommends Server Actions for simple web applications, tRPC for supporting mobile or desktop clients, and GraphQL as a viable choice for internal applications, while cautioning against exposing it to the open internet due to potential denial-of-service vulnerabilities.

Takeaways

  • 🔑 Server Actions, tRPC, GraphQL, and REST are four different paradigms for handling client-server communication.
  • 🚀 Server Actions are incredibly easy to set up and use in Next.js 14, but lack robust query capabilities.
  • 🔐 tRPC and GraphQL excel at handling queries, with tRPC being easier to set up and GraphQL providing better type safety through introspection.
  • 📝 Mutations are straightforward with Server Actions, tRPC, and GraphQL, while REST allows more flexibility but lacks standardization.
  • 🧩 Server Actions have limited compatibility with non-web clients, while tRPC and GraphQL offer better interoperability.
  • 🔌 Only Server Actions can work without JavaScript enabled on the client.
  • 🏆 For simple web apps, a combination of Server Actions and React Server Components is recommended.
  • 📱 For apps with mobile or desktop clients, tRPC or GraphQL (for internal apps) are better options.
  • ⚠️ GraphQL has potential for Denial of Service issues and should be used cautiously on the open internet.
  • 🤔 The choice between these paradigms depends on factors like app complexity, client types, and security requirements.

Q & A

  • What is the purpose of this video script?

    -The purpose of this video script is to compare different paradigms for server-client communication, such as server actions, tRPC, GraphQL, and REST, and provide insights into which might be the best choice for a particular project.

  • What are server actions?

    -Server actions are functions defined on the server side that can be invoked from the client. In Next.js 14, they are defined using the `use server` pragma, and the framework manages the communication between the client and server.

  • What is tRPC (TypeSafe Remote Procedure Calls)?

    -tRPC is a protocol that allows defining remote procedure calls that can be exposed by the server. It automatically creates query hooks and handles the marshalling between the API endpoint and the function, sitting on top of HTTP and JSON.

  • What is GraphQL?

    -GraphQL is a query language created by Meta (formerly Facebook) that sits on top of HTTP and JSON. It allows specifying queries or mutations using a well-defined syntax, and the server returns the requested data in JSON format.

  • What is REST (Representational State Transfer)?

    -REST is an architectural style where entities are defined in a hierarchical structure, but it doesn't have strict standards or formality. It relies on different styles and formats for APIs, with tools like OpenAPI and Swagger providing some standardization.

  • Which paradigm is the easiest to set up?

    -According to the script, server actions are the easiest to set up, as they are built into Next.js 14 and require no additional configuration.

  • Which paradigm is the most type-safe?

    -The script suggests that GraphQL has an advantage in terms of type safety due to its introspection capability, which allows clients to request the schema from the server and generate types accordingly.

  • What is the potential issue with GraphQL in terms of queries?

    -The script mentions that with GraphQL, clients can make up any query against the server, which can lead to a denial of service attack if a malicious API request consumes excessive database or server resources.

  • Which paradigm is the most compatible with different clients (e.g., mobile, desktop)?

    -According to the script, GraphQL is the most compatible paradigm due to its standardized format, which allows libraries and clients in different languages and platforms to consume GraphQL APIs efficiently.

  • What is the recommendation for simple Next.js web applications?

    -For simple Next.js web applications, the script recommends using a combination of queries on the server in React Server Components and server actions, as it is the easiest way to go.

Outlines

00:00

🤔 Intro to Server Actions, tRPC, GraphQL, and REST

This paragraph introduces the four different paradigms that will be compared: Server Actions, tRPC (Typesafe Remote Procedure Calls), GraphQL, and REST (Representational State Transfer). It provides a brief overview of each paradigm and sets the stage for the subsequent comparison.

05:00

⚖️ Comparing Server Actions, tRPC, GraphQL, and REST

This paragraph compares the four paradigms in terms of ease of setup, ease of use, handling mutations, handling queries, type safety, compatibility across different clients (web, mobile, desktop), and ability to work without JavaScript enabled on the client. It provides a comprehensive analysis of the advantages and disadvantages of each approach, highlighting their strengths and weaknesses in different scenarios.

10:02

💡 Recommendations for Using Server Actions, tRPC, GraphQL, and REST

Based on the comparison in the previous paragraph, this paragraph provides recommendations on when to use each paradigm. For simple web applications, it suggests using a combination of Server Actions and React Server Components. For applications with mobile or desktop clients, it recommends tRPC or GraphQL, depending on whether it's an internal or internet-facing app. It also cautions about the potential denial of service issue with GraphQL on the open internet.

Mindmap

Highlights

Server actions are functions that you define on the server, which can be invoked from the client by just calling that function.

tRPC (typesafe remote procedure calls) allows you to define remote procedure calls exposed by the server, creating handy query hooks and handling marshalling between the API endpoint and your function.

GraphQL is a query language created by Meta, sitting on top of HTTP and JSON, with a standard syntax for queries and mutations.

REST (Representational State Transfer) is an architectural style with entities defined in a hierarchical structure, but without strict formality or standards.

Server actions are incredibly easy to set up, being built into Next.js 14 out of the box.

tRPC is fairly easy to set up, with good documentation.

GraphQL is difficult to set up, often requiring a code generator to keep it type-safe.

REST is easy to set up in most environments, with a way to create API endpoint routes.

Server actions are incredibly easy to use, as they're just functions called on the client.

Server actions are designed for mutations, making them shine in that area.

Server actions are not as good for queries, as requests are queued, which can be problematic for simultaneous queries.

GraphQL queries can be a security risk, as clients can make up any query, potentially leading to a denial of service.

Server actions and tRPC provide excellent type safety out of the box.

GraphQL allows for introspection against the server, enabling the creation of types from the schema, which is a unique advantage.

Server actions have limited compatibility with other clients, as the API is designed by the framework.

Transcripts

play00:00

whenever the topic of server actions

play00:01

comes up inevitably folks ask well now

play00:03

that we have server actions and

play00:04

something like nextjs do we even need

play00:07

stuff like trpc graphql or rest and

play00:11

that's actually a complex question so

play00:13

what we're going to do in this video is

play00:15

compare server actions to trpc graphql

play00:19

and rest and give you some insights into

play00:22

which might be the best choice for your

play00:24

project let's get right into

play00:28

it

play00:33

all right let's introduce our four

play00:34

different paradigms starting off we've

play00:37

got server actions server actions are

play00:39

functions that you define on the server

play00:42

in the case of xjs 14 you define them

play00:45

using the use server pragma and then you

play00:47

can invoke them from the client by just

play00:50

calling that function and nextjs or

play00:53

solid start or quick or whatever

play00:55

framework you're using manages that

play00:58

entire flow of making that call for you

play01:01

next up is trpc or typesafe remote

play01:03

procedure calls you define the remote

play01:06

procedure calls that you want to have

play01:08

exposed by the server it then

play01:10

automatically creates some handy query

play01:13

hooks for you and does all of that

play01:16

marshalling for you between the API

play01:18

endpoint and your function which is

play01:20

really cool it sits on top of HTTP and

play01:22

Json and despite what people may think

play01:25

you don't have to be using typescript to

play01:27

use trpc you can make RPC requests from

play01:32

any language next up is graphql it is a

play01:34

query language that was created by meta

play01:36

it sits again on top of HTP and Json

play01:38

there is nothing exotic about the return

play01:41

values those are simple Json what is

play01:43

interesting is the request format which

play01:46

is a query language and you can specify

play01:49

either queries or mutations and the

play01:51

Syntax for that query is well understood

play01:55

and there's a full standard around that

play01:57

and then finally there is rest rest

play01:59

stand stands for representational State

play02:01

transfer it is an architectural style

play02:04

where there are entities defined in a

play02:07

hierarchic structure but beyond that it

play02:10

it really doesn't have a lot of

play02:11

formality to it or standards to it and

play02:14

so you see things like open API and

play02:17

Swagger as ways to kind of lock down

play02:20

rest apis but rest apis can have all

play02:24

kinds of different shapes and flavors

play02:26

and styles so now let's get into

play02:28

comparing the various advantag and

play02:30

disadvantages of using server actions

play02:32

trpc graphql and rest we'll start off

play02:37

without easy each one of these is to set

play02:39

up in terms of setup server actions is

play02:41

incredibly easy to set up it's actually

play02:43

built into NEX js14 now so you don't

play02:46

even have to enable anything all you

play02:48

have to do is just start using them and

play02:50

they work out of the box so that's why

play02:52

I'm giving it three up arrows if it's

play02:55

three down arrows that would be the

play02:56

lowest ranking three up arrows is our

play02:58

highest ranking so how does that compare

play03:00

to something like trpc well trpc is

play03:03

fairly easy to set up the docs are

play03:04

pretty good about how to set this up in

play03:06

your environment so I'm going to give

play03:07

that two up arrows graphql is actually

play03:10

pretty difficult to set up not only you

play03:11

have to go and set up the API end points

play03:13

and get those going but you also usually

play03:16

have to do something like a graphql code

play03:18

generator to just go and create all of

play03:21

the stuff like the query Hooks and

play03:23

everything else to keep it type safe it

play03:25

is kind of a pain to set up and then

play03:27

rest is really easy to set up in most of

play03:29

these environments

play03:30

nextjs remix they all have a way to

play03:32

create API endpoint routes all right

play03:35

what's next ease of use all right well

play03:38

server actions again are incredibly easy

play03:39

to use there are just functions all you

play03:42

got to do is just call these functions

play03:44

on the client and the client does all of

play03:47

the work of actually making the request

play03:49

against the server and getting the data

play03:51

back it couldn't be easier it looks just

play03:53

like a function and if you're familiar

play03:54

with react query trpc is pretty easy to

play03:57

use as well as our graphql and rest

play04:00

they're basically just queries against

play04:03

that endpoint and with react query you

play04:05

get all those status values and all of

play04:06

that but let's face it come on use Query

play04:09

is never going to be as convenient as

play04:11

just calling a function which is what

play04:12

you do with server actions our next

play04:15

category is mutations how easy is it to

play04:17

do a mutation against a server server

play04:20

actions were designed to do mutations so

play04:23

that's one of the places where server

play04:26

actions are really going to shine of

play04:27

course they're pretty good across trp C

play04:29

and graphql as well graphql has specific

play04:33

types of queries known as mutations

play04:37

that's all type safe so that's really

play04:38

easy to use now rest is also really easy

play04:41

to do mutations with but the thing with

play04:44

rest is when it comes to these endpoints

play04:45

you're basically kind of making it up as

play04:47

you go along you get to define the API

play04:50

you could use a get to make a mutation

play04:53

which is not something you'd want to do

play04:54

you could use a post or a put you get to

play04:57

define the API that you want and so in

play05:00

essence you get to define a non-standard

play05:03

API and that can be a problem all right

play05:06

what's next well queries so the flip

play05:08

side of doing a mutation is to do a

play05:10

query this is actually where server

play05:12

actions are not so great so server

play05:15

actions aren't really designed to do

play05:17

queries they're server actions after all

play05:20

you're acting against the server you're

play05:21

not querying against it you're trying to

play05:23

make some sort of change on the server

play05:25

and one of the things I've heard

play05:27

recently about nextjs in particular is

play05:29

that server action requests are cued so

play05:31

if you want to go and make multiple

play05:32

query requests against a server you're

play05:34

going to have to wait for those to cue

play05:36

and that's not great when you want to do

play05:37

queries you're generally going to want

play05:39

to do multiple queries simultaneously so

play05:41

that's something to watch out for when

play05:42

it comes to server actions on nextjs

play05:45

queries really shine of course on trpc

play05:47

and graphql but there's a big hidden

play05:50

gotcha on graphql and that's the fact

play05:53

that a client can make up any query that

play05:56

they want against the server and that

play05:58

can be deadly you can get a denial of

play06:00

service against your API when someone

play06:02

makes an AP a malicious API request that

play06:06

ends up eating a lot of either database

play06:09

time or server time to accomplish that

play06:11

request so that's something to watch out

play06:13

for when it comes to graphql now there

play06:15

are productss like vunder graph that

play06:16

allow you to do build time graphql but

play06:19

runtime rest that avoid that issue so

play06:22

that's simply something you want to

play06:23

think about when you think about putting

play06:24

graphql into production particularly

play06:27

when you're thinking about high traffic

play06:30

and then of course rest is phenomenal

play06:32

for queries all you've got to do is just

play06:33

create a get endpoint and it's really

play06:35

easy so another big question is how

play06:37

types safe are these so server actions

play06:39

are fantastic they're typees safe right

play06:40

out of the box you're just calling a

play06:42

function and so typescript is able to

play06:44

track those types just as a function now

play06:48

type safety is one where I'm going to

play06:49

give an advantage to graphql because

play06:51

graphql allows for introspection against

play06:53

the server and that means that a client

play06:55

whether it be on JavaScript or

play06:57

typescript or go or rust or whatever

play06:59

have you you can go and request against

play07:02

the server to get the schema from the

play07:04

server and create types off of that so

play07:07

that is very very handy and it's a

play07:09

unique advantage of

play07:11

graphql and then rest is a problem when

play07:13

it comes to type safety because again

play07:15

you can make up anything you want when

play07:17

it comes to rest now you could follow

play07:19

open API or you could export Swagger and

play07:24

potentially get types out of rest but

play07:25

that's a lot of setup and unless you're

play07:28

in a larger setup most of the time you

play07:31

are just going and creating your own

play07:33

types around your own queries and that's

play07:35

not great for type safety all right

play07:37

another Vector of comparison is

play07:38

compatibility so if you are going to

play07:41

have these endpoints how compatible are

play07:43

they with other things making those

play07:45

calls for example you have a mobile

play07:47

client or you got a desktop client are

play07:49

those going to interface with these

play07:51

Technologies well and that's actually

play07:53

one of the areas where server actions

play07:55

fall down and that's because server

play07:58

actions the API is a effectively

play08:00

designed by the framework so you don't

play08:02

control what type of query it is if it's

play08:05

a form post what the actions are the

play08:09

format of the request you control none

play08:11

of that so when it comes to a mobile

play08:14

client if all you have a server actions

play08:16

they're basically going to have to look

play08:17

at the wire and see what's going across

play08:19

the wire and then imitate that to go and

play08:22

do the equivalent of the server action

play08:25

which is not a great API trpc is really

play08:28

good for this you can have the types

play08:29

that are then imported by a client if

play08:32

you got JavaScript or typescript on the

play08:34

other client that's going to be

play08:36

fantastic when it comes to trpc when it

play08:38

comes to something like go or rust or

play08:40

another framework that's not going to be

play08:43

as good but yeah if you're doing trpc

play08:46

between two different typescript

play08:48

applications be it react native and the

play08:51

web that's going to be great graphql is

play08:53

fantastic when it comes to

play08:54

interoperability that's because graphql

play08:57

is a standard and so you can make

play08:58

Library liaries that comport to that

play09:00

standard and therefore you can have you

play09:03

know IOS and Android libraries that are

play09:05

fantastic for doing graphql as well as

play09:07

rust and go it's great rust is pretty

play09:11

good when it comes to compatibility

play09:12

pretty much everything you're going to

play09:13

find is going to be able to do a get or

play09:15

a post against some server but you're

play09:17

not going to get that really nice

play09:19

standardized request like you would with

play09:21

like a graphql one last area of

play09:23

comparison that's specific to the web is

play09:25

whether it can work without JavaScript

play09:27

being enabled on the client the only on

play09:29

that's going to be able to do that are

play09:31

server actions server actions are often

play09:33

done as a form post that's a basic

play09:35

function of the web and therefore can be

play09:37

accomplished without JavaScript and the

play09:39

only thing that's going to do that of

play09:40

course is server actions in this case so

play09:42

if you need that it's going to be server

play09:44

actions or nothing so my recommendations

play09:46

as of late 2023 after nextjs 14 has come

play09:49

out are that for very simple nextjs

play09:52

applications that are webon using a

play09:55

combination of queries on the server in

play09:58

react server components and server

play10:00

actions is going to be the easiest way

play10:01

to go if you're looking to support

play10:04

mobile if you're looking if you also

play10:06

have mobile clients or desktop clients

play10:08

then I personally would recommend

play10:10

probably

play10:11

trpc if it's an internal app or an

play10:14

internet app I might also look at

play10:15

graphql as a possibility nice thing

play10:18

about graphql is it's really good on the

play10:20

server and the client and it's really

play10:22

easy to make customized

play10:24

queries but on the other hand it's got

play10:27

that denial of service issue so I

play10:29

wouldn't want to put it out on the open

play10:31

internet because it could potentially be

play10:33

denial of serviced well I hope this

play10:35

helps you figure out what you want to

play10:36

use in your applications of course let

play10:38

me know in the comments do you agree

play10:40

with my assessments or not in the

play10:41

meantime of course hit that like button

play10:43

if you like the video hit the Subscribe

play10:44

button if you really like the video and

play10:46

I'll see you on the next Blue Collar

play10:47

coder