Send request-id from Apollo Gateway to link logs
Tags: typescript, node, graphql, nestjs
Published: 2023-05-04 16:22:59

## Introduction

My work project uses Apollo Gateway (Federation). Currently, the API logs are output, but it is difficult to determine which GraphQL queries were executed within a single request.

In this case, I tried to improve it by using Apollo Gateway's RemoteGraphQLDataSource to add an ID to the request header so that it can be referenced from each application's GraphQL context.

![app-sturucture](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jylv1sigrghndz7qsgh7.png)

This article uses NestJS. Tool versions are below.

* Node.js v18.12.1
* Apollo Server v3.11.1
* NestJS v9.2.1
* yarn v1.22.19
* `@nestjs/cli` v9.1.5

## Setting up Gateway

First, set up request-id to send applications. Set header generated by Apollo Server context in `RemoteGraphQLDataSource.willSendRequest`.

```typescript
import { IntrospectAndCompose, RemoteGraphQLDataSource } from '@apollo/gateway';
import { ApolloGatewayDriver, ApolloGatewayDriverConfig } from '@nestjs/apollo';
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { v4 } from 'uuid';

@Module({
  imports: [
    GraphQLModule.forRoot<ApolloGatewayDriverConfig>({
      driver: ApolloGatewayDriver,
      server: {
        cors: true,
        context: () => {
          return { requestId: v4() };
        },
      },
      gateway: {
        supergraphSdl: new IntrospectAndCompose({
          subgraphs: [
            { name: 'posts', url: 'http://localhost:3001/graphql' },
            { name: 'users', url: 'http://localhost:3002/graphql' },
          ],
        }),
        buildService: ({ url }) =>
          new RemoteGraphQLDataSource<{ requestId: string }>({
            url,
            willSendRequest: ({ request, context }) => {
              request.http.headers.set('x-request-id', context.requestId);
            },
          }),
      },
    }),
  ],
})
export class AppModule {}
```

## Add request-id to the application's log

Next, implement ApolloServerPlugin to output the log. As shown in the figure, applications can obtain request-id from the GraphQL context.

```typescript
import { Plugin } from '@nestjs/apollo';
import { ExpressContext } from 'apollo-server-express';
import {
  ApolloServerPlugin,
  GraphQLRequestContext,
  GraphQLRequestListener,
} from 'apollo-server-plugin-base';

@Plugin()
export class LoggingPlugin implements ApolloServerPlugin {
  async requestDidStart(
    requestContext: GraphQLRequestContext<ExpressContext>
  ): Promise<GraphQLRequestListener<ExpressContext>> {
    return {
      willSendResponse: async ({ context }) => {
        const {
          request: { query, variables },
        } = requestContext;
        console.log({
          query,
          variables: JSON.stringify(variables),
          request_id: context.req.headers['x-request-id'],
        });
      },
    };
  }
}
```

## Output log to check request-id added

The rough setup is completed. If you want to run it, clone the repository below.

[https://github.com/choco14t/example-gateway-logging](https://github.com/choco14t/example-gateway-logging)

Run applications.

```bash
cd application-posts && yarn start
cd application-posts && yarn start
cd gateway && yarn start
```

Then run the query in [http://localhost:3000/graphql](http://localhost:3000/graphql).

```graphql
query QueryPosts {
  posts {
    id
    title
    user {
      id
      name
    }
  }
}
```

When executed, the following log should be output.


![post-app-log](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/us9f0qnanq2lxvau15j3.png)


![user-app-log](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/chh4osplwrw7m7nbah91.png)

Send the same request-id to applications. It sounds good!!

## Conclusion

This article showed how to improve logging using a gateway.

I hope this information will be helpful to those who are operating applications using Apollo Gateway or considering using Apollo Gateway.

## References

* [API Reference: @apollo/gateway - Apollo GraphQL Docs](https://www.apollographql.com/docs/apollo-server/using-federation/api/apollo-gateway)
* [packages/apollo-server-express/src/ApolloServer.ts#L48-L51](https://github.com/apollographql/apollo-server/blob/apollo-server-express%403.11.1/packages/apollo-server-express/src/ApolloServer.ts#L48-L51)

---

If you found this article helpful, please react to the article and follow me on Twitter!

[https://twitter.com/choco14t\_en](https://twitter.com/choco14t_en)