'Using gRPC and/or GraphQL for microservice architecture

At my company we're about to set up a new microservice architecture, but we're still trying to decide which protocol would be best for our use case.

In our case we have some services that are called internally by other services, but are also exposed via a GraphQL API gateway towards our clients.

Option 1: gRPC

gRPC seems to be a popular choice for microservice internal communication because of its performance and efficiency.

However, gRPC makes it more difficult to query relational data and requires more work to hook up to our API gateway.

Option 2: GraphQL

Another option is for each microservice to implement their own GraphQL schema so they can be easily stitched together using Apollo Federation in the API gateway.

This approach will make queries more flexible, but internal requests become less performant because of the lack of protocol buffers.

Option 3: Both?

Perhaps another alternative is to use the best of both worlds by implementing mutations in gRPC and queries in GraphQL. Or just creating two APIs, one facing the gateway clients and one for communication between services.

Questions

  1. How do we decide which approach to use?
  2. Are there any significant (dis)advantages we should consider? E.g. in terms of ease of use, maintainability, scalability, performance, etc?
  3. Are there better alternatives for this use case?


Solution 1:[1]

It depends on the overall architecture you are implementing.

I would suggest to use both GraphQL and gRPC:

  • Use Apollo Federation as a border node to seamlessly handle the requests from your frontends talking in GraphQL.

  • Use CQRS pattern on your API and microservices, and strictly separate the read model from the write model.

  • Use hexagonal architecture (we use Explicit Architecture in my company) to implement DDD - Domain-driven-design.

  • In order to seamlessly integrate Apollo, you will have to implement GraphQL layer into the architecture of all of your backend services.

  • In read model, implement GraphQL layer. You will benefit from the federation (parallel reads of data from several microservices will be "joined" in federation engine without any participation of your API nodes).

  • For communication among your backend services in write model (mutations), use gRPC.

  • gRPC will make it possible to call your CQRS commands remotly like it was local.

  • So, your remote microservices will look like part of your local backend code.

  • You will also need a message-broker like RabbitMQ or Kafka to manage some more complex state changes via events and message queues.

Solution 2:[2]

I would suggest that you should go with gRPC for internal services communication as it is fast. Now comes what should you use for external communication, you may use REST or Graph QL. Graph QL is good option if different type of Client needs different amount of data otherwise REST will be easier to implement.

In one of my project, we have used the gRPC for internal communication (services are in Go language) & for external communication, we have used REST. Go have some packages which help to develop service expose using REST and internally communicating with other service using gRPC. So, in our scenario, it was working fine.

Solution 3:[3]

You dont have to use REST or graphQL at all. It just added layer. It can be achieve use grpc web and pull/push like pubsub. You can also do graphQL-like behavior using FieldMask

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 xs2tarunkukreja
Solution 3 Archmad