What is GraphQL?
GraphQL is an API standard as an open-source project by Facebook to be an alternative to REST.
Instead of many endpoints that return fixed data-structures, GraphQL only exposes a single API endpoint that responds precisely with the data specified in the HTTP request.
More efficient how?
Only the necessary data is transferred over the network, resulting in minimization of network consumption.
GraphQL exposes a single endpoint that responds to HTTP requests for data (GraphQL requests), and evaluates the query and and replies to HTTP request with only the data specified. No more, no less. Unlike REST APIs, which have several endpoints and respond very structured responses to requests, often returning excess information and/or requiring multiple HTTP requests to piece together objects.
REST vs. GraphQL
There is a blog application that has the following objects and relationships:
-
user
- represents a user model.- properties:
-
user.id
integer (primary key, auto-incrementing) -
user.firstName
string -
user.lastName
string -
user.password_digest
string -
user.dob
date-time
-
- relationships:
- has-many
followers
- has-many
- properties:
-
follow
- represents a subscription to another user's blog posts- properties:
-
follow.id
integer (primary key, auto-incrementing) -
follow.subscriber
integer (foreign key, user who "follows" another user) -
follow.user
integer (foreign key, user that is "followed")
-
- relationships:
- has-many
users
- belongs-to
users
- has-many
- properties:
REST Approach
A REST API for this blog application would have a /users
" endpoint and a /follows
endpoint with the following routes:
Users REST Endpoint
- INDEX - GET
/users
- SHOW - GET
/users/:id
-
CREATE - POST
/users/
- body (JSON):
{ user: { firstName , lastName password, dob}}
-
UPDATE - PATCH
/users/:id
- body (JSON):
{ user: { firstName , lastName password, dob}}
DELETE - DELETE
/users/:id
Follows REST Endpoint
The endpoint /follows/
- INDEX - GET
/follows
- SHOW - GET
/follows/:id
-
CREATE - POST
/follows
- body (JSON):
{ follow: { subscriber , user}}
-
UPDATE - PATCH
/follows/:id
- body (JSON):
{ follow: { subscriber , user}}
DELETE - DELETE
/follows/:id
In order to get all the users that follow the user currently logged in (assuming basic setup and no nested routes) the following logic would be executed:
- Front-end (client) executes a HTTP
GET
request to the/follows
endpoint (index) - REST API (backend/server) queries the all the
follow
records in the database, and encodes them as JSON in the body of the HTTP response (status200
success) returned to the client. - Front-end (client) decodes HTTP request and parses the JSON data from the body creating an array in memory with all the
follow
objects returned from theGET
request. - Front-end (client) executes a reduce function, filtering down the array of
follow
objects so that it only includes the ones whoseuser
field matches theid
field of the authenticated user. - Front-end (client) executes a HTTP
GET
request to/users
endpoint (index) - REST API (backend/server) queries database for all the
user
records in the database, and encodes them as JSON data in the body of an HTTP response (status200
success) returned to the client. - Front-end (client) creates an array to store the associated
user
objects, then loops over theuser
(foreign key) field filtered from theGET
request to the follow/follow
adding the user's with the correspondingids
.
GraphQL Approach
-
Front-end (client) sends GraphQL query to server:
- body:
query { Follow (user: 23){ Followers { firstName LastName } } }
GraphQL API (backend/server) queries the database for all the records of
follows
the whoseuser
propety is23
, then takes those foreign keys (follow.user
) to query the database for all theuser
records contained in the result of the first query and returns an HTTP response to the client containing an array of objects each withfirstName
andlastName
fields of only theuser
models with matchingfollow.user
The difference
REST APIs are built with 5-7 routes for each of the endpoints. Each endpoint represents a collection of records in a database (in a "table" in relational databases), and return either a single record (object) or all of the records (objects). The client (frontend) is then responsible for parsing the responses, filtering the data (if needed) and making additional subsequent requests for more information (if needed), which returns individual records (objects) or all records associated with an endpoint (or "table") in strictly defined data structures which could result in repeating the filtering of data, and making additional/supplemental HTTP requests over and over until all the data is necessary information is gathered.
GraphQL APIs reduce the number of HTTP requests/responses by enabling the developer to "declare" exactly the information needed, and allow the API to join, filter and sort data in a single HTTP request (similar to filtering done in SQL databases using the where
operator).
Instead of providing excess records (e.g. REST INDEX
) The HTTP response generated from the GraphQL server contains only the records that match the conditions specified in by the client, and each object only has the fields specified, stripping out additional fields and objects, and (in some cases) dramatically reducing the size of the HTTP response.
TLDR;
GraphQL takes a declarative, SQL-like approach to data fetching (APIs), and increases application efficiency and flexibility by enabling client (frontend) request to declare the required information, then querying, filtering, ordering, and joining records/objects (like a SQL statement) and returning only the declared records and fields. No extraneous records, and only the fields declared.
This approach allows GraphQL to reduce both the number/frequency of HTTP request and size of HTTP requests.
Top comments (3)
Reading the TL;DR it's almost hilariously obvious how all that reasoning leads to one simple conclusion: SQL beats both.
The reason why we might use GraphQL over SQL is the same reason why we might use REST over GraphQL.
These protocols are all on a spectrum and GraphQL has the most difficult position: it sits right in the middle. No matter what it does, one of the two extremes will be better at doing that, so the only good point for using GraphQL is: For many projects, it sits right in the sweet spot between the extremes. Arguing that it's objectively "better" than either extreme will just lead to the question "Why not go all the way to the other extreme then?".
GraphQL rocks 🤘
I will start using it. Thanks for the explanation. It made my life a lot better! ❤️