13 min read

GraphQL vs REST API

A side-by-side comparison, advantages/disadvantages of both approaches, real-word examples, getting started with GraphQL, etc. And some new out-of-the-box ideas.
GraphQL vs REST API
A standoff between GraphQL vs REST

My most visited page (querying multiple resources) is not loading, should I use GraphQL instead of REST?

I had this question for my app. And that led me to explore GraphQL. And I went too far away in my research. I will answer the question later in this article but what's more fun for now is to learn what I found. So here it goes, my research about GraphQL vs REST.

Before we dive into the topic, let's get the basics out of the way. If you don't know yet what GraphQL or REST is, read the next two section.

What is GraphQL

Imagine you go to a restaurant where instead of ordering set meals from the menu, you get to customize your own plate. You can ask for just the items you like, in the amount you want, and leave out the rest. That way, you get exactly what you're hungry for and nothing extra.

GraphQL is like that for data on the web. Instead of multiple fixed menus (or endpoints) where you get more or less than what you need, GraphQL allows apps to ask for exactly the data they want, nothing more, nothing less. This makes it easier and more efficient for apps to get information from servers. It's like a customizable menu for your app's data needs!

In a more technical language, GraphQL is a syntax that describes how to request data. It's often termed as a "query language for your API" because, unlike REST, which exposes a fixed set of endpoints per resource, GraphQL allows you to articulate your data needs explicitly.

GraphQL ensures that the client can fetch precisely the data it requires, in a single request.

What is REST

Imagine you're at a fast-food drive-thru. There are specific windows you drive up to: one for ordering, one for paying, and one for picking up your food. Each window has a clear purpose, and you know what to expect at each one.

REST is a way for computer applications to talk to each other using the internet, kind of like how you interact with the drive-thru windows. Each "window" (or endpoint) in REST gives you specific information. For example, one might give you user details, another might list all products, and another might show your order history. You go to each specific window to get what you need.

It's a structured way to get data, just like how the drive-thru has a structured process for you to get your food!

In a more technical language, REST (Representational State Transfer) an architectural (not a protocol or a standard) style for distributed hypermedia systems.

Core Principles of REST

  • Statelessness: Every request from a client to a server must contain all the information required to understand and process the request. No session state is stored on the server between requests, which ensures that the server can treat each request in isolation.
  • Cacheability: Responses from the server can be explicitly labeled as cacheable or non-cacheable. This ensures that clients can cache responses and improve performance and responsiveness.
  • Layered System: REST allows for an architecture composed of layered components. A client doesn't necessarily communicate directly with the server housing the data but might interact with an intermediary layer. This modular approach aids in scalability and flexibility.
  • Uniform Interface: The uniform interface simplifies and decouples the architecture, enabling each part to evolve independently. This principle is foundational and is described in more detail through constraints like the use of standard conventions (URIs) for resource names and standard methods.

RESTful services make use of standard HTTP methods, mapping them to CRUD (Create, Read, Update, Delete) operations:

  • GET: Retrieve information. Corresponds to the 'Read' operation in CRUD.
  • POST: Submit data for processing to a specified resource. Often associated with 'Create'.
  • PUT: Update data or create data if it doesn't exist. Maps to both 'Update' and 'Create' in situations where the client decides the URI.
  • DELETE: Remove the specified resource. Tied to the 'Delete' operation in CRUD.

It's worth noting that while these are the primary HTTP methods, others, such as PATCH (for partial updates) and HEAD (fetch headers without the body), also exist and can be employed in RESTful services.

GraphQL vs REST

With above definitions, one can see that REST is much more intuitive to understand and can improve performance by caching. At the same time, GraphQL can result in better user experience due to reduced network bandwith usage and faster results thanks to optimized query response in complex scenerios.

But in order to understand it in more depth, we need to compare GraphQL and REST based on various parameters:

ParameterRESTGraphQL
Flexibility- Fixed data structure per endpoint.- Clients can specify exactly what data they need.
- To retrieve different data, you might need to hit multiple endpoints.- Single endpoint can return a wide variety of shapes of data.
Over-fetching/Under-fetching- Can lead to over-fetching or under-fetching of data because the server defines what data is returned for each endpoint.- Virtually eliminates over-fetching and under-fetching since clients specify what they want.
Versioning- Typically requires version numbers (e.g., v1, v2) in the URL or header.- No strict need for versioning since new fields can be added to the response and old ones can be deprecated.
Performance- Multiple requests might be needed to gather all required data.- Can retrieve all data in a single request.
- Over-fetching can waste bandwidth.- Only what's needed is fetched, but queries can become complex and potentially slow.
Error Handling- Uses HTTP status codes (e.g., 404, 500).- Typically returns 200 OK status with errors in the response body.
Data Retrieval Example- To get user details: GET /users/123- To get user details: { user(id: "123") { name, email } }
- To get user's posts: GET /users/123/posts- In the same query: { user(id: "123") { name, email, posts { title } } }
Community & Ecosystem- Mature with a wide range of tools and libraries available.- Growing rapidly with a strong community and tooling (e.g., Apollo, Relay).
Learning Curve- Relatively straightforward for most developers.- Steeper learning curve, especially for those new to schema definition and query language.
Endpoint Structure- Multiple endpoints for different resources.- Typically a single endpoint (e.g., /graphql).
Documentation- Requires tools like Swagger for documentation generation.- Has introspection, allowing tools like GraphiQL to auto-generate documentation.

Real-world examples:

REST: The GitHub REST API offers multiple endpoints for each resource. For instance, to fetch user details, one would use GET /users/{username}. To get repositories for a user, another endpoint like GET /users/{username}/repos is used.

GraphQL: The GitHub GraphQL API provides a single endpoint. For fetching user details and their repositories, one query like:

{
  user(login: "username") {
    name
    repositories(first: 10) {
      nodes {
        name
      }
    }
  }
}

This query fetches the user's name and the names of their first ten repositories in one go.

From the table, it's evident that

  • REST offers simplicity and a proven track record
  • GraphQL boasts flexibility and precision

The choice between the two often hinges on the specific requirements and challenges of a project. Let's deep dive into advantage vs disadvantages of each option now.

Advantages and disadvantages

Both GraphQL and REST offer unique advantages that have secured their places in the developer community. However, no solution is without its drawbacks. Let's weigh the pros and cons of each approach based on developer feedback, performance metrics, and adaptability.

Advantages of REST

  1. Simplicity and Familiarity: REST is well-understood by many developers, making it relatively straightforward to implement, especially for simple applications.
  2. Standardization: REST uses standard HTTP methods, which helps in defining clear interfaces for APIs.
  3. Mature Tooling: Given its longer existence, REST boasts a wealth of tools, libraries, and middleware solutions.
  4. Scalability: RESTful systems can be highly scalable due to their stateless nature and can easily be distributed.
  5. Cacheable: Responses can be explicitly marked as cacheable, enhancing performance.

Disadvantages of REST

  1. Over-fetching and Under-fetching: REST APIs can return more data than needed or may not provide all the necessary information in one go, leading to additional requests.
  2. Versioning Challenges: Introducing changes in a REST API often leads to versioning, which can become cumbersome.
  3. Multiple Endpoints: Every resource in REST has its endpoint, which can become challenging to manage for complex applications.
  4. Less Flexibility: Harder to adapt to clients with diverse and rapidly changing needs.

Advantages of GraphQL

  1. Precision: Clients can request exactly the data they need, leading to optimized and efficient queries.
  2. Single Endpoint: Unlike REST, GraphQL typically exposes a single endpoint, making the API easier to manage and consume.
  3. Strongly Typed: GraphQL schemas are strongly typed, ensuring data consistency and integrity.
  4. Developer Tooling: Tools like GraphQL Playground and GraphiQL offer enhanced developer experiences.
  5. Flexibility: Easily adapts to varied and evolving frontend needs.

Disadvantages of GraphQL

  1. Learning Curve: Newcomers to GraphQL might face a steeper learning curve than with REST.
  2. Performance Overhead: Complex queries can lead to performance bottlenecks.
  3. Caching Complexity: Unlike REST's straightforward HTTP caching mechanisms, caching in GraphQL can be more intricate.
  4. Potential Over-fetching on the Server: While clients fetch exactly what they need, the server might still over-fetch from databases.

Feedback from developers often revolves around the flexibility and specificity of GraphQL versus the simplicity and familiarity of REST. In developer forums, REST remains a tried-and-true method for basic applications, while GraphQL is hailed for applications with intricate frontend needs or those that require real-time data.

However, no one-size-fits-all answer exists, and the choice often depends on specific project requirements, team familiarity, and long-term goals.

Interesting ideas

Interesting Ideas for Combining REST and GraphQL

Hybrid Approach:

  • Use RESTful endpoints for writing operations since they're often more straightforward and standardized (CRUD operations).
  • Use GraphQL for reading and consumption due to its flexibility in fetching exactly what's needed.

Middleware Translator:

  • Design a middleware layer that translates RESTful responses into GraphQL schemes. This way, legacy systems built on REST can still benefit from GraphQL's querying capabilities without a complete overhaul.

GraphQL as an Overlay:

  • Use GraphQL as a "view" layer on top of RESTful services, especially for complex frontend applications that require aggregated data from multiple services. This can reduce the number of HTTP requests and improve frontend performance.

Dynamic Endpoints:

  • Allow clients to decide their preferred interaction style. For example, if a client appends /graphql to the endpoint, the server responds in GraphQL. Otherwise, it uses standard REST.

REST for Internal, GraphQL for External:

  • Keep RESTful services for internal microservices communication. This can ensure stability and simplicity for backend-to-backend communication.
  • Offer GraphQL for third-party developers or public APIs, allowing them the flexibility to request data as they see fit.

Adaptive Data Loading:

  • Based on the user's connection quality (e.g., 4G vs. Wi-Fi), the backend could choose to send data either via a few complex GraphQL queries or multiple simple RESTful requests. This ensures optimal data retrieval based on the connection's reliability and speed.

Real-time Data with REST and GraphQL:

  • Utilize REST for initial data load and then employ GraphQL subscriptions for real-time updates. This can be especially useful for applications like dashboards, where initial data can be fetched using REST and updates are pushed in real-time via GraphQL.

Schema Stitching:

  • Merge multiple REST data sources and GraphQL services into a single GraphQL schema. This way, consumers only need to interact with one unified API, regardless of the underlying services.

Error Handling Middleman:

  • GraphQL can sometimes be verbose about errors, which is useful for developers but not always for end-users. Implement a middleware that translates GraphQL errors into simpler REST-style error codes when needed.

API Exploration Portal:

  • Create an API portal where developers can explore both REST and GraphQL endpoints. This portal could automatically generate GraphQL schemas from RESTful services documentation, offering developers a unified experience.

Implementing a combination of REST and GraphQL offers the benefits of both worlds. While the choice ultimately depends on the specific use case, these creative ideas can inspire businesses to think outside the box and harness the strengths of both technologies.

What internet thinks about GraphQL vs REST

HN discussion

Similar to this discussion, I went through numerous discussions on the internet about GraphQL/REST and many of those opinions caught our attention. Here's the summary of those opinions:

damondefault on Reddit:

  • Prefers Backend for Frontend over GraphQL due to perceived complexity.
  • Acknowledges GraphQL's simplicity for quick projects.
  • Encountered challenges with debugging, custom data resolvers, and type generation.

anonymous on Reddit:

  • Utilizes a mixed approach: GraphQL for reads and RESTful APIs for writes.
  • Advocates for GraphQL's self-documenting, type-safe interfaces.
  • Notes that creating customized interfaces in REST can be like "GraphQL with extra steps."

zyl0x on Reddit:

  • Finds REST simpler to implement, debug, and secure.
  • Regrets his company's decision to use GraphQL, especially without a mobile frontend.

namelosw on HackerNews:

  • Agrees that GraphQL addressed real issues present in REST.
  • However, sees GraphQL as a problematic solution with significant hassle.

hderms on HackerNews:

  • Believes GraphQL offers benefits mainly to large-scale companies.
  • Lists advantages such as reduced HTTP connections, better backend-for-frontend services, and addressing frontend performance issues without changing the frontend.

jensneuse on HackerNews:

  • Suggests using REST for websites, GraphQL when frontend interacts with diverse backend teams, OpenAPI for backend-to-backend communication, and gRPC when relevant.

timr on HackerNews:

  • Advocates for REST by default.
  • Views GraphQL as an unnecessary burden with limited practical gains.
  • Questions the supposed need for newer tools in modern web development.

b212 on HackerNews:

  • Criticizes Apollo + GraphQL for being over-engineered.
  • Argues that GraphQL doesn't effectively address issues it promises to solve, such as over-fetching.

stickfigure on HackerNews:

  • Warns about GraphQL's vulnerability to DOS attacks.
  • Compares public-facing GraphQL to exposing a SQL interface, deeming it risky.
  • Emphasizes that there are no truly private APIs on the web.

kreetikal on Reddit:

  • Praises GraphQL for automatic validation, documentation, and flexibility for clients.
  • Raises concerns about the loss of conventional error response codes in GraphQL.

Srbalj on Reddit:

  • Highlights numerous benefits of GraphQL, including fewer API calls, type safety, improved developer experience, and better API control.
  • Emphasizes the importance of correct implementation to harness GraphQL's potential benefits.

Despite the oppposing perspectives, we do see a trend that indicates

Love it or hate it, but you can't ignore GraphQL
REST vs GraphQL trend. Source: https://insights.stackoverflow.com/trends?tags=graphql%2Crest

Before, you can make your own informed judgement, let's try out GraphQL for a sample project.

Get Started with GraphQL

Welcome to this tutorial on setting up a basic GraphQL server using Apollo. By the end of this guide, you'll have a functional GraphQL server that you can query for book data.

Find the code for a trial project below

Wait, what were the steps to create this trial project, let's learn about that:

Step 1: Create a new project

Start by setting up a new project directory:

mkdir graphql-server-example
cd graphql-server-example

Initialize a new Node.js project:

npm init --yes && npm pkg set type="module"

This command sets up the project using ES Modules, which enables us to use top-level await and simplifies our examples. You should now have a package.json file in your project directory.

Step 2: Install dependencies

Apollo Server needs two main dependencies:

  1. graphql: The core GraphQL library.
  2. @apollo/server: The main library for Apollo Server.

Install these packages with:

npm install @apollo/server graphql
Note: This tutorial will be using JavaScript for simplicity. However, you can also set up with TypeScript if preferred.

Step 3: Define your GraphQL schema

Every GraphQL server uses a schema to define the structure of queryable data. For this tutorial, we're setting up a server to query books by title and author.

Create an index.js file and add the following:

import { ApolloServer } from '@apollo/server';

const typeDefs = `
  type Book {
    title: String
    author: String
  }

  type Query {
    books: [Book]
  }
`;

This defines a simple GraphQL schema where clients can query an array of books.

Step 4: Define your data set

Now, let's define some sample data:

const books = [
  {
    title: 'The Awakening',
    author: 'Kate Chopin',
  },
  {
    title: 'City of Glass',
    author: 'Paul Auster',
  },
];

For this tutorial, we're using hardcoded data, but in real-world applications, this could come from databases, other APIs, etc.

Step 5: Define a resolver

Resolvers specify how to fetch data for a given type. Since our data is hardcoded, our resolver is simple:

const resolvers = {
  Query: {
    books: () => books,
  },
};

Step 6: Create an instance of ApolloServer

Provide Apollo Server with your schema, data, and resolver:

const server = new ApolloServer({
  typeDefs,
  resolvers,
});

server.listen().then(({ url }) => {
  console.log(`πŸš€  Server ready at: ${url}`);
});

Step 7: Start the server

Run your server:

npm start

You should see:

πŸš€  Server ready at: http://localhost:4000/

Step 8: Execute your first query

Visit http://localhost:4000 to open the Apollo Sandbox. You can now write and execute GraphQL queries.

Try the following query:

query GetBooks {
  books {
    title
    author
  }
}

Execute it, and you'll see the results from our hardcoded data. Feel free to experiment with the fields to see how GraphQL allows you to query only what you need.


Congratulations! You've set up a basic GraphQL server with Apollo.

New tools to consider

While researching, I ended up on this another similar project as GraphQL - tRPC, which aims to achieve the same goals as GraphQL having tight integration with typescript. As they mention, with tRPC, one can "build & consume fully typesafe APIs without schemas or code generation". It seems to have a good attention from the dev community (29k stars on GitHub), worth trying out. Maybe, later when I'm done with my experiments with GraphQL.

GitHub - trpc/trpc: πŸ§™β€β™€οΈ Move Fast and Break Nothing. End-to-end typesafe APIs made easy.
πŸ§™β€β™€οΈ Move Fast and Break Nothing. End-to-end typesafe APIs made easy. - GitHub - trpc/trpc: πŸ§™β€β™€οΈ Move Fast and Break Nothing. End-to-end typesafe APIs made easy.

Conclusion

Overall, my impression - GraphQL is not as easy as I wished for. But when I look at my problem, I can see how in some cases, I will choose REST to solve the same problem via caching, while in other cases, I will choose GraphQL. Hope this article makes you little more confident in choosing what's right for your case. If in doubt, I'll go with REST. YMMV.


References

GraphQL Is a Trap? | Hacker News
GraphQL vs. REST APIs: a complete guide | Hacker News
Best practices for REST API design (2020) | Hacker News
Why not use GraphQL? | Hacker News
GraphQL vs. REST in the real world
by u/JohannesFrey in graphql