GraphQL and Microservice Architecture

天大地大妈咪最大 提交于 2019-12-02 13:47:25

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.

See the article here, which says how and why approach #1 works better. Also look at the below image taken from the article I mentioned:

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/

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 :P

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.

As of mid 2019 the solution for the 1st Approach has now the name "Schema Federation" coined 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.

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 nether 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)

  • 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.

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=http://service1
            - URL_1=http://service2

As microservice architecture does not have a proper definition, there is no specific model for this style but, most of them will come with few notable characteristics.In case of microservices architecture, each service can be broken down into individual small components, which can be individually tweaked and deployed without affecting application integrity. This means you can simply change a few services without going for application redeployment through custom microservices app development.

More about microservices, I think GraphQL could work perfect in serverless architecture too. I don't use GraphQL but I have my own similar project. I use it as a aggregator which invoke and concentrates many functions into single result. I think you could apply same pattern for GraphQL.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!