Recently for multiple projects during work and study I have been asked to define a web API that the back-end exposes and the front-end interface (single-page application-like) consumes.
All of these cases so far, I have looked at GraphQL and a couple of contenders, and in the end I decided every time to roll my own simple API library that uses a somewhat RESTful routing style for simple queries, returning simple JSON answers, with HTTP status codes indicating the difference between a success or a failure.
Every time I felt a bit insecure about this choice. The reason I decided not to use GraphQL is that it felt overkill for these projects, since GraphQL requires you to define schemas for all your objects, which seemed to me as an ‘expose your database to the world’ kind of construction which these projects were too far limited in scope for, as well as usually the content that actually gets exposed through an API being limited in the way how we want to return it to the front-end.
Still, not relying on tools such as GraphQL also feels like missing out, or like re-inventing the wheel. I hope some of you professional users of GraphQL and similar data-fetching tools can shed some light on this issue .
Think of it more as a multi-argument : multi-return RPC call. They don’t need to (probably shouldn’t even) mimic the database, but rather be either view actions or event submitter’s, at least that’s how I use it.
I would like a better server-side request system rather than just client-side, like a good Ecto-Like DSL, but unsure if really worth it.
I am not a professional and my experience is limited only to Absinthe. Even that is very limited.
Graphql relies on resolver functions to populate the objects of the schema. This means the schema doesn’t have to be a one to one mapping of your database tables. The resolver can return a result manipulated, transformed and limited to whatever form you wish. The schema is just a representation of that return. Also with use of middlewares you can transform further the return from the resolver, in the schema level.
Also Graphql doesn’t require schemas for all your objects. Only for those you wish to communicate with the client.
I believe GraphQL shines for two use cases that can otherwise be a real pain to implement: expensive computed fields and included related resources.
In a simple rest API, you have to document that the response will only contain the expensive computed fields if an extra query params is passed, then check and handle it in the API Controllers. GraphQL makes it simple - you get whatever fields you ask for
Included resources are often used to avoid having very chatty APIs, but again, with a simple rest API, you need to document a convention for requesting them, and specially handling those params. With graphql you get this out of the box.
In 2018, having had a couple years of using GraphQL on a project, there’s really no situation where I would prefer to start with REST instead.
Even in the simplest use, defining the schema in absinthe is straightforward, and you’re in much greater danger of just exposing your database when you are able to hand off whatever your query returns to send down the wire as a json blob, except you’re not going to document it or make a conscious decision about it. What you get with GraphQL though, is a well-defined, well-documented API, and a set of standards you adhere to with zero effort. You have excellent tooling on the client, and if you’re really wanting to roll your own JS API wrapper, its straightforward to do so.
Basically my feeling is that there’s no advantage REST offers over GraphQL once you know how the GraphQL pieces fit together. I’d recommend doing a small project with it to learn how to use it effectively, then the cognitive cost of using it the first time is already paid.
The API schema is relatively static. Because I found the resolver is a little bit easier to write compared to controller action. And it’s also a little bit easier for client to consume.
GraphQL has union type, so actually some dynamic field could be reasonably expressed as well. If the fields have no schema at all, better to directly return a JSON.
I found dataloader is a little bit cumbersome to use compared to not using it. So I’m currently just using GraphQL with Gen servers and non-critical database access.
Basically, I found GraphQL could ease a lot of pains if you have multiple or will have large front-end code bases. So the benefit is mainly on the clients side.
Another thing is GraphQL is against some micro-service pattern. This does not always happen, but surely it would make things a little bit more complicated (eg: conditional forward to different services, recursive resolving).
I believe Elixir/OTP work better with GraphQL than to most of tech stacks:
Gen server make data loader less important in some scenarios.
Micro services pattern sometimes could be partially replaced by OTP applications.