When and How to use GraphQL with microservice architecture

When and How to use GraphQL with microservice architecture

263

I’m trying to understand where GraphQL is most suitable to use within a microservice architecture.

There is some debate about having only 1 GraphQL schema that works as API Gateway proxying the request to the targeted microservices and coercing their response. Microservices still would use REST / Thrift protocol for communication though.

Another approach is instead to have multiple GraphQL schemas one per microservice. Having a smaller API Gateway server that route the request to the targeted microservice with all the information of the request + the GraphQL query.

1st Approach

Having 1 GraphQL Schema as an API Gateway will have a downside where every time you change your microservice contract input/output, we have to change the GraphQL Schema accordingly on the API Gateway Side.

2nd Approach

If using Multiple GraphQL Schema per microservices, make sense in a way because GraphQL enforces a schema definition, and the consumer will need to respect input/output given from the microservice.

Questions

  • Where do you find GraphQL the right fit for designing microservice architecture?
  • How would you design an API Gateway with a possible GraphQL implementation?
Share
Improve this question

1

  • Checkout this video

    – Kaveh Naseri

    Oct 8, 2021 at 15:32

9 Answers
9

Reset to default

336

+50

Definitely approach #1.

Having your clients talk to multiple GraphQL services (as in approach #2) entirely defeats the purpose of using GraphQL in the first place, which is to provide a schema over your entire application data to allow fetching it in a single roundtrip.

Having a shared nothing architecture might seem reasonable from the microservices perspective, but for your client-side code it is an absolute nightmare, because every time you change one of your microservices, you have to update all of your clients. You will definitely regret that.

GraphQL and microservices are a perfect fit, because GraphQL hides the fact that you have a microservice architecture from the clients. From a backend perspective, you want to split everything into microservices, but from a frontend perspective, you would like all your data to come from a single API. Using GraphQL is the best way I know of that lets you do both. It lets you split up your backend into microservices, while still providing a single API to all your application, and allowing joins across data from different services.

If you don’t want to use REST for your microservices, you can of course have each of them have its own GraphQL API, but you should still have an API gateway. The reason people use API gateways is to make it more manageable to call microservices from client applications, not because it fits well into the microservices pattern.

Share
Improve this answer

7

  • 4

    @helfer: This really make sense 🙂 thanks. I have few questions on top of this gorgeous answer. – You are saying that GraphQL has to be used as API gateway? – Let’s say i have an Order Microservice which expose Either a REST or GraphQL end point. Once i finished with it I have to update the main GraphQL schema to reflect the exactly the same data that the microservice will expose? Does it not sound duplication or moving away from microservice culture which should be independenty deployed? Any changes to a microservice has to be reflected / duplicated to the Main GraphQL Schema?

    – Fabrizio Fenoglio

    Jun 28, 2016 at 16:40


  • 24

    @Fabrizio the nice thing with GraphQL is that even if the backend REST API changes, the GraphQL schema can still stay the same, as long as there’s a way to get the data that the REST service previously exposed. If it exposes more data, then the canonical way to deal with this is to just add new fields/types to the existing schema. The folks at Facebook who created GraphQL told me they’ve never made a breaking change to their schema in four years. All the changes they made were additive, which means that new clients could use the new functionality, while old clients would continue to work.

    – helfer

    Jun 29, 2016 at 16:51

  • 4

    Right! 🙂 Thanks to write this up! I’m following you on Medium and on github through apollo repos! Your articles and posts are very valuable! 🙂 Keep up the good work! I also think that a medium article with topic GraphQL + Microservices will be very enjoyable to read!

    – Fabrizio Fenoglio

    Jun 30, 2016 at 8:28

  • 1

    Thanks, I’ll keep that in mind. Definitely planning to write about about GraphQL and Microservices at some point, but probably not in the next couple of weeks.

    – helfer

    Jul 6, 2016 at 0:53

  • How about the combination of option #2 and github.com/AEB-labs/graphql-weaver ?

    – Mohsen

    Dec 24, 2018 at 10:59

56

This article recommends approach #1. See the below image too, taken from the mentioned article:

When and How to use GraphQL with microservice architecture


One of the main benefits of having everything behind a single endpoint is that data can be routed more effectively than if each request had its own service. While this is the often touted value of GraphQL, a reduction in complexity and service creep, the resultant data structure also allows data ownership to be extremely well defined, and clearly delineated.

Another benefit of adopting GraphQL is the fact that you can fundamentally assert greater control over the data loading process. Because the process for data loaders goes into its own endpoint, you can either honor the request partially, fully, or with caveats, and thereby control in an extremely granular way how data is transferred.

The following article explains these two benefits along with others very well: https://nordicapis.com/7-unique-benefits-of-using-graphql-in-microservices/

Share
Improve this answer

4

  • 1

    HI, sorry for the noob questions, but isn’t your graphQL gateway a new retention point? Eg if I have a basket service that is suddenly over sollicited, would’nt my graphQL gateway break too? Basically I am not sure of its role, this gateway is supposed to contain a lot of resolvers for each service?

    – Eric Burel

    Oct 3, 2018 at 16:45

  • 1

    @EricBurel Thanks for the question. Actually, as far as I understood from the article, all the schema from different services are unified under one GraphQL schema, so as you mentioned, other services are still resides on their own datasets. Regarding possibility of single source of failure for graphQL gateway, there are always other options like providing a backup plan. Please read this article (labs.getninjas.com.br/…) for more information. Hope this helps.

    – Enayat

    Oct 3, 2018 at 17:09


  • How do you test the central API gateway and the individual services? Are you doing integration or mocking http response?

    – Jaime Sangcap

    Oct 4, 2019 at 16:00

  • @JaimeSangcap, in my experience integration tests are written against both: direct to the back-end to test complex workflows & edge cases as well as integration tests that hit the proxy to test common “API user journeys”.

    – benhorgen

    Jan 19, 2022 at 15:50

10

As of mid 2019 the solution for the 1st Approach has now the name “Schema Federationcoined by the Apollo people (Previously this was often referred to as GraphQL stitching).
They also propose the modules @apollo/federation and @apollo/gateway for this.

ADD: Please note that with Schema Federation you can’t modify the schema at the gateway level. So for every bit you need in your schema, you need to have a separate service.

Share
Improve this answer

2

  • it’s also valid to know that this solution demands Apollo Server which is slightly limited in free version (max 25 millions queries per month)

    – Marx

    Nov 29, 2019 at 20:59

  • Thanks for giving the name of approach

    – mbesson

    May 25, 2021 at 8:50

7

For approach #2, in fact that’s the way I choose, because it’s much easier than maintaining the annoying API gateway manually. With this way you can develop your services independently. Make life much easier 😛

There are some great tools to combine schemas into one, e.g. graphql-weaver and apollo’s graphql-tools, I’m using graphql-weaver, it’s easy to use and works great.

Share
Improve this answer

2

  • Using GraphQL in Android is imperative that I create a .graphql file with all the queries? Or can I just create them in the code without this file?

    – MauroAlexandro

    Jun 5, 2019 at 12:51

  • 1

    @MauroAlexandro I’m not an android guy, but you can have the queries in different files. It’s more a design problem. IMHO, I prefer the first one 🙂

    – HFX

    Jun 6, 2019 at 9:49

7

I have been working with GraphQL and microservices

Based on my experience what works for me is a combination of both approaches depending on the functionality/usage, I will never have a single gateway as in approach 1, but neither a GraphQL for each microservice as approach 2.

For example based on the image of the answer from Enayat, what I would do in this case is to have 3 graph gateways (Not 5 as in the image)

When and How to use GraphQL with microservice architecture


  • App (Product, Basket, Shipping, Inventory, needed/linked to other services)
  • Payment
  • User

This way you need to put extra attention to the design of the needed/linked minimal data exposed from the depending services, like an auth token, userid, paymentid, payment status

In my experience for example, I have the “User” gateway, in that GraphQL I have the user queries/mutations, login, sign in, sign out, change password, recover email, confirm email, delete account, edit profile, upload picture, etc… this graph on it own is quite large!, it is separated because at the end the other services/gateways only cares about the resulting info like userid, name or token.

This way is easier to…

  • Scale/shutdown the different gateways nodes depending on they usage. (for example people might not always be editing their profile or paying… but searching products might be used more frequently).
  • Once a gateways matures, grows, usage is known or you have more expertise on the domain you can identify which are the part of the schema that could have they own gateway (… happened to me with a huge schema that interacts with git repositories, I separated the gateway that interact with a repository and I saw that the only input needed/linked info was… the folder path and expected branch)
  • The history of you repositories is more clear and you can have a repository/developer/team dedicated to a gateway and its involved microservices.

UPDATE:

I have a kubernetes cluster online that is using the same approach that I describe here with all the backends using GraphQL, all opensource, here is the main repository:
https://github.com/vicjicaman/microservice-realm

This is an update to my answer because I think that it is better if the answer/approach is backed up code that is running and can be consulted/reviewed, I hope that this helps.

UPDATE 2:

Just adding another example of the functionalities separation, I separated into a graph the functionality related to manage files, upload, create, delete, group files into buckets, bulk delete, private files, cors config etc… while the other graphs/services only need a few details like a pre-signed post or the resulting url/fileid

Share
Improve this answer

    3

    To question 1, Intuit acknowledged the power of GraphQL few years back when it announced moving to One Intuit API ecosystem (https://www.slideshare.net/IntuitDeveloper/building-the-next-generation-of-quickbooks-app-integrations-quickbooks-connect-2017). Intuit chose to go with approach 1. The drawback that you mention actually prevents developers from introducing breaking schema changes that could potentially disrupt client applications.

    GraphQL has helped improve productivity of developers in a number of ways.

    1. When designing a new microservice for a domain, engineers (backend/ frontend/ stakeholders) agree on a schema for the domain entities. Once the schema is approved, it is merged with the master domain schema (universal) and deployed on the Gateway.Front end engineers can start coding client applications with this schema while backend engineers implement the functionality. Having one universal schema means that there are no two microservices with redundant functionality.
    2. GraphQL has helped client applications become simpler and faster. Want to retrieve data from /update data to multiple microservices? All client applications have to do is fire ONE GraphQL request and the API Gateway abstraction layer will take care to fetch and collate data from multiple sources (microservices). Open source frameworks like Apollo (https://www.apollographql.com/) have accelerated the pace of GraphQL adoption.
    3. With mobile being the first choice for modern applications, it is important to design for lower data bandwidth requirements from ground zero. GraphQL helps by allowing client apps to request for specific fields only.

    To question 2: We built a custom abstraction layer at the API Gateway that knows which part of the schema is owned by which service (provider). When a query request arrives, the abstraction layer forwards the request to the appropriate service(s). Once the underlying service returns the response, the abstraction layer is responsible to return the requested fields.

    However, today there are several platforms out there (Apollo server, graphql-yoga, etc.) that allow one to build a GraphQL abstraction layer in no time.

    Share
    Improve this answer

      0

      As of 2019 the best way is to write microservises that implements apollo gateway specification and then glue together these services using a gateway following approach #1.
      The fastest way to build the gateway is a docker image like this one
      Then use docker-compose to start all the services concurrently:

      version: '3'
      
      services:
          service1:
              build: service1
          service2:
              build: service2
          gateway:
              ports:
                  - 80:80
              image: xmorse/apollo-federation-gateway
              environment: 
                  - CACHE_MAX_AGE=5
                  - "FORWARD_HEADERS=Authorization, X-Custom-Header" # default is Authorization, pass '' to reset
                  - URL_0=https://service1
                  - URL_1=https://service2
      

      Share
      Improve this answer

        0

        The way it is being described in this question, I believe that using a custom API gateway as an orchestration service can make a lot of sense for complex enterprise focused applications. GraphQL can be a good technology choice for that orchestration service, at least as far as querying goes. The advantage to your first approach (one schema for all microservices) is the ability to stitch together the data from multiple microservices in a single request. That may, or may not, be very important depending on your situation. If the GUI calls for rendering data from multiple microservices all at once, then this approach can simplify the client code such that a single call can return data that is suitable for data binding with the GUI elements of such frameworks as Angular or React. This advantage doesn’t apply for mutations.

        The disadvantage is tight coupling between the data APIs and the orchestration service. Releases can no longer be atomic. If you refrain from introducing backwards breaking changes in your data APIs, then this can introduce complexity only when rolling back a release. For example, if you are about to release new versions of two data APIs with the corresponding changes in the orchestration service and you need to roll one of those releases back but not the other, then you will be forced to roll back all three anyway.

        In this comparison of GraphQL vs REST you will find that GraphQL is not quite as efficient as RESTful APIs so I would not recommend replacing REST with GraphQL for the data APIs.

        Share
        Improve this answer

          0

          We also had similar concerns on the bootstraping a Microservices ecosystem with graphql. And we are able to solve it with Apollo GraphQL.

          We built these solutions from scratch for our One Platform. Folders ending with service are microservices others are SPAs aka (Single Page Applications)

          This consists of various microservices and spas with an API Gateway which is the primary interface for multiple microservices.

          Along with this you can find a OP CLI generator which can help to bootstrap a microservice from scratch.

          Project – https://github.com/1-Platform/one-platform

          I request to please have a look on this project and feel free to adopt if this looks good to you.

          Regards

          Rigin Oommen

          Share
          Improve this answer

            Not the answer you’re looking for? Browse other questions tagged

            or ask your own question.

            Leave a Reply

            Your email address will not be published. Required fields are marked *