Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Apollo-server 2 validation middleware

I want to add a validation layer to the apollo server. It should run after every graphql query / mutation but before the resolver function. The validation layer will need to know the graphql query / mutation being called and the passed parameters. It will throw an error if its invalid and prevent the resolver function from running.

I'm unclear where to inject it without manually placing it in each resolver function.

like image 740
SILENT Avatar asked Dec 18 '18 17:12

SILENT


Video Answer


1 Answers

graphql-tools actually includes a addSchemaLevelResolveFunction utility that allows you to wrap the resolver for every Query, Mutation and Subscription field to simulate a "root level resolver":

const { makeExecutableSchema, addSchemaLevelResolveFunction } = require('graphql-tools')

const schema = makeExecutableSchema({ resolvers, typeDefs })
const rootLevelResolver = (root, args, context, info) => {
  // Your validation logic here. Throwing an error will prevent the wrapped resolver from executing.
  // Note: whatever you return here will be passed as the parent value to the wrapped resolver
}
addSchemaLevelResolveFunction(schema, rootLevelResolver)

This is a simple way of applying some logic to all root-level fields, but gets a bit hairy if there's only some fields you want to apply this logic to. If that's the case, now you have to maintain a list of whitelisted or blacklisted fields, separate from your schema. This can be troublesome if someone else on your team is adding a new field and isn't aware of this mechanism. It's also not all-too-helpful if you want to apply the same logic to fields outside of root level ones.

A better approach is to utilize a custom schema directive, as outlined in the docs. This allows you to indicate which fields to apply the logic to:

directive @customValidation on FIELD_DEFINITION

type Query {
  someField: String @customValidation
  someOtherField: String
}
like image 51
Daniel Rearden Avatar answered Oct 06 '22 01:10

Daniel Rearden