Going Beneath the GraphQL Federated API

Written by susamn | Published 2022/11/28
Tech Story Tags: graphql | web-development | rest-api | api | coding | debugging | networking | tracing | web-monetization

TLDRI am fascinated to work with GraphQL federated API. Recently, I was building a code generation framework that can generate actual compilable and deployable code in Java and connect automatically through GraphQL Federation API. In this post, I will discuss what goes into the life cycle of a federated GraphQL API. We will take a very simple Federated graphQL API built with NodeJS and intercept its traffic with HTTP Toolkit. The project is hosted at:https://github.com/susamn/gateway?embedable=true(https://www.hackernoon.com)via the TL;DR App

I am fascinated to work with GraphQL federated API. Recently, I was building a code generation framework that can generate actual compilable and deployable code in Java and connect automatically through GraphQL Federation API.

For this to shine, I needed to have a profound understanding of how GrahQL works and what is going underneath.

In this post, I will discuss what goes into the life cycle of a federated GraphQL API. We will take a very simple Federated GraphQL API built with NodeJS and intercept its traffic with HTTP Toolkit.

You can follow along with me at every step and I promise the result will be delicious. We will get to know how Gateway queries all the attached services.

The project is hosted at:

https://github.com/susamn/gateway?embedable=true


In a Federated GraphQL service, the responsibility of the gateway is to

  1. Consolidate all the component GraphQL service schema structures.

  2. Validate all the services by doing a query and making sure the graphql API exposed by all the component services is properly federated.

  3. When the call comes to the gateway understand that query and decide what query to be made to all the intended services

  4. Do the queries parallel y to all the relevant services and wait for the response

  5. Obtain the responses and consolidate them and send them to the caller, also add respective errors if any error has been sent any error.

Here we have 2 federated services.

Service 1: Employee Service

https://gist.github.com/susamn/2a9ac5a98f3d605b9388fcc1c956d925#file-employee-graphql?embedable=true

Service 2: Address Service

https://gist.github.com/susamn/9c424b2967626b17010674930fd9bcac#file-address-graphql?embedable=true

The Address type is extending the Employee type and provides address data for each employee.

And here is my Gateway.

https://gist.github.com/susamn/ae1457213017942153829dde3f8f87f0#file-gateway-js?embedable=true

The code is ready and when running this:

npm run server

we get our gateway server ready

Let’s go to http://localhost:4001 and verify our server is ready by executing a query.

Yep, it is running for sure and we can get address data for each employee. Let’s shut it down and debug the process.

Let’s start HTTP Toolkit and select Fresh Terminal.

and run the same command to run the service in the freshly opened terminal so that HTTP Toolkit can intercept the traffic and we can know what it going on.

Let’s see what is happening.

The first query made by the gateway to the Address and Employee services are the same and it is like below:

{"query": "query __ApolloGetServiceDefinition__ { _service{sdl} }"}

This is a gateway verifying the services by validating the schema of the services.

The Employee service responds:

https://gist.github.com/susamn/88bae9a650ce35a10596730457b36650#file-employee_definition-graphql?embedable=true

And the Address service responds:

https://gist.github.com/susamn/1fc361ce93910c258e611e720c038ee7#file-address_definition-graphql?embedable=true

After verifying the schema structures, the gateway is ready to accept incoming calls. Let’s debug that too.

Here is our query:

{
  employeeData(id:332233){
    employeeId
    address{
      addressId
    }
  }
}

  • The employee ID will come from Employee service.
  • The address ID will come from Address service.

As expected, we are seeing 2 calls made from the gateway to the service.

The first call to Employee service.

https://gist.github.com/susamn/5c8cdd4302735e27317632d273b16c89#file-employee_request-graphql?embedable=true

and the call to Address service.

https://gist.github.com/susamn/e147931dcb6ba348dbf67561835463d7#file-address_request-graphql?embedable=true

Observe here a couple of things.

  1. The first call to the Employee is self-explanatory, it’s a simple call.
  2. The second call to Address is a fragment on Employee. The fragment selection is only the data needed from the Address, i.e. the addressId. The data is passed in the variable section and only the employeeId is provided as the Address service only needs this.
  3. The Address data uses the data passed to it and uses its resolver to get the address of the employee.
  4. The direction matters here. As the Address is dependent on Employee and direction is from Employee → Address, the gateway sends a fragment to the Address service to be resolved.

Now the responses.

Employee service response to Gateway

https://gist.github.com/susamn/59078056793fbbb69b7f004e907db8bc#file-employee_response-graphql?embedable=true

Address service response to Gateway

https://gist.github.com/susamn/c459c51d24bc8486604c8be63231a591#file-address_response-graphql?embedable=true


Gateway finally consolidates and sends the response as :

https://gist.github.com/susamn/f0b953abc4caf076453b100720fd837a#file-gateway_response-graphql?embedable=true

That’s it, this concludes our journey.

A couple of things to keep in mind while developing GraphQL Federated API

  • After the service is built and hosted, manually do an HTTP GET call using the SDL query,
    {“query”: “query ApolloGetServiceDefinition { _service{sdl} }”}
  • See the schema properly, it’s very easy to make mistakes, and all of a sudden, the federation is unsuccessful.
  • The call to all the services should be parallel and independent. Take care of that.
  • If an error happens, return them judiciously so that the client is aware of them.

I hope you liked the journey. See you soon.

Originally published here.


Written by susamn | I am a daddy, a coder, a tech blogger, a music lover, a photographer, and an all in all nerd.
Published by HackerNoon on 2022/11/28