Querying a Local GraphQL Microservice

Stop spinning up the whole world

Question: How can I work on just my microservice without also running a Gateway and all of the other related services?

Answer: Just like it works in Production

OK, so that’s a cheeky answer. In production, you have a Gateway, and you have all of the other services. What I mean by this is: your service doesn’t know any of that. It doesn’t know it’s part of a Gateway. It just knows how to respond to queries, just like every other GraphQL server. Let’s take this a step at a time, and I can show you what I mean:

Let’s assume the following super-simple Users service schema:

And you have another Movies service:

And now you want to add the user’s favorite movie.

Caveat: The favoriteMovie could be added in either service. In real life it would probably make more sense to be owned by the Movie Service, but that didn’t fit what I wanted to teach you as well, so this is what you get.

Step 1: Make Movie federable (federatable?):

We need to add a lookup key for Movie:

Step 2: Add the favoriteMovie to the user:

Here we add the user’s favorite movie, and we also stub out the Movie type.

Great! Now we can spin up the whole world (an Apollo Gateway, the Users service, and the Movies service) and test this thing out. You can make calls to the Gateway, and it proxies the whole thing and stitches it all together:

Now you will do this and this is how you will build stuff. The end.

Spun up the GraphQL World

OK. This is where my complaint is. This is what this article is about. The problem here is that you’re no longer thinking in microservices. You’re building and developing against a distributed monolith. Microservices are meant to work in isolation, and developing against a microservice means you should be developing against a contract, NOT against another service.

Who cares? This works

OK. Maybe it works today. Maybe you’ll never mind. But I can tell you that for most people, as the team gets bigger, you’re going to mind. One day someone is going to break the build. Someone is going to corrupt your Apollo Gateway server or one of your other services, and you’re going to be stuck, unable to work because you just finished a giant merge and you don’t want to go backward. Now you just wait.

There is a better way. docker-compose down and let’s try something. Trust me.

Start up your users service. If you’re actively building the users service, you should be able to use its API:

The only field you can ask for here on the Movie is the id, as that’s all you have. This is your contract, and it’s amazing to get to work against JUST your contract.

You’ve already tested that it all connects through the Gateway. You don’t need to keep doing that anymore. You’re working on the users service. The other fields “don’t exist” anymore.

Now shut down the users service and start up the movies service. Let’s query for one of those:

Great!

But wait, there’s more to your contract, yeah? You’re here because you need to test and make sure that your __resolveReference methods are working, and that everything will play nice, right? So back to my answer:

Well, what does production do? Your request comes in through Apollo Gateway, which makes makes a call to your users service:

And then it turns around with that user.favoriteMovie.id and makes the following call to your movies service:

with the following variables

So now you can just make those calls. “Just” call into your _entities and ask for the values you want.

The End

Node.js Architect and Web Developer. Lover of all good technologies (and some crappy ones), and sometimes I write about them.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store