One of the technologies that has caught my eye in recent days is GraphQL. Additionally, I’ve been doing a lot of work with Go and gRPC at work, so I was curious if there was a way that these technologies could play nicely with one another. Then, it hit me. GraphQL fits really nicely into a service-oriented architecture (SoAs). Before we talk about the role GraphQL plays, let’s get some background on building out SoAs first.
gRPC & Service-Oriented Architectures
gRPC is an RPC framework extended from Protocol Buffers that is used for service-to-service communication. gRPC is quite useful for building out services with a specific role and allows you to generate client libraries in any language that can then be imported into another codebase in order to talk with that service. It takes out the need to memorize every URL path for an API, as all the calls are just functions. Now the question is, how do we get that information from the gRPC services to the front-end? This is where an API Gateway comes into play.
API Gateways
So, you have all of these separate services, right? Some of them have their own databases and their own data, but generally if you need more information from that service in your codebase, you can call that necessary service as needed through it’s gRPC client. But the question is, how does the front-end present things from these services? Enter the API Gateway. Microsoft has a really good reading on this specific concept, but the general idea is, rather than creating a separate JSON API service for each internal service that you have, you have a single gateway service that can route requests to the relevant service. See this diagram that I drew as reference.
But Microsoft also has a really good diagram that I think gives a more real-world view of things.
So looking at these diagrams, let’s say that the gateway is normally implemented as a JSON API. And then that JSON API just calls each relevant gRPC service as necessary. Then it can be converted back to the relevant JSON response for the consumer. But when working in complicated architectures, this can easily get messy in itself. For example, imagine the cart service is called by the checkout service. There’s two ways one could display this information. There can be two separate API calls by the client to get the cart information and show it in the checkout page. Or, the checkout page can call the cart service internally and return that back to the gateway, but that seems kind of messy to do every single time. So how do we fix this? Well, this is where GraphQL comes into play.
GraphQL as the API Gateway
The beauty of GraphQL is that the queries are made for getting the exact data that the client needs. Thinking about this from a microservices perspective, this is kind of cool right? If a GraphQL server becomes the API Gateway to our various services, it then can call these services as necessary to resolve the data the front-end needs. Most GraphQL client libraries can handle this automatically, of course with other features such as batching and subscriptions as well. Amazing, right? Additionally, another benefit of GraphQL is that its schemas serve as a really good means of enforcing the contracts of our various API services and the information that we need from them. It’s a blessing in disguise, to be honest.
So why (or why not) Go?
I think Go is nice in this sense because it feels nice to work with in a mono-repo context. Plus, it has static typing. And lastly, I’m just pretty fond of it. The beauty of gRPC’s language-agnosticism is that your API gateway doesn’t necessarily have to be written in Go. You could use apollo-server as the API gateway and just call the services from the resolver functions if you really wanted to do so. But I do think that Go has some niceties (such as working with contexts) that are nice to haves. But on the other hand, other tooling for GraphQL stuff is definitely Node.js-focused, so it also is understandable why that you’d use Node for the GraphQL server. Use whatever works best for your needs.
Less talk, more code
Okay, so you’re probably like, “Iheanyi, I don’t care about all of this thinking you’ve put into it, show me how I can utilize it.” Here’s an old repo that shows the underlying concepts about what I’m talking about. I want to come back to this with a more nuanced example, but for now, I think this will do. Feel free to hit me up if you have any questions though, I’m happy to answer them!