DEV Community

Harshit Kumar
Harshit Kumar

Posted on • Edited on • Originally published at harshitkumar.co.in

3 2

Creating a Proxy for your GraphQL Server

I needed to create a proxy server for my GraphQL service to be able to make some decisions before reaching my service.

This article will document how you can do the same with minimal amount of code 😏
We'll be leveraging awesome utilities provided by graphql-tools

Installation

npm init -y
npm i @graphql-tools/delegate @graphql-tools/utils @graphql-tools/wrap apollo-server cross-undici-fetch graphql typescript
Enter fullscreen mode Exit fullscreen mode

Create an executor

Executor is a function used capable of retrieving GraphQL results (both introspection & fetching results during a query's execution).

In the executor, I've defined the GraphQL service's URL which I want to proxy - https://graphql.anilist.co/ (an open API to fetch your favourite Anime characters)

const executor =  async ({ document , variables, context }: {document: any, variables: any, context: any}) => {
    const query = print(document)
  const fetchResult = await fetch('https://graphql.anilist.co/', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      ...context?.headers
    },
    body: JSON.stringify({ query, variables })
  })
  return fetchResult.json()
}
Enter fullscreen mode Exit fullscreen mode

Define applicationProxyResolver

This function is passed to wrapSchema method. In this method, you should be able to make some decisions. For example - I wanted to validate some headers & only honour the requests if they had these headers. We'll use delegateToSchema to delegate the entire request to our original GraphQL service.

export const applicationProxyResolver = ({
    subschemaConfig,
    operation,
    transformedSchema,
}: {
    subschemaConfig: any,
    operation: any,
    transformedSchema: any,
}) => {
    return (_parent: any, _args: any, context: any, info: any) => {
        return delegate.delegateToSchema({
            schema: subschemaConfig,
            operation,
            operationName: info!.operation!.name!.value,
            context,
            info,
            transformedSchema,
        });
    };
}
Enter fullscreen mode Exit fullscreen mode

Let's fire up the graphQL proxy server 🚀

const init = async () => {
    const schema = wrapSchema({
        schema: await introspectSchema(executor),
        executor,
        createProxyingResolver: applicationProxyResolver
    });

    const server = new ApolloServer({ 
        schema,
    });

    // The `listen` method launches a web server.
    server.listen(4001).then(({ url }) => {
        console.log(`🚀  Server ready at ${url}`);
    });

}

init();
Enter fullscreen mode Exit fullscreen mode

Proxy

You can find this code at Github.

Is there an easier way to do this? Please comment & let me know 😁

Image of Datadog

How to Diagram Your Cloud Architecture

Cloud architecture diagrams provide critical visibility into the resources in your environment and how they’re connected. In our latest eBook, AWS Solution Architects Jason Mimick and James Wenzel walk through best practices on how to build effective and professional diagrams.

Download the Free eBook

Top comments (0)

nextjs tutorial video

Youtube Tutorial Series 📺

So you built a Next.js app, but you need a clear view of the entire operation flow to be able to identify performance bottlenecks before you launch. But how do you get started? Get the essentials on tracing for Next.js from @nikolovlazar in this video series 👀

Watch the Youtube series

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay