For some years now, the APIs are an integral part of the landscape in the developers' communities. During the React-Europe, a new challenger called GraphQL, appeared, two years ago. And I am almost certain that you have already heard about it. In this post, I will try to explain how GraphQL could be a game changer for fetching your data and why the API are necessary more than ever.
Before we go any further, I would start by defining the terms that I will use below. It is truly important to understand each concept behind those technologies.
An API is an interface which provides a list of functionalities to interact with a software. For example, Stripe offers an API that allows making payments, refunds, invoices, etc. Thanks to the APIs, your data management can be centralised and your front-end app separated from your back-end.
GET https://api.stripe.com/v1/refunds/re_18mMcv2eZvKYlo2C6yUDxm44
This request retrieves the refund with the ID re_18mMcv2eZvKYlo2C6yUDxm4
REST is an architecture style for an API. That's a set of conventions, rules and good practices to follow. I will not expand more on them. If you want more information about it, I recommend looking at this good website dedicated to REST.
GraphQL is a data fetching language that allows clients to declaratively describe their data requirements with a JSON-like format. Furthermore, GraphQL is database agnostic. Its design allows you to deal with every kind of databases. For more about GraphQL, I strongly recommend reading the posts of the awesome Apollo Team!
1{
2 user(id: 1234) {
3 firstname
4 lastname
5 }
6}
This is a very simple GraphQL query which requests the first name and the last name of the user with the ID #1234.
At Strapi, we are working especially with REST API. The REST API provides a great way to build powerful applications. The API ecosystem is becoming a more mature each day. Companies such as Facebook, Twitter, Netflix, etc... are using their APIs to offer some parts of their functionalities to the third app for many years now. Every app which has more than one client needs to build an API. REST is the most common architecture used to create an API.
However, since the introduction of GraphQL, many people expressed their feelings about GraphQL and its future:
Every one of them agrees on one thing: the efficiency for clients-app to fetch data. And I can't say otherwise. GraphQL seems the answer, for now, to easily fetch your data. However, when people talks about GraphQL they always talk about the fetching part. But GraphQL can also have mutations!
Mutations are the way to change the dataset behind GraphQL.
*Developer traduction:
A mutation is a function executed on each request. Nothing else.*
This kind of operation highlights some very common layers such as validations, authentication, or policies. While these layers are well-defined and established in a REST architecture, the implementations with GraphQL are still difficult to find. There is a lack of good practices to follow for these very commons patterns.
To understand of what I'm speaking about, an example should be better.
*User story:
As an administrator, I want to be able to update a post on the blog.*
== Notes: ==
Pretty simple, no? In this user story, I have to handle the role of the user. This mutation cannot be resolved if the user is not an administrator, a post's owner or a moderator. I also have to validate the input values and reject the request if the user which is making it is not authenticated.
GraphQL is non-opinionated, it doesn’t tell you how to do or implement those layers. Each one needs to be handled by the back-end server. With GraphQL as an abstract layer between your clients and your back-end server, the lack of resources could become very annoying...
The Apollo stack tries to provide a beginning of an answer but not on all these points (A guide to authentication in GraphQL).
Moreover, Dan Schafer which is working on GraphQL at Facebook talked about the Facebook's GraphQL stack during the last React-Europe in Paris. He introduced the viewer
concept. This concept aims to allow or disallow a user to execute the logic into a resolver if he is granted or not. It seems that Facebook begins to share their GraphQL patterns... We are looking forward to see more patterns and good practices that help the GraphQL community solve those recurrent difficulties. But for now, the REST API looks still a better way to handle the validations, authentication, policies, etc.
At Strapi, we believe on the future of GraphQL. Strapi provides an easy way to create API on the fly and query your data through a generated GraphQL schema. We made this choice to benefit from both technologies and get their full potential. Which means when you are mutating data through GraphQL, the resolver redirects your request to the REST controller. If you had added policies, authentication's or validation's rules on this controller's action, they will be resolved.
GraphQL is not the perfect answer without a solid and convention-based solution, and the REST APIs have proven since many years that they are working very well. The REST APIs and GraphQL are the future! GraphQL fills some lack of the REST APIs, and vice-versa.
I thought a summary table with the current pros and cons of GraphQL and REST API could be interesting. I hope that table could help some of you to make a choice for your future app.
These observations came from our experiences with GraphQL and REST API. We are looking forward to read your comments or thoughts about REST API and GraphQL, and how you deal with it?
GraphQL is a query language for APIs that makes data fetching efficient. Unlike REST, where you might over-fetch or under-fetch data, GraphQL lets you ask for exactly what you need.
Direct Integration: Query a database directly using GraphQL, ideal for new projects.
Wrapping Existing APIs: Wrap existing REST APIs with GraphQL to modernize interactions without a complete rewrite.
Hybrid Approach: Combine direct database queries and wrapped REST APIs for flexibility and gradual migration.
Efficiency in Data Fetching: GraphQL lets you request exactly the data you need, avoiding over-fetching and under-fetching.
Improved Performance: Reduce the number of API calls, enhancing application performance.
Enhanced Flexibility: Modify queries to fetch new data fields without changing the backend.
Scalability: Scale API infrastructure without significant rewrites by adding new fields and types as the application grows.
Initial Setup: Set up a GraphQL server using Apollo Server or GraphQL Yoga.
npm install apollo-server graphql
Define Data Types: Model API data types by defining the GraphQL schema.
1type Query {
2 user(id: ID!): User
3}
4
5type User {
6 id: ID!
7 name: String
8 email: String
9}
Create Resolvers: Create resolvers to fetch data from REST API endpoints.
1const resolvers = {
2 Query: {
3 user: async (_, { id }) => {
4 const response = await fetch(`https://api.example.com/users/${id}`);
5 return response.json();
6 },
7 },
8};
Expose GraphQL Endpoint: Set up the server to listen for GraphQL queries.
1const { ApolloServer } = require('apollo-server');
2
3const server = new ApolloServer({ typeDefs, resolvers });
4
5server.listen().then(({ url }) => {
6 console.log(`🚀 Server ready at ${url}`);
7});
Caching and Optimization: Use tools like DataLoader to batch and cache requests.
1const DataLoader = require('dataloader');
2
3const userLoader = new DataLoader(keys =>
4 Promise.all(keys.map(id => fetch(`https://api.example.com/users/${id}`).then(res => res.json())))
5);
Complexity: Manage complexity with incremental adoption, clear documentation, and tools like Strapi.
Performance Overhead: Mitigate performance overhead with efficient caching, optimized resolvers, and performance monitoring.
Learning Curve: Use resources like the GraphQL official documentation, Stack Overflow, and tutorials on Egghead and Udemy.
Maintenance: Use consistent naming conventions, automated testing, and version control.
PS: I know this kind of post could be controversial because I compare two technologies with different philosophies. I don't pretend to have the answer. This is our answer, at Strapi, to these difficulties. I'm pretty sure this will evolve in the future.
Co-founder & Chief Product Officer, I started developing since I was 13 years old, I already developed 2 CMS before and am currently in charge of the product vision & strategy.