REST and GraphQL are technologies used to build web APIs and define the interaction between clients and API servers. However, comparing the two is not necessarily apples to apples. REST is an API architectural style, while GraphQL is an API query language and runtime.
The most significant difference is how clients fetch data. For example, REST and GraphQL differ in how they expose data, how clients apply filters, and how the client receives and parses the response.
This article will discuss the differences between REST and GraphQL and their use cases.
What is REST?
REST (REpresentational State Transfer) is an architectural style that places constraints on how to build web APIs. A defining feature of REST is its use of resource URLs to expose data objects to clients. We go in-depth on REST in our other blog post, REST vs. SOAP: What is the difference?
One must mention REST to discuss web APIs. REST is the most widely adopted API architecture for web APIs and the most commonly used API type that connects components in microservice architectures. Due to its widespread adoption, REST has a richer ecosystem of tools and frameworks with built-in support for REST.
What is GraphQL?
Facebook developed GraphQL to address some of REST’s shortcomings. GraphQL’s selling point is its flexibility in how data is requested. With GraphQL, clients construct queries that filter and structure the response data.
REST, in contrast, has predefined responses that can only be minimally impacted by passing parameters in the request.
GraphQL is simpler because your app does not need to keep track of all the resource URLs for every data object it wants to retrieve or manipulate. Instead, it can use one URL to query the data it needs.
Requesting data is more efficient than REST because you can retrieve only the data you need. Conversely, REST often involves ‘over-fetching’ and ‘under-fetching.’
Since you can structure data in a query, developers can spend less time parsing the response. REST’s strict response structures require more strategy for parsing and often need to be formatted so your application can use it. GraphQL lets you structure your query’s JSON response to match your application’s expectations.
Finally, GraphQL works better than REST for complex applications.
How are they different?
The main difference between REST and GraphQL is how clients fetch data.
REST APIs expose data through resource URLs. Therefore, gathering the data may involve sending requests to separate resources. This limitation is called “under-fetching.” Under-fetching occurs when you cannot receive all the information you need.
Conversely, REST’s strict response structures can lead to “over-fetching.” Over-fetching occurs when a client gets more data than it needs in the response.
GraphQL exposes data differently. Clients send queries for data to the API’s one URL. As a result, gathering the data you need using GraphQL may require fewer requests.
Both REST and GraphQL offer ways to filter the response by passing parameters. However, GraphQL’s queries provide more flexibility. GraphQL, as a query language, allows you to filter the response to precisely the data you need. How you structure your query determines how the API structures the response. In REST, you cannot control the structure of the response. Instead, the API defines the order of JSON properties.
The downside of GraphQL is that you must be intimately aware of the GraphQL schema you use.
Request Examples: REST vs. GraphQL
We will compare REST and GraphQL requests to show how they fetch data. Two fake APIs, one for REST and one for GraphQL, will return the same data. The APIs allow you to retrieve user details by providing a userId.
REST – Fetching More Data Than Needed (Over-fetching)
Below is an example request to a fake REST API called fake_rest_api using vanilla JavaScript in a simple web app.
fetch("https://fake_rest_api.com/user/86", { method: "GET", }) .then((response) => response.json()) .then((data) => { console.log(data); });
The request passes a resource URL in the fetch() method to a resource that returns user information based on a userId. The userId of the user you wish to retrieve data about is passed as a path parameter in the resource URL as /86. The request specifies the method, or CRUD operation, taken upon the resource. In this case, the GET method tells the API to “retrieve” data, not create, update, or delete data.
The request returns a JSON object that looks like this:
{ "id": 86, "username": "doeUser", "firstName": "John", "lastName": "Doe", "email": "johndoes@gmail,com", "password": "8625", "phone": "3348439878", "userStatus": 0 }
As you can see, the JSON includes all for the user with userId: 86. But what if we only want to retrieve the user’s username and email? If you remember, REST APIs dictate the response. The API developers decided not to allow the client to filter only the fields needed in the user object.
As the client app, you now have more data than you need (“over-fetching”). Over-fetching can affect performance since the payload size increases. In addition, if the data object returned by the API is, extensive and frequent requests can negatively impact performance.
For this REST API, you can also not define the order of the properties in the returned JSON object. The user object follows a strict format specified by the API. Because you cannot dictate the structure of the response, your application must structure the data it receives in the response.
GraphQL: Fetching Only the Needed Data
Next, we will send a similar request to the GraphQL API, fake_graphql_api, to show GraphQL’s flexibility.
First, we will save the API uri (basically a URL) to a variable called a client that we will access later.
const client = new ApolloClient({uri: 'https://fake_graphql_api.com/', });
Notice that we are providing the API’s base URL as the value of the uri property. There is no separate /user resource URL. With GraphQL, clients access data objects using a base URL only. How you specify which user you wish to retrieve details about is passed in the query (we will get to that in a second).
Now, let’s construct the request using vanilla JavaScript to retrieve user details.
client .query({ query: gql` query User(id: 84) { username email } `, }) .then((result) => console.log(result));
Ignore the overall structure of the request for now. The critical bit of code is the query string wrapped in the gql template literal:
query User(id: 86) { username email }.
Like the REST API, you pass the userId to return data for that user. The equivalent GraphQL request involves ending a query (the operation type) called user (the operation name) that passes the id of 86 as an argument.
Our application only needs the username and email, not the other fields belonging to the user object. With GraphQL, requesting specific fields from the user data object is possible. If you remember, the REST API did not offer a way to filter the user data and returned ALL user details.
With GraphQL, you can filter data and define its structure in the request.
{ "data": { "user": { "username": "doeUser," "email": "johndoes@gmail,com" } } }
If you look at the query structure and the response JSON structure above, you will see that the basic structure is the same.
With GraphQL, the response contains precisely the data you requested, no more and no less.
The order of the data you requested is maintained, with the email displaying after the username. In the REST API, the API determines the order of properties.
REST: Fetching Data from Multiple Resources (under-fetching)
Now, let’s say we are building a blog app. Each user writes blog posts. Say we want to retrieve the titles of all blog posts written by the same user.
The REST API has two endpoints: one for retrieving user details called /user (the one we sent a request to before) and another called /posts that allow you to retrieve data about articles users have written.
In this case, a request to the /users resource is an example of under-fetching because we need to get all the data from that resource.
We must send a second request to the /posts resource. This resource allows you to pass an optional userId to filter the list of posts to only those the user writes.
fetch("https://fakerestapi.com/posts?userId=86", { method: "GET", }) .then((response) => response.json()) .then((data) => { console.log(data); });
GraphQL: Fetching Data from a Single Resource
For the GraphQL API, we do not need to send a separate request to retrieve the user’s blog posts. Instead, we can send an HTTP request to the API’s uri and specify that we want the user details and the articles they wrote in the same query.
client .query({ query: gql query User(id: 84) { username email posts { title } } , }) .then((result) => console.log(result));
We added a posts{} object to the query in the above code snippet. Within posts{}, we specify that we want the title of all the user’s posts.
Using GraphQL, we can request all the data we need with one request. Looking back, REST required requests to two resource URLs: one for /users and one for /posts. GraphQL prevented the under-fetching by allowing you to request all the data you needed with one request.
A Disclaimer
In the previous examples, I may have diminished the capabilities of REST to illustrate the flexibility of GraphQL.
REST offers ways of filtering data using parameters. For example, the REST API could have specified that you can pass the desired fields in the response. But, of course, you cannot control the response’s structure; it demonstrates that you can affect the response in a limited way.
The point of the previous examples is that you can use REST and GraphQL to retrieve the same data. The possibilities for affecting the REST API response are at the discretion of the API developers. GraphQL offers API users more options to define the relationship between fields and structure the response exactly how an application expects data.
Ready to take your API documentation to the next level? Book a demo with Document360 today!
Book A DemoDifferences Deep Dive
Now that we know the difference between the two in practice let’s dive deeper into these differences.
Components
REST
-
- Resources – Data objects the API exposes that clients can retrieve and manipulate. Each resource has a unique resource ID the client uses to access the resource.
- HTTP Methods – These are the equivalent of standard CRUD operations. Each operation represents a specific action taken against a resource.
- Representations – REST offers several message formats, such as JSON, HTML, YAML, XML, and plain text.
- Statelessness – The client application does data and not the server. The server does not track requests; each request is independent of past requests. The client must manage the application state.
GraphQL
-
- Server implementation – The GraphQL API server provides a URL to which clients send queries and has a resolver function that gathers data and sends the response.
- Data source – The data source is the location that contains the data the API acts upon. Data sources include databases, file systems, or web services that retrieve data from another API.
- Schema – An API’s schema defines the requested data, available operations, fields, and the potential relationships between fields.
- Client implementation – The client implements GraphQL by constructing GraphQL queries.
Operations
REST
As briefly discussed, HTTP methods are sent with API requests to indicate the actions you would like to take toward a resource. There are many API methods, so I will only list some important ones:
-
- POST request – creates a resource.
- GET request – retrieves information about a resource.
- PUT request – updates or creates a resource.
- DEL request – deletes a resource.
GraphQL
-
- Query – A query is a request for server data. A query is a way to filter a data object to only the fields you need. A query is a more flexible version of the GET request where you are retrieving data.
- Mutation – If a query is like REST’s GET method, the mutation is the rest of the CRUD operations (methods) used to modify data objects. The mutation operation type manipulates and returns data.
- Subscription – This operation type lets you specify real-time events or data changes you want to trigger. Examples include implementing feeds, chat rooms, and more.
Data Fetching
REST
-
- Construct Request – Specify the specific endpoint containing the data you need in the request.
- Send Request – Use a tool or library specific to the client’s programming language to send the request.
- Receive response – The response body includes the requested data. Status codes indicate whether the request succeeded or failed.
- Parse response – The application must parse and format the response body.
GraphQL
-
- The client sends a request for data in a query that specifies the exact data to the API’s uri. You commonly use a library that adds GraphQL functionality to your web app.
- GraphQLfunctions map fields in the query to data in the source and return the data.
- GraphQLfunctions combine data in sources, apply business logic, and execute calculations.
Community
Both have strong communities. However, REST has been around longer and is more widely adopted, so more resources such as tutorials, blogs, documentation, and user forums are available.
GraphQL’s community has grown steadily. Resources include GraphQL.org, GraphQL Weekly, GraphQL Summit, and GraphQL libraries and tools.
Performance
Both are optimized for high performance. GraphQL can be more performant than REST because it reduces over and under-fetching. GraphQL does require, however, an often complex server-side implementation. As a result, API developers must define schemas carefully and optimize queries to avoid performance issues.
Development Speed
While GraphQL is better suited to complex APIs, REST’s simplicity and familiarity among developers can speed up development initially.
Switching to GraphQL may involve a learning curve. Your team’s familiarity with each technology is a factor. In the end, complex APIs require more time to develop than simple ones, whether or not they use REST or GraphQL.
Documentation
REST usually relies on third-party tools that parse a REST API’s Open API spec to generate documentation. However, GraphQ supports complete in-built documentation.
Read more: How to Write API Documentation with Examples
Caching
Both REST and GraphQL server responses are cachable. However, the caching strategy is different.
When a client requests a REST API, the API must indicate that the response can or cannot be cached. Also, it must show how long the client can cache responses. Caching can improve availability and performance by reducing the number of API requests since the client can leverage cached data for a particular time.
For GraphQL, you must cache individual fields since catching the entire GraphQL query response is not feasible. As a result, you need more granular control to cache responses effectively. Therefore, it would be best to have a caching library for GraphQL.
Also read: gRPC vs REST: What’s the difference?
Wrapping Up
REST and GraphQL are technologies used to build web APIs. For example, Facebook created GraphQL to address REST’s over-fetching and under-fetching problems. GraphQL solves this issue by allowing clients to send queries that filter the needed data and structure the data returned in the response.
While GraphQL solves many REST problems, it is less familiar than REST and requires a learning curve.
APIs working with complex data models and relationships between those data models may be better suited to GraphQL. Conversely, simpler APIs not involving complex data may be better suited to discreet and isolated functionality.
Ultimately, it is possible to abstract GraphQL on top of REST to gain both benefits.
An intuitive technical documentation software to easily add your content and integrate it with any application. Give Document360 a try!
GET STARTED