Advice on communication between gRPC microservices


(Zac Holland) #1

Edit:
I was struggling with how to ask this question, but here is a way shorter and more direct verision…
Should each client send requests to a single service, which then authenticates once and communicates with all the other services, or should the client send requests directly to each of the microservices who authenticate the requests themselves?

Hey all! I’m trying to create a microservice based application as an independent study but I’m having trouble designing it, specifically the communication. I won’t go into detail about what each service does because it’s mainly the communication and authentication I’m confused about.

The project is really simple right now. There is a gateway server where the user connects, and then authenticates their connection (by hitting an auth service). Now that the connection is authenticated they can make calls to a game server where they can perform actions. It’s pretty much just a little game; the game server makes calculations every 33 milliseconds (30fps) and the API let’s users make simple actions like moving characters or placing objects.

Here’s what it looks like:
Olam%20Arch%20Diagrams-AgentFlow

So here’s where I’m confused. What’s the best way to allow the gateway to get requests and communicate these actions to the other services?
Here are my thoughts…

Idea 1: Redirection
Each service will have it’s own gRPC API so they will have their own protobuf service. This means I can’t really have the gateway accept gRPC calls that are meant for a different service and have it just redirect them and return the result (to my knowledge). But is there a way to simply have calls go through the gateway to ensure authentication (both encryption and user identification) and then go to the right service?

Idea 2: Generic calls hit the gateway then the gateway handles the rest
I also thought about creating some generic format for gateway calls:
{ servicename, methodName, params... }
And then have the gateway interpret these and perform the correct calls to the service specified. Does this make more sense than redirecting messages?

I would love any advice as I’m just starting out developing services with Go and to this whole idea of microservices. :grin:


(Boban Acimovic) #2

(Zac Holland) #3

From my understanding that just helps create a RESTful json endpoint that translates to gRPC right?


(Boban Acimovic) #4

Don’t you need that? I think you can get nice ideas for your project by inspecting this repo.


(Tamás Gulácsi) #5

See https://www.nginx.com/blog/deploying-nginx-plus-as-an-api-gateway-part-3-publishing-grpc-services/
and https://www.envoyproxy.io/ - anything that can proxy HTTP/2 can proxy gRPC, too.

Authentication should be in HTTP headers, outside of the protocol buffers.


(Zac Holland) #6

I think I worded my question really poorly, I was still trying to understand exactly what I was asking myself.

Should each client send requests to a single service, which then authenticates once and communicates with all the other services, or should the client send requests directly to each of the microservices who authenticate the requests themselves?


(Tamás Gulácsi) #7

It depends.
An API gateway usually helps the clients, as all service is called through that gateway,
which can do the authentication, too.
Also it can provide some useful services to the upstream, too: registry, discovery, authentication, rate limiting and so on.
And the API gateway can provide such services by itself to the clients, too: list the registered services, with their .proto files, endpoints, rate limits …

The closest thing I’ve found is Ambassador (getambassador.io), but that’s just too heavyweight for me:
it needs Kubernetes and Envoy.
https://github.com/mwitkow/grpc-proxy is a gRPC proxy (library), but shows that such a high-level proxy is cumbersome: you have to go greate lengths to NOT know the underlying data types an proxy just the HTTP/2 bytes.

Which means that a HTTP/2 proxy with service registry would be the best, I think.


(Tamás Gulácsi) #8

Also, see https://grpc.io/blog/loadbalancing