loading...
Cover image for Always test default parameters (Graphql, express)

Always test default parameters (Graphql, express)

crimsonmed profile image Médéric Burlet ・2 min read

Introduction

So I have been recently working on an app that uses the following:

Backend:

  • Graphql Yoga
  • Prisma2

Frontend:

  • apollo-graphql
  • apollo-boost
  • react

The problematic

The main issue I was encountering was all my data is based on the user that is logged in. This meant having the bearing token to check in the active connections which userID is the id of the person making the request.

Currently the platform has a list of active connections in the context generated by Graphql Server

{webtoken:  {userID, timestamp}

The issue that arose was that the bearer token passed by Apollo Boost is in the request headers per standard.

But when working with GraphQL Query we only have the variables passed and thus no idea hwo is making the request.

After searching high and low for how to get access to either:

  • Get access to request.headers from GraphQL Query
  • Add middleware to GraphQL Server to pass the request.headers as variable to the query

The solution

After tens and tens of testing and console.log I noticed this line:

const server = new GraphQLServer({ schema, context: createContext, })

In my create createContext I initialize a class which handles the prisma2 client, active connections and more:

export function createContext(): Context {
    return { prisma, connections: connectionContext }
}

I then decided to add the following:

export function createContext(req: any): Context {
    console.log(req)
    return { prisma, connections: connectionContext }
}

Turns out the default value passed to the context by GraphQL Server is the request payload.
This means we can do the following:

export function createContext(req: any): Context {
    // Check and set bearer token
    const bearerToken = req.request.headers.authorization || null
    return { prisma, bearer: bearerToken, connections: connectionContext, drive: driveContext }
}

This means in my GraphQL query I can get access to the context.bearer.

t.list.field('User', {
    type: 'User',
    resolve: (_parent, _args, ctx) => {
        return ctx.prisma.user.findMany({
            where: {userID = ctx.connections.getUserByToken(ctx.bearer)}
        })
    },
})

Discussion

pic
Editor guide