REST API to GraphQL Migration

REST API coexisting with GraphQL API. Source: Haldar 2019.
REST API coexisting with GraphQL API. Source: Haldar 2019.

While GraphQL has its limitations, there are many advantages that make it worthwhile to migrate existing REST APIs to GraphQL. To reap these benefits, it's important to think in terms of graphs rather than endpoints.

The migration itself can be done in one go for small projects. An incremental approach is preferred for complex projects handled by large teams. For most projects, it's expected that current REST APIs will coexist with new GraphQL APIs. This is because clients may not migrate to new app versions or update their code immediately.

In general, migration will involve building the GraphQL schema and writing the resolvers for that schema.

Discussion

  • What's a possible migration path from REST to GraphQL?
    Migration path from REST to GraphQL. Source: Adapted from Mayorga 2018.
    Migration path from REST to GraphQL. Source: Adapted from Mayorga 2018.

    Let's assume that we're using REST API and React client (a). We can start by keeping the REST endpoints but wrapping it with a GraphQL gateway (b). We need to define the GraphQL schema. React client will now call a single GraphQL endpoint. Resolvers will use REST endpoints for fetch the data.

    A natural evolution from here is to implement the GraphQL server (c). We can remove the gateway. React client will directly call the new GraphQL API. This has direct access to the database layer and therefore lower latency compared to the gateway architecture. REST endpoints may coexist to support legacy clients.

    A React client does imperative data fetching and might do manual client-side caching. By migrating to Apollo Client, we can do declarative data fetching and zero-config caching. By using Apollo Link REST, we don't even need changes at the server side. This could be an easy way to get started. The final goal is to have GraphQL API and Apollo Client (d).

  • To design for GraphQL, what sort of mindset should I have?
    Visualize the graph when designing a GraphQL API. Source: Engledowl 2017.
    Visualize the graph when designing a GraphQL API. Source: Engledowl 2017.

    One study found that reducing the number of API calls by migrating to GraphQL is not a trivial exercise. Suppose the current code is organized to consume small amounts of data returned by specific REST endpoints. Refactoring this into fewer endpoints that return large graph structures requires a graph-based mindset.

    Developers have to stop thinking in terms of endpoints and start thinking in terms of graphs. It's important to understand this before designing the GraphQL schema. A typical endpoint-based approach is to ask, "What pages are there and what data each of them needs?" With graph-based approach, we should instead focus on the data and its relationships, and seek to expose these to clients.

    Consider a blogging site. Let's think about exposing user information. Relationships from the user might include posts, comments, liked articles, groups, etc. Thus, we are building a graph around the user. Relationships are bidirectional. When focusing on a comment, we should also link it back to the user.

    In short,

    Think in graphs, not endpoints. Describe the data, not the view.
  • How is TypeScript relevant to GraphQL?
    Type consistency from database to server code to client code. Source: Shtatnov and Ranganathan 2018.
    Type consistency from database to server code to client code. Source: Shtatnov and Ranganathan 2018.

    Unlike vanilla JavaScript, TypeScript gives type safety at the client side. GraphQL gives type safety at the server side.

    Suppose we have a client that uses only JavaScript. If this client makes a query to the GraphQL server in which the types don't match. This error will be caught at the server during runtime. Instead, if the client code had been in TypeScript, such a mismatch would have been caught during the build process. We can deploy our code with lot more confidence.

    A good approach is to define GraphQL schema and then use tools to auto-generate TypeScript types for the front-end. Ideally, we could extend this to the database layer so that from browser to the database, types are consistent.

    In general, we should strive for type consistency systemwide. At Airbnb, they defined Thrift IDL that was then compiled into GraphQL schema. Moreover, they then automatically generated TypeScript types from the GraphQL schema.

  • Should I implement caching for my GraphQL service?
    Caching avoids duplicate REST calls. Source: Shtatnov and Ranganathan 2018.
    Caching avoids duplicate REST calls. Source: Shtatnov and Ranganathan 2018.

    A single client query can trigger multiple resolvers. GraphQL resolvers run as independent units. This has the benefit that even if some of them fail, the ones that succeed return the requested data to the client. One problem is that across resolvers there could be many duplicate calls to REST endpoints.

    It's to solve this problem that a caching layer is helpful. Resolvers need not worry about optimizing their calls to REST endpoints. At Airbnb, engineers approached this problem via what they call a data-centric schema and a data hydration layer.

    At another level, we can cache client request-response. Since GraphQL doesn't support HTTP-level caching, we need an alternative. It's possible to use application-level caching, such as Spring Boot caching. Database queries can also be optimized via caching.

  • Could you share some case studies on migrating to GraphQL?
    At Netflix, the same graph model powered different views. Source: Shtatnov and Ranganathan 2018.
    At Netflix, the same graph model powered different views. Source: Shtatnov and Ranganathan 2018.

    At Netflix, the Marketing Technology team adopted GraphQL to solve their network bandwidth bottlenecks. Their use cases were complex and building custom REST endpoints for each page was cumbersome. GraphQL matched their graph-oriented data structures. They could roll out features lot faster. A GraphQL middle layer reduced number of direct calls from the browser. Instead, server-to-server calls within the data centre gave 8x performance boost. Payload of 10MB reduced to 200KB.

    At Airbnb, they reconciled legacy presentation services with GraphQL by having Thrift/GraphQL translators per service. These services were then exposed to clients via a GraphQL gateway service.

    At PayPal, a user checkout involved many round trips. Reducing round trips with REST meant overfetching data. They also found that UI developers spent less time building UI. Mostly, they were trying to figure out where and how to fetch data. After moving to GraphQL, data performance and developer productivity improved.

    Interested readers can head to the official GraphQL website that shares a number of GraphQL case studies.

  • Are there tools that help with GraphQL migration?

    GraphiQL is an in-browser IDE. Via GraphiQL, you can look at the schema, make queries and look at the responses. GraphQL Editor, GraphQL Playground and GraphQL Voyager are other useful tools.

    Apollo Server and Apollo Client provide server and client-side implementations of GraphQL. Apollo Client can integrate with React, Angular or Vue frameworks. As an alternative to Apollo Client, there's Relay to act as a bridge between GraphQL and React.

    There are many tools that can read your REST API files and export GraphQL schema. Apimatic's API Transformer is one such tool. Input files can be in various formats such as OpenAPI, RAML, or API Blueprint. This tool can also migrate SOAP users by translating WSDL files.

    Some clients may want to use only REST. To avoid maintaining two codebases, we can have a GraphQL schema and generate REST APIs from it. Sofa is a Node.js package that does this.

  • How I do map REST features to their equivalent GraphQL features?

    Using REST, a client would make an endpoint call, parse the response and make further calls to get all relevant data. This is the N+1 problem. This can be solved using the nested API design but this leads to overfetching. With a well-designed GraphQL API, clients should be able to and should request only relevant data with a single API call. Moreover, we should make use of connections. A connection encapsulates the queried node and other nodes to which it's connected by edges. This comes directly from the underlying graph-based data abstraction.

    In REST, we paginate with a query string such as ?limit=1&page=2. Cursor-based pagination is the GraphQL equivalent. It's typically used with connections using arguments first, last, offset or after.

    In REST, POST, PUT or DELETE requests modify data. In GraphQL, clients can instead use mutations. We could define mutations to create, update or delete items.

    GraphQL prefers serving a versionless API and avoids breaking changes as the API evolves. Clients only request what they need and understand. In REST, the practice has been to serve different versions.

  • Could you share some tips and best practices for moving to GraphQL?

    GraphQL should be a thin layer. Tasks such as authentication, caching or database queries should happen below the GraphQL service layer. By doing this, application will be more resilient to changes in platform or services. Likewise, name your fields in a self-documenting manner. Once clients start using them, it becomes hard to change later.

    Don't force clients to replace all their REST endpoint calls to GraphQL. Instead, allow them to adopt GraphQL incrementally. Shopify documentation shows how responses from REST endpoints can include GraphQL IDs that can be used for subsequent GraphQL queries.

    Resolvers should be thin and fetch data asynchronously. Fetch data at field level and de-duplicate requests using a library such as DataLoader.

    Server logs help in debugging GraphQL calls. To debug within the browser, include logs into the response payload when enabled by a flag.

    With GraphQL, we often fetch partial objects that can't be directly used in methods that need full objects. Use duck typing to get around this.

Milestones

Jul
2015

Facebook open sources GraphQL, which is also released as a draft specification. The development of GraphQL within Facebook can be traced back to 2012.

Jun
2019
GraphQL performs better than REST. Source: Brito et al. 2019.
GraphQL performs better than REST. Source: Brito et al. 2019.

Brito et al. compare the performance of GraphQL against REST using seven open source clients to call GitHub and arXiv APIs. They also make typical queries noted in recent papers presented at engineering conferences. They find that GraphQL results in 94% less number of fields fetched and 99% less number of bytes. These are median values. However, there's no significant reduction in the number of API calls.

Oct
2019
GraphQL migration journey at Airbnb. Source: Devopedia 2019.
GraphQL migration journey at Airbnb. Source: Devopedia 2019.

Airbnb engineer Brie Bunge shares Airbnb's migration journey to GraphQL. They adopted an incremental approach, making sure the app is always shippable and regression-free. As pre-requisites, they set up GraphQL in the backend and adopted TypeScript in the frontend. Migration itself had five stages. The approach was to first replace REST with GraphQL. Refactoring and optimizations were done later.

References

  1. AltexSoft. 2019. "GraphQL: Core Features, Architecture, Pros and Cons." Altexsoft, March 23. Accessed 2019-12-08.
  2. Betts, Thomas. 2019. "Migrating to GraphQL at Airbnb." InfoQ, December 03. Accessed 2019-12-08.
  3. Brito, Gleison, Thais Mombach, and Marco Tulio Valente. 2019. "Migrating to GraphQL: A Practical Assessment." arXiv, v1, June 18. Accessed 2019-12-08.
  4. Bunge, Brie. 2019. "Migrating to Apollo + GraphQL at Airbnb." GraphQL Summit, via Apollo GraphQL on YouTube, October 30. Accessed 2019-12-08.
  5. Burk, Nikolas. 2018. "How to wrap a REST API with GraphQL - A 3-step tutorial." Prisma, February 22. Accessed 2019-12-08.
  6. Byron, Lee. 2015. "GraphQL: A data query language." Facebook Code, September 14. Accessed 2019-12-08.
  7. Byron, Lee. 2016. "Lessons From 4 Years of GraphQL." GraphQL, November. Accessed 2019-12-08.
  8. Danutama, Karol. 2018. "GraphQL — Case Study : KASKUS Groups." gdplabs, on Medium, September 30. Accessed 2019-12-08.
  9. Engledowl, Matt. 2017. "Build Better GraphQL APIs: Thinking In Graphs." GraphQL { me }, November 11. Accessed 2019-12-08.
  10. GraphQL. 2019. "Pagination." GraphQL. Accessed 2019-12-08.
  11. Haldar, Mahesh. 2019. "Migrating Existing REST APIs to GraphQL." Bits and Pieces, on Medium, June 26. Accessed 2019-12-08.
  12. Kraeling, Brandon. 2019. "How to Think in GraphQL Coming From a REST Mindset." Differential, December 06. Accessed 2019-12-08.
  13. Mayorga, Julian. 2018. "Gradually migrating a Node and React app from REST to GraphQL." GraphQL College, March 12. Accessed 2019-12-08.
  14. Meredith, Caleb. 2017. "Explaining GraphQL Connections." Apollo GraphQL Blog, on Medium, February 24. Accessed 2019-12-08.
  15. Neary, Adam. 2018. "Reconciling GraphQL and Thrift at Airbnb." Airbnb Engineering & Data Science, on Medium, May 29. Accessed 2019-12-08.
  16. Ploesser, Kay. 2019a. "Generating REST APIs from GraphQL Schemas, a Tutorial." Moesif Blog, January 30. Accessed 2019-12-08.
  17. Ploesser, Kay. 2019b. "Best Practices for Versioning REST and GraphQL APIs." Moesif Blog, March 21. Accessed 2019-12-08.
  18. Rehman, Faria. 2019. "Moving to GraphQL from SOAP or REST." Apimatic Blog, on Medium, July 12. Accessed 2019-12-08.
  19. Saring, Jonathan. 2019. "13 GraphQL Tools and Libraries You Should Know in 2019." Bits and Pieces, on Medium, May 28. Accessed 2019-12-08.
  20. Shopify Developers. 2019. "Migrating to GraphQL from REST." Help, Shopify Developers. Accessed 2019-12-08.
  21. Shtatnov, Artem, and Ravi Srinivas Ranganathan. 2018. "Our learnings from adopting GraphQL." The Netflix Tech Blog, on Medium, December 10. Accessed 2019-12-08.
  22. Stuart, Mark. 2018a. "GraphQL Resolvers: Best Practices." PayPal Engineering, on Medium, December 11. Accessed 2019-12-08.
  23. Stuart, Mark. 2018b. "GraphQL: A success story for PayPal Checkout." PayPal Engineering, on Medium, October 17. Accessed 2019-12-08.
  24. Tarvainen, Jani. 2016. "Versioning an API in GraphQL vs. REST." Symfony Finland, August 05. Accessed 2019-12-08.

Further Reading

  1. Wolthuis, Dirk. 2019. "From REST to GraphQL: A different way to create an API (with Apollo & Node.js)." Blog, Log Rocket, July 21. Accessed 2019-12-08.
  2. Burk, Nikolas. 2018. "How to wrap a REST API with GraphQL - A 3-step tutorial." Prisma, February 22. Accessed 2019-12-08.
  3. Shtatnov, Artem, and Ravi Srinivas Ranganathan. 2018. "Our learnings from adopting GraphQL." The Netflix Tech Blog, on Medium, December 10. Accessed 2019-12-08.
  4. Mráz, David. 2018. "GraphQL best practices for GraphQL schema design." Blog, GraphQL Mastery, October 30. Accessed 2019-12-08.
  5. Giroux, Marc-André. 2018. "GraphQL Schema Design: Building Evolvable Schemas." Apollo GraphQL Blog, on Medium, June 01. Accessed 2019-12-08.
  6. Kraeling, Brandon. 2019. "How to Think in GraphQL Coming From a REST Mindset." Differential, December 06. Accessed 2019-12-08.

Article Stats

Author-wise Stats for Article Edits

Author
No. of Edits
No. of Chats
DevCoins
2
0
1337
1
0
8
1705
Words
4
Likes
5849
Hits

Cite As

Devopedia. 2022. "REST API to GraphQL Migration." Version 3, February 15. Accessed 2023-11-13. https://devopedia.org/rest-api-to-graphql-migration
Contributed by
2 authors


Last updated on
2022-02-15 11:54:47