One of the main tasks that we as developers have to do is communicate with servers: to get data from them, post new data to them, and manipulate existing data on them. Currently, the most widely used system to do this is REpresentational State Transfer (also known as REST).
At its core, REST is only an architecture, a set of principles for creating a client server interface. Most commonly it is implemented
· with HTTP with different HTTPS methods to carry out different operations
· with JSON as the message format to send requests and receive responses
· with tokens and cookies to track user sessions
· with HTTP status codes (304) to enable caching
GraphQL is a new “query language for your API” that was developed by Facebook to solve some of the shortcomings of REST. One of the biggest advantages that REST provides is the ability to request only the data that you need on the client and get all requested data in one response. With REST, the client has no control over the data fields that it will get from the server, instead it has to handle whatever data the server responds with, regardless of whether it is used or not. Moreover, if a REST API returns normalized data with only entity IDs, and you need more data on the client, you have to make another request to get the missing data. If you are dealing with a list of entities, the number of requests that need to be made will be multiplied even more. With GraphQL, you avoid all of these pitfalls by specifying the exact data fields you need in the form of a query and having the server return only those fields, regardless of how deeply nested they are, in one response.
When we started working with GraphQL at U+, our servers were still using REST. We got around this issue by implementing a thin resolver layer on the client that converted our client side graphQL queries into REST calls. While this did increase overhead on the client by a bit, this approach did introduce several new features into our React Native app. At present, the two most popular libraries to use GraphQL in REST are Apollo 2.0 and Relay Modern, which are very similar in terms of features. In our case, we used Relay Modern, which introduced a deep caching system that worked even with entities nested within different entities and also allowed us to implement optimistic updates very easily without needing to have multiple states to track the state of the response and to rollback if the request failed. (Optimistic updates are temporary changes made to the UI immediately, without waiting for a server response to improve application responsiveness and UX). Finally, it also allowed us to write our server communication code in a declarative way, to declare the data that an individual component needed alongside its code and to handle loading and error states in a straightforward way, with having async functions or promises running on lifecycle methods (e.g. componentDidMount).
Of course no technologies are without their downsides, and GraphQL is no exception. One of the more obvious drawbacks is that to get the maximum benefit of GraphQL, you need to know the structure of the data in advance. While you can still use GraphQL for dynamic cases (such as building a universal CMS) through introspection queries, it wasn’t meant for this at all. Another downside is that you are adding yet more compile time tools on your stack, at least when using Relay Modern, which uses relay-compiler to compile the fragments of GraphQL code placed in your source files.
However, in our use of GraphQL, we found the upsides definitely outweighed the downsides, which is why we will be moving to a completely native GraphQL implementation in most of our future projects.