DEV Community

Cover image for Understanding GraphQL through REST
John Fay
John Fay

Posted on • Updated on

Understanding GraphQL through REST

In order to understand why GraphQL is continuing to gain attention, it is increasingly helpful to understand what it was intended to improve upon. One of the beauties of Software Engineering is the constant desire to improve upon what was provided to us. GraphQL tries to do this with REST. By the end, you will have examples of REST API(Application Programming Interface) endpoints, how GraphQL queries relate to those REST endpoints, and why GraphQL exists. Let's get started.

Let's get started

Understanding REST

REST stands for REpresentational State Transfer.

Holy forking shirt balls - The Good Place

This architecture is known for being stateless and able to separate concern between client and server.

Stateless

Stateless in this sense means the server does not need to know what the state of the client is to execute an action.

Separation of Concern

Client and server separations allow for developers to change the server without it affecting the client-side code and vice versa.

Communication

When comparisons come into play with other API specifications, what actually makes REST unique is how the client and server communicate. REST was developed alongside HTTP(Hypertext Protocol Transfer) 1.1 back in the late '90s. Because of this, REST was able to leverage the benefits of HTTP. To illustrate the communication I'll be using a generic model with genres and books.

1 Genre to Many Books

We will review receiving and updating a data source through a REST API.

Receiving Information from a REST API

GET /genres

When a client visits this endpoint they will be returned a list of genres.

[
  {
    "id": 1,
    "name": "Mystery"
  },
  {
    "id": 2,
    "name": "Romance"
  }
]
Enter fullscreen mode Exit fullscreen mode

Similar to genres, books would be the exact same

GET /books

[
  {
    "id": 1,
    "title": "The lost man",
    "author": "Jane Harper",
    "img": "/img/jh-tlm.png"
  },
  {
    "id": 2,
    "title": "And then there were none",
    "author": "Agatha Christie",
    "img": "/img/ac-attwn.png"
  }
]
Enter fullscreen mode Exit fullscreen mode

As you can see, this is a very predictable and scalable process. If our model above changed to include another model such as Libraries, we could easily add-in that endpoint and keep chugging along.

CRUD Operations in REST

In creating a service to handle CRUD(create, replace, update, and destroy) operations we would create the following

  • POST /genres

Create a new genre

  • PUT /genres

Update an existing genre

  • DELETE /genres

Remove or delete an existing genre

In REST API development taking advantage of the HTTP methods provided makes communicating with these available endpoints very predictable.

Summary

The general idea behind REST API's is to make everything an endpoint. If you need to add or remove pieces of information from a request to take the load away from your client's browser, you can easily do so without giving the client too much knowledge of what is going on behind the scenes. Above all, REST aims to be fast, reliable, and predictable while taking advantage of all HTTP.

Laughing

What is GraphQL?

GraphQL is a language for querying an API. Not enough? Don't worry, more is coming.

This broke me

Contrary to REST API's, GraphQL provides one HTTP endpoint and an understandable description of the data available through type specification. This gives the client the ability to request what they need and nothing more. This query language is much closer to the data sources giving the frontend developers more access to available models and relationships between them. With that, they are able to get many resources in a single request.

Type Specification and Self Documentation

Instead of REST endpoints returning different return types per endpoint, GraphQL relies on types and fields to tell your client what is possible.

type Query {
  books: [Book]
  genres: [Genre]
}

type Book {
  id: Int
  title: String
  author: String
  img: String
}

type Genre {
  id: Int
  name: String
  books: [Book]
}
Enter fullscreen mode Exit fullscreen mode

With this, anyone needing the API to develop client-side code can reference developer tooling to see all the possible queries thanks to the type specifications and self-documenting.

Hot diggity dog!

Request What is Needed and Nothing More

In our genres and books data source, when we request a book we will always get all available keys.

[
  {
    "id": 1,
    "title": "The lost man",
    "author": "Jane Harper",
    "img": "/img/jh-tlm.png"
  },
  {
    "id": 2,
    "title": "And then there were none",
    "author": "Agatha Christie",
    "img": "/img/ac-attwn.png"
  }
]
Enter fullscreen mode Exit fullscreen mode

With GraphQL we can add and remove keys to format only the data needed on the frontend. Let's say, for example, we are creating a page that only wants the title and image we could create a query to do so.

query {
  books {
    title
    img
  }
}
Enter fullscreen mode Exit fullscreen mode

This would return the same result without the author and id keys.

[
  {
    "title": "The lost man",
    "img": "/img/jh-tlm.png"
  },
  {
    "title": "And then there were none",
    "img": "/img/ac-attwn.png"
  }
]
Enter fullscreen mode Exit fullscreen mode

Now here we go

Get many resources in a single request

In the above REST example, if we wanted to get both genres and books we would have a few options.

  1. Make multiple requests to /genres and /books
  • This would force the client-side to resolve these relationships itself.
  1. Add books relationship into the /genres endpoint.
  • The only negative to this would be now anytime you want to fetch genres you are forced to also include books with it which is a problem of over-fetching as referenced above.
  1. Make a new endpoint or add an option that would allow fetching of both genres and books.
  • This is most common because it will not interfere with existing frontend applications connected to your API.

Instead of planning the relationship and response for each endpoint GraphQL aims to make all relationships available through the type specification.

Nice

Versioning

Communication between frontend and backend teams can be difficult. In the example of changing an endpoint, you would need to communicate with the frontend teams to ensure they prepare for any breaking changes. With GraphQL it's easy to add or remove fields relative to your types above.

type Book {
  id: Int
  title: String
  author: String @deprecated
  authoredBy: Author
  img: String
}

type Author {
  firstName: String
  lastName: String
}
Enter fullscreen mode Exit fullscreen mode

This could result in less communication needed between the teams and less breaking changes downstream.

Happy

The Basics

Query vs. Mutation

Thus far the examples above are all queries. Queries and mutations replace endpoints to all resolve to one endpoint POST /graphql. This endpoint can be changed but what is always consistent is everything is a POST request. Past that you either send a query variable or mutation variable. The formatting used is always spaced out for ease of reading and copied from the developer tools frequently used such as GraphiQL. Here is an example of GraphiQL used to query countries. Try it out!

GraphiQL is awesome

Query

Queries are all related to GET requests in a REST API. Queries are the primary focus of GraphQL and what makes it unique. Instead of hitting a REST endpoint GET /books you would use a single endpoint POST /graphql and send a query variable. Here is an example.

query {
  books {
    id
    title
  }
}
Enter fullscreen mode Exit fullscreen mode

Mutation

PUT, POST, and DELETE endpoint equivalents in GraphQL are mutations.

POST /book?name=Storyteller

mutation {
  createBook(
      {
          name: 'Storyteller'
      }
  ){
      // what you want to return
      id
      name
  }
}
Enter fullscreen mode Exit fullscreen mode

One key difference above, regardless of mutations or queries, we always need to resolve the responses in the // what you want to return section. To me, this still seems awkward because you typically just want to know whether creating the books succeeded or failed. It's up to the client to decide how to handle that as opposed to a REST endpoint returning an id for example.

Nothing left to teach

Why you should know GraphQL

A Brief History

GraphQL was made by the internal team at Facebook but released to the open-source community in 2015. Sometime around 2012, the Facebook team wanted to combat a few problems they saw in their REST API's. Mobile applications were getting slower with their heavily over-fetched data. They were sharing API's across multiple client applications, and changing one endpoint could be considered a breaking change to one client app.

It's Still Growing

GraphQL Impact

In the State of JS 2019 survey, about 6% of developers in the JavaScript community are still unfamiliar with it but the remaining majority express interest in it. Since it's inception to the open-source community in 2015, it's been gradually growing. The open-source community has really run with this API specification and is building more tools to take this thing further and further.

Connect to Multiple Data Sources

I'm used to creating a three-tier app with an API that connects directly to a database, so restarting your API to leverage GraphQL benefits might seem like a large overhaul. This isn't the case, in fact, the community has fantastic resources for leveraging your already existing REST API to generate a GraphQL layer. So take your REST API, database, or an existing GraphQL API and you can make one unifying endpoint for all.

Support

Facebook isn't going anywhere and they make great tools that help the open-source community build great things. If you're a React developer you know all about this! Open source is also having a field day with tooling to make this an even better developer experience. One of my favorites is the graphql-code-generator where we can auto-generate TypeScript types and type-graphql types after creating your schema.

Support

Part 2. Creating a GraphQL API using a REST API

If you are interested in learning about creating a GraphQL API utilizing a REST API as your data source here it is.

Summary

REST and GraphQL are useful specifications for sharing data. REST is scalable, stateless, and great at separating concerns. GraphQL tries to build on REST's shortcomings in terms of over-fetching data, needing to request multiple times to get all the information needed on the client-side, versioning, and manual documentation. We learned the basics of the differences between REST and GraphQL and their various terminologies such as queries and mutations. GraphQL is growing thanks to open-source software development and developer experience satisfaction. If you haven't already, try it out.

You're ready

Oldest comments (2)

Collapse
 
madza profile image
Madza

This is well put together 😉👍
Personally, GraphQL has always reminded me of working with DOM 😉

Collapse
 
jhelberg profile image
Joost Helberg

Well done. One of the great things about graphql is that a client can tell which data is requested. This results in a server fetching only needed data. Wel... not. Most graphql server implementations don't support telling the server which columns are requested and which are not. Graphql is great, documentation wise and operational wise, but server implementations are not good enough.