Skip to main content
For this example, we are using fastify and tsx to run a local server on port 4000. Before running any checks, we need to configure the check extension to point to our local server and set the secret key. For this example, we are using the following values:
  • Endpoint: http://localhost:4000/check-schema
  • Secret key: ...

Setting up the project

First, create a new directory for the project and navigate into it.
mkdir <project-name>
cd <project-name>
Once inside the project directory, initialize the project using your preferred package manager and install the required dependencies.
npm init -y
npm install --save-dev fastify tsx
Finally, create a script in the package.json file to run the project.
{
  ...
  "scripts": {
    "dev": "tsx watch server.ts"
  }
  ...
}

Handler implementation

The following example includes the handler implementation, a helper for validating the request signature, and type definitions for the payload and reply.
import Fastify, { type FastifyInstance } from 'fastify';

import { SubgraphCheckExtensionPayload, SubgraphCheckExtensionReply } from './types';
import { verifySignature } from './utils';

const YOUR_SECRET = '...';
const server: FastifyInstance = Fastify({ logger: true });

server.post<{
  Body: SubgraphCheckExtensionPayload,
  Reply: SubgraphCheckExtensionReply,
}>(
  '/check-schema',
  {
    config: { rawBody: true }
  },
  async (req, res) => {
    if (!req.body) {
      res.code(400);
      return { errorMessage: 'Bad request' };
    }

    const { body } = req;
    const cosmoSignature = req.headers['x-cosmo-signature-256'];
    if (!verifySignature(body, cosmoSignature, YOUR_SECRET)) {
      res.code(400);
      return { errorMessage: 'Bad request' };
    }

    // Run checks conditionally
    if (body.namespace.name !== 'default' || body.subgraph?.name !== 'family') {
      // Only overwrite lint issues for the `family` subgraph in the `default` namespace
      res.code(204);
      return;
    }

    return {
      lintIssues: [
        {
          lintRuleType: 'TYPE_SUFFIX',
          severity: 1,
          message: 'Type names should use the prefix `Type`',
          issueLocation: {
            line: 9,
            column: 6,
            endLine: 9,
            endColumn: 11,
          },
        },
      ],
    };
  },
);

const start = async () => {
  try {
    await server.listen({ port: 4000 })

    const address = server.server.address()
    const port = typeof address === 'string' ? address : address?.port
  } catch (err) {
    server.log.error(err)
    process.exit(1)
  }
};

start()