Before I go further, I want to clarify that I love GraphQL as a frontend engineer. It empowers me to create.
I also think GraphQL is a great choice for larger engineering organizations. Having a GraphQL server as an API layer over different micro services allows frontend engineers to just build without dealing with the complexity.
For new projects, however, I will no longer be using GraphQL. My definition of a new project is a project without a clear market fit and a project with a small team (less than 3 engineers).
As a backend engineer, I hate GraphQL. GraphQL provides a lot of flexibility on the client side but this means that we cannot optimize as aggressively on the server.
Making sure that our GraphQL server is performant requires discipline and care. It's questionable if this investment is justified unless the team is already well versed in GraphQL performance. For example the team will need to know how to utilize dataloaders to avoid n + 1 queries.
With a traditional REST API, we can add security on each of the routes that we are exposing. With a GraphQL API we have to be cognizant of the fact that there could be endless permutations of queries that can be triggered.
Types and access to types have to be organized with care. We have to make sure that we don't unexpectedly add a subquery that exposes sensitive fields.
GraphQL is new to a lot of engineers. Traditional REST API is familiar to many engineers. It's one extra thing someone has to learn before they can be productive.
It's tempting to reach for GraphQL especially if we want to learn it, or because we really enjoy working with it. Before we reach for GraphQL, we should ask ourselves 'Is this tradeoff worth it early on in the project?'
There is an argument that we should just start off with GraphQL if that's ultimately where we want to get to once the project gets big. If there is a guarantee that the project will get big, then yes I agree.
However, if we aren't sure if our project is going to be a runaway success with 30+ engineers in a span of 6 months...I believe going the more traditional route will allow the team to be more nimble and add talent easier. Time is of the essence, GraphQL can be added later when the organization matures.
Top comments (76)
I'm sorry but your arguments are very poor.
The worst thing that can happen with any app (web, desktop, mobile, etc) is that due to bad backend design/architecture they should call multiple api requests to display some data it doesn't matter if it's REST API or Graphql.
Just think of if you order a notebook and in stead of receiving a whole notebook at once you'll get it in part first keyboard some time later display then other parts. For the user app is a complete product why user have to get parts of it? Of course there are some optimisation technics and data is loaded in parts but the reason why they were created in not just a poor internet connection. User would prefer any app to be loaded just when the app is opened and data is just there no loaders, no jumps, no weird behaviours.
Of course all these can be solved both with Rest API and Graphql but it requires
a little bit more work and better architecture design.
Performance (N+1 problem)
If you are using node.js there is a tool called prisma (prisma.io) it will help forget about any dataloader.
But keeping in mind that it would be better for user to get all the data for current view at once some problem may occur with Rest API so you'll have to find solution for that.
A lot of modern backend frameworks doesn't solve n+1 problem.
If your are using Rest API it doesn't mean that your backend has better performance. Users don't pay for your backend and it's performance they pay for the data/information they see on their displays, they don't care about your backend and if it has n+1 problem or not. And it's a huge difference when the app has to make 10 http request, wait for them all then app code should somehow merge them and display meanwhile it can be done with just one http request.
Very similar thing can be done even with Graphql. You can secure each query or mutation as you can secure each endpoint when you're using Rest API. It's just a question of architecture and your comfort zone.
If someone doesn't have deep understanding how current tool works that tool won't be helpful. Any tool can be misused. There are no bad or good tools, there are tools that solve specific problem and maybe there are not trying to solve your problem, so developers should choose tool according to their problem.
I'm talking about a special kind of app, a project that's just getting started.
The worst thing that can happen to a new project is no one uses it. I believe the main problem at hand is validating a business idea, not worrying about sending 5 requests instead of 1 request.
There are definitely ways to have performant and secure graph. It does require a level of comfort zone with GraphQL. It does require additional tooling. It might also introduce some black boxes as well if we are blindly using these tools without understanding the internals.
Choosing the right tool for the job is very important. We have to consider the stage of the product and the size of the team when choosing initial set of technologies.
If I'm working on a mature project that already has product market fit, of course I would prefer to work with GraphQL. These arguments would be poor if I was talking about mature apps.
To your point about reaching for a tool too early in a project, a microservices architecture shouldn't be utilized before the "seams" of the business domains have been clearly defined.
Absolutely. Microservices is not the right approach when we are just trying to validate a business idea.
Have you tried keystonejs.com?
this backend framework is a game changer.
Just defining schemas (objects with field and types) automatically gives you a complete GraphqlAPI + Pretty CMS. All relationships are connected. It uses Prisma on its backgrund. Can let you extend and customize mutations, triiger actions on hooks, add layers of security. Authentication, authorization and caching included.
I can start a backend project in a couple of hours.
My favorite project in 10 years of developing as a backender
I think that there is a world between REST and GraphQL.
For front-end application, there is a need to create something specific for the jobs (presenters). Most of us are not developing a Facebook that has the complexity of displaying lots of variable data.
In most application that I have worked on, we always ended up writing services (note that I'm not using the word REST) that were used to present data for specific parts of the application. Mutation were also tailored to the specific need.
The architecture was usually FE -> Presenters -> Business
Presenters are specific to the view (whether that is web, mobile, or mobile app).
This does not suite all but when the team is taught for defining the contract and making them evolve according to the need.
I don't think microservices, which is the nearest you could come to REST, have ever been suitable for frontend consumption especially for the reason
Unleash the trolls :-)
🤔 REST is not microservices, or nearest... Microservices is much more 🙌
In my company that i'm working at, we discovered that prisma sql query are poorly optimize...
We completely removed Prisma from the code and now we are writing our own queries.
This isn't quite right for a few reasons.
Agreed users don't care about n+1, unless that means things are slow to load. Then they care heaps.
GQL doesn't cache. Never will you get a 304.
GQL can't make use of client side service worker caching either.
It's not a huge difference if a Client makes 10 calls anymore because of multiplexing.. In fact if those 10 calls hit different pods/severs/dynos then the call is much faster. Each server has to grab a small optimised bit of data, where with GQL the fast bits of the query have to wait for the whole data to be built.
Lazy loading or partial loading of the data gives the user something to see while the rest is being load..
Now.. when you want to upload or download a file. How does GQL handle that. I've not been around all that long, but I always see people falling back to REST for these.
GQL is not great for errors. All posts return 200. If I say you got a 404 or a 401 or 403, then you don't have to think about what those mean. Each GQL build has to build its own error mechanic. Moving jobs means one has to learn new error paradigms.
Agree about how GQL handles security.. One can set limits right down to the field. In that it shines.
EDIT: I keep thinking of other things.. lIke debugging errors from the network tab.. Nothing like 20+ posts to the same endpoint to make finding the call that is returning an error a right pain. I'd take a RED line over a pile of 200's any day.
I wanted to write some of these as well
I think it's more of there is not alot of tooling and "best practices" for GraphQL.
Like for me a gold standard for API will be either Twilio or Sendgrid or Salesforce but when it comes to endpoints made using graphql I have no idea.
I'm the founder of WunderGraph, we're setting the gold standard of how to run GraphQL in production. We focus on security and automation to give you the good parts of GraphQL without you having to take care of the tradeoffs: wundergraph.com/
I can confirm, WunderGraph is a game changer.
You'll never have to worry about creating GraphQL API again, everything is in the box. Composing your service using other existing API is also really easy.
Hi Jens. Could you compare wundergraph to something like Postgraphile? The beauty of Postgraphile for our MVP project was the ability to get up and running quickly. The only friction we've had thus far with Postgraphile was un-plugging the default JWT authentication in favor of a session-based solution. We evaluated Hasura mid way through our project and just didn't think it brought much to the table at that point (Typescript gen would have been nice in a new project). As we scale our project and introduce additional integrations we are always looking for more scalable/performant solutions. Thanks!
This is a great question, thank you!
PostGraphile is an amazing framework, written by benjie, a really nice guy from the GraphQL community. PostGraphile is, as it says, an extensible high performance automatic GraphQL API for PostgreSQL. It's written in NodeJS and can be used as a standalone service or even as a library.
WunderGraph on the other hand is a suite of tools to make API practitioners highly productive. Our aim is to create the best developer experience for working with APIs. GraphQL is core to our solution but it's just a tool to accomplish our goals. PostgreSQL is also just one of the possible connectors. You can also use MySQL, SQL Server, SQLite, GraphQL, OpenAPI (REST) and Apollo Federation, with MongoDB, gRPC, SOAP and OData support coming soon. Additionally, we look at problems like authentication and solve them with an end to end approach. For example, you can plug in your own OpenID Connect provider, e.g. Auth0 or Keykloak, and WunderGraph not just generates the backend to handle the auth flow and protect your APIs but also generates a type safe client to initiate and end the login flow for the user. It's like Firebase but using your own custom DataSources, Authentication Providers, File Storage, etc.. We're not doing anything magically. What we do is make a lot of decisions for you so that you can focus on what really matters: Getting the business logic right and building a great User Experience. Everything else, the whole Middleware layer, is solved by WunderGraph.
So, to answer your question more specifically. You don't have to think about JWTs with WunderGraph. We offer a secure login flow out of the box, with CORS , and CSRF protection for mutations, using secure, http only, encrypted cookies. If this is not enough for your problem, we'll add another flow. E.g. we'll also be adding token based auth for non browser-based environments. But again, our goal is that you don't have to think about this middleware layer. You should be focusing on User Experience and Business logic. Everything else can be standardized and automated away.
Hey @jensneuse ! Seeing the title of this post, I immediately thought about Wundergraph.
It helped me remove lots of complexity from the project, such as Apollo server, type-graphql, and next-auth.
@jensneuse I love WunderGraph! Are you hiring? :)
Thank you! What exactly do you like about it?
On hiring, you can join our discord and we have a chat.
This was my experience building a GraphQL API with Elixir + Postgres. Ran into all kinds of n+1 issues. Dgraph solved all these problems for me, it's allowed me to ship a scalable GraphQL backend with minimal effort as a team of one. Pretty incredible tech, I wrote a summary here: dev.to/koder/dgraph-is-the-most-ex...
I was about to suggest DGraph as well. Such an amazing tech 💖
So you don't want to control any logic in backend and just expose all your data with generated APIs? I just looked at DGraph and it seems like ready to go solutions to generate API from DB on the fly with auth.
I work at StepZen, and because of the usefulness of our product I've really started to think in terms of GraphQL first, even when I daydream about personal projects. We offer advantages in terms of managing security and performance for you, which often is a first concern with larger teams, but I also find our custom directives make GraphQL accessible for 1-person projects because they complete elimate resolvers etc. I just write a little schema with directive that plug directly into my endpoints and I'm good to go.
I hate graphql... full stop.
The client side should never need be so intelligent about the data as is necessary with graphql. Its a terrible pattern imho.
There are many usecases where clients can benefit from the added flexibility. No single style of API will be perfect for every purpose, but making statements like that just makes you look a little narrow minded to be honest. Choose the right tool for the job, sometimes that's GraphQL, sometimes it gRPC, sometimes it's REST, and sometimes it's something altogether different.
I never suggested there was ever a single api style that's perfect for every purpose. But GraphQL is shit, and rarely the right solution for MOST use cases where it's mistakenly employed.
As for how open or narrow minded I am - conveniently, your opinion on it doesn't affect me whatsoever 👍
It's clearly not shit, many teams big and small have invested in it (ex: Facebook). Please back up your claims, and we can have a constructive conversation. :)
Valuable insight for me just starting a new project and somewhat unsure of what API style should we go. And yes the project is still in design phase.
I've implemented already GraphQL in a more mature project and it was really delightful not having to build multiple custom endpoints for different frontends. Mobile and web developers have been able so far to query and rarely they require just a new field.
Hating tech is just so childish.
Just to clarify I don't hate GraphQL! I said I love working with it as a frontend engineer but hate it as a backend engineer. It's not that I hate the technology, I hate it because it's much harder to optimize a graph vs. optimizing specific routes...makes my job a lot more difficult.
I like using graphql with highly related data structures. Hasura.io is pretty cool. What I don't like about graphql is the very verbose code when querying on the client side, and complex client libs like apollo.
Agree. Or you have to keep some kind of SDK library between code and gql, that provides the developers with predefined GQL queries, optimized and limited to some extent, so the developers cannot go wild :)
I've never considered GraphQL for large or serious projects. It always appeared to me a good fit for MVP or prototypes. That's just my view based on my experience. The "security" part in this post is one of the concerns that I never felt GraphQL would replace my REST API requirements. I know there are people who are building cool and serious stuffs with it, but for me, it's not yet for serious ones.
Out of curiosity, what are your security concerns that GraphQL is unable to cover?
Just the "Security" part the OP written in this part - that is: In a REST API, adding a number of middlware to a specific route is easy - which is not as easy in Graph as per my knowledge.
Dunno what tools you're using but for example laravel lighthouse has @can directive and all you have to do is place it on your schema or even field. lighthouse-php.com/master/api-refe...
I actually developed a middleware in PHP for GraphQL, that uses directives. I can define, as an example, a
@signeddirective that forces users to go through authentication middleware. Basically you can inject yourself to the parsing process and put your stuff in there. Many developers just don't wanna dig deeper into that and prefer using ready-to-use frameworks that do all the heavy lifting. I also implemented a directive for fields which hides them from introspection.
But you're right, it's not easy to do and many libraries don't include something like this. GraphQL is very complex and the support for some languages is lacking.
As a FE engineer I like using it, because graphs reflect the way people think better. BE for graphql can be intimidating though, and the dev-time you save on the FE is shifted to the BE. That's the case when you implement the resolvers yourself, especially if you try to map to a relational model or tree structure. Neo4j have a project to map graphql to a graph database though, I'm tinkering with that now and it seems they're tackling some of the problems you mention. And it needs surprisingly little code: neo4j.com/developer/graphql/#_usin...
I'd like to hear other people's opinions / experiences, but it seems pretty useful at this point
Adding dataloader is not that hard, you just need to detect where you will need this. For example in a field resolver
In REST its true that we can protect routes using a middleware or something. but when you develop a large scale project involving multiple level authorizations, things started to get messy. For example take a route like
GET /api/invoice/1. There can be additional fields that are hidden or shown based on the user authorization level. Implementing this in REST is a mess, even though documenting it even harder...serialization goes the same
But in GraphQL this is already solved, you can have granular field level authorization which is lot easier to implement and maintain.
So my conclusion is, if your API is getting complex, involving authorization levels, having multiple people working in different client applications...GraphQL worth the shot. It may take some time, but once you get it going you will see the result
The new HTTP QUERY Method, is designed to compensate that.
It will be possible to use Rest as you use it now in elastic, so you can use it to get just some data, and to grab relational data too.
a good open source project that take already advantage of that is directus9.
REST API as a concept has been known for nearly 20 years. The GraphQL specification was publicly released 6 years ago. There are tons of frameworks out there which already contain support for REST API implementation, in a variety of languages, with all sorts of features and helpful things for developers to start using it out of the box. We have it so easy when a framework converts those HTTP requests to a standardized request / response format, with easily implementable middleware per route and all sorts of cool gadgets to make it even better.
GraphQL doesn't really have this kind of ecosystem. At least not yet in the open source world (I think?). Commercial solutions might have some since they're motivated by money to produce them.
If GraphQL solved some specific problem we have, since most of us don't work at the level that Facebook operates in, people would be all over it. I'd bet there'd be tons of libraries out there that allowed users to write GraphQL schemas with custom directives for queries, mutations and fields with little effort, and middleware/some other security mechanism to protect those. So far I've had to implement all of those by hand, because there's very little support for mechanisms like those in languages like PHP.
We used GraphQL on a front-end rewrite project and it didn't take long for five developers to learn how it work. It's not that hard. When you explain to them what the n+1 problem is and how you can solve it by deferring resolving to a later stage when you have all the necessary data to perform a batched query or something, it's relatively simple to use.
Depends on the stack also, as there are quite some things like Hasura to make GraphQL easy. But if you can't use tools like that, it totally makes sense.
Hasura will solve your backend woes.
GraphQL queries could cause performance issues.
REST can do much of what GraphQL does.
GraphQL makes some tasks more complex.
It's easier to use a web cache with REST than with GraphQL.
The way GraphQL schemas work could be a problem.
REST is better for error handling and tooling. by yacinetv.fun/
This is a good article, I don't know that I 100% agree with the sentiment but maybe 70%.
More often than not, a REST API is perfectly fine. But there are occasions when graphql will save you an absurd amount of development time.
I built a CRM for the lending industry and the clients had massive databases with hundreds of thousands of records that they needed to query based on insane amounts of data. They may want to find all of the men in Louisiana who are between age 30 and 50, that are currently employed, making over $50k per year, and have an active cell phone. These people may need to be narrowed down by people who owe capital one more than $1000.
Considering that there are about 80 more data points that they might want to search, this type of architecture will take weeks to build out as a REST API or minutes with Hasura.
But at the same time, queries that complex are usually the exception, not the rule with most of the projects that I work on at least.
REST is standardized, familiar, and perfectly sufficient for most use cases.
I've used graphql on small projects and I've used rust apis and large projects, I have a really hard time using any definitive language but graphql was definitely driven by hype for far too long.