Why GraphQL is the future of API development

Rishi Collins

by Rishi Collins | February 02, 2023

In recent years, the internet has changed drastically, from how we humans use it to how developers create and manage their applications.

Although the average end user may not see or notice it, the API is usually the "brains" of every primary application, whether web, mobile, or desktop-based. Up until 2015, most APIs followed the REST implementation.

REST was based on a series of methods, GET, POST, PUT, PATCH, DELETE, to name a few. These methods indicate what was being sent to the server and what would be expected in response. For example, a GET request would be sent to retrieve a page or data from the server, as you do whenever you view any web page. On the contrary, a POST request is sent when sending data to the server, such as when registering for an account on a website.

REST relies on individual endpoints for each task, essentially a specific URL. So, if you had a web service with a REST API and wanted to manage users, you would have to create multiple endpoints.

All Users:

GET /api/users

User by ID:

GET /api/users/:id

Create a user:

POST /api/users/create

When creating a large-scale application, you can quickly see how tedious and inefficient this can become. Additionally, since you cannot change the data returned in each response, your server often sends back more information than the client needs at that given time.

2015 changed everything. This was when Facebook released GraphQL, which they had been developing internally since 2012. GraphQL solves almost all the inefficiencies of REST.

Instead of creating multiple endpoints for each task, every API call would now be accessible from a singular endpoint.

/api/graphql

You may wonder, how can GraphQL do all of these things for me? Well, three things, Queries, Mutations and a Schema.

Your schema defines what you will be querying with the API. This should be relatively easy if you're already set up with a database. A GraphQL schema follows as such:

type User {
    id: String
    name: String
    email: String
    role: String
    isAdmin: Boolean
    phoneNumber: String
}

//GraphQL Schemas always contain a 'Query' type to define what to return
//A 'Mutation' type is also needed if uploading data.

type Query {
    allUsers : [User]
    user(id: String): User
}
type Mutation {
    createUser(
        name: String
        email: String
        phoneNumber: String
    ): User
    updateUser(
        id: String
        name: String
        email: String
        phoneNumber: String
    ): User
 
}

Once your schema is set up, you need to define what to do with it. This is where resolvers come into play; think of this as your main API logic.

/resolvers.ts
Query: {
 allUsers: async () => {
            return await prisma.user.findMany()
        },
        user: async (_: any, args: any) => {
          //query your database here. I am using Prisma's ORM as an example.
            return await prisma.user.findUnique({
                where: {
                    id: args.id
                }
            })
        },
},
Mutation: {
createUser: {
            async resolve(_: any, args: any, ctx: any) {
                return await prisma.user.create({
                    data: {
                        //user data
                    }
                })
            }
  }

In resolvers, you can do pretty much anything. For example, if you want to restrict specific data to authenticated users but not the entire API, you can do so in resolvers. See more on this topic.

Now that your schema and resolvers are configured, you can start your GraphQL server. How you do this strictly depends on your programming language and GraphQL framework. Here's an example for Apollo Server (JavaScript)

Once your server is fired up, you're ready to start querying:

allUsers {
  id
  name
}

The above query would return the following:

"data": {
   allUsers: {
     {
      "id": 1,
      "name": "John Doe:
     },
     {
      "id": 2,
      "name": "Jane Doe:
     }
  }
}

Since in the query, we only defined that we wanted id and name returned, that's all we get. Simply put, GraphQL will only return what you asked it to, whereas, with REST, the entire User object would be returned regardless. Furthermore, all of these functions are accessible from one singular endpoint, regardless of the HTTP method.

Overall, GraphQL makes it significantly easier to develop APIs, but it is much less resource intensive on your server, as you're not constantly over-fetching data you don't need. What you ask for is what you receive. This is why I've been creating APIs for my recent projects almost exclusively with GraphQL.

I will admit there is a slight learning curve to GraphQL. But once you've passed that slight hump, you will never want to go back to REST.

Ready to start learning GraphQL? If you're using JavaScript, I personally recommend Apollo Server. But remember, GraphQL is language agnostic, so you can use it with any server-side programming language Learn GraphQL.

Date Last Updated: February 02, 2023