Skip to content

anthonyroach/mercurius-validation

 
 

Repository files navigation

mercurius-validation

CI workflow

Mercurius Validation is a plugin for Mercurius that adds configurable validation support.

Features:

  • Supports JSON Schema.
  • Supports JTD.
  • Supports Custom Function validation on field arguments.
  • Supports validation through constraint directives in your schema. This plugin will apply JSON Schema validation policies based on the matching directives.
  • Provides SDL type definitions for the GraphQL directive.
  • Works in both normal and gateway mode.
  • In addition to the argument metadata and value, custom functions have access to the same GraphQL information that any GraphQL resolver has access to.
  • Define custom errors.
  • GraphQL spec compliant.

Docs

Install

npm i fastify mercurius mercurius-validation

Quick Start

Validation with JSON Schema definitions

You can setup mercurius-validation using a JSON Schema validation definition as follows:

'use strict'

const Fastify = require('fastify')
const mercurius = require('mercurius')
const mercuriusValidation = require('mercurius-validation')

const schema = `
  type Message {
    id: ID!
    text: String
  }

  input Filters {
    id: ID
    text: String
  }

  type Query {
    message(id: ID): Message
    messages(filters: Filters): [Message]
  }
`

const messages = [
  {
    id: 0,
    text: 'Some system message.'
  },
  {
    id: 1,
    text: 'Hello there'
  },
  {
    id: 2,
    text: 'Give me a place to stand, a lever long enough and a fulcrum. And I can move the Earth.'
  },
  {
    id: 3,
    text: ''
  }
]

const resolvers = {
  Query: {
    message: async (_, { id }) => {
      return messages.find(message => message.id === Number(id))
    },
    messages: async () => {
      return messages
    }
  }
}

const app = Fastify()

app.register(mercurius, {
  schema,
  resolvers
})

app.register(mercuriusValidation, {
  schema: {
    Filters: {
      text: { type: 'string', minLength: 1 }
    },
    Query: {
      message: {
        id: { type: 'string', minLength: 1 }
      }
    }
  }
})

app.listen(3000)

Validation with the GraphQL @constraint directive

You can setup mercurius-validation with the @constraint GraphQL directive. mercurius-validation provides the type definitions to include this directive definition within your GraphQL schema.

'use strict'

const Fastify = require('fastify')
const mercurius = require('mercurius')
const mercuriusValidation = require('mercurius-validation')

const schema = `
  ${mercuriusValidation.graphQLTypeDefs}

  type Message {
    id: ID!
    text: String
  }

  input Filters {
    id: ID
    text: String @constraint(minLength: 1)
  }

  type Query {
    message(id: ID @constraint(type: "string", minLength: 1)): Message
    messages(filters: Filters): [Message]
  }
`

const messages = [
  {
    id: 0,
    text: 'Some system message.'
  },
  {
    id: 1,
    text: 'Hello there'
  },
  {
    id: 2,
    text: 'Give me a place to stand, a lever long enough and a fulcrum. And I can move the Earth.'
  },
  {
    id: 3,
    text: ''
  }
]

const resolvers = {
  Query: {
    message: async (_, { id }) => {
      return messages.find(message => message.id === Number(id))
    },
    messages: async () => {
      return messages
    }
  }
}

const app = Fastify()
app.register(mercurius, {
  schema,
  resolvers
})
app.register(mercuriusValidation)

app.listen(3000)

Benchmarks

Normal GraphQL Server Mode | Without Validation

Last run: 2021-09-27

Running 10s test @ http://localhost:3000/graphql
100 connections

┌─────────┬──────┬──────┬───────┬───────┬─────────┬─────────┬───────┐
│ Stat    │ 2.5% │ 50%  │ 97.5% │ 99%   │ Avg     │ Stdev   │ Max   │
├─────────┼──────┼──────┼───────┼───────┼─────────┼─────────┼───────┤
│ Latency │ 4 ms │ 5 ms │ 8 ms  │ 14 ms │ 5.33 ms │ 2.28 ms │ 63 ms │
└─────────┴──────┴──────┴───────┴───────┴─────────┴─────────┴───────┘
┌───────────┬────────┬────────┬─────────┬─────────┬─────────┬─────────┬─────────┐
│ Stat      │ 1%     │ 2.5%   │ 50%     │ 97.5%   │ Avg     │ Stdev   │ Min     │
├───────────┼────────┼────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│ Req/Sec   │ 9831   │ 9831   │ 18111   │ 19023   │ 17069.1 │ 2470.46 │ 9827    │
├───────────┼────────┼────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│ Bytes/Sec │ 4.3 MB │ 4.3 MB │ 7.91 MB │ 8.31 MB │ 7.46 MB │ 1.08 MB │ 4.29 MB │
└───────────┴────────┴────────┴─────────┴─────────┴─────────┴─────────┴─────────┘

Req/Bytes counts sampled once per second.

188k requests in 11.03s, 82 MB read

Normal GraphQL Server Mode | With Validation

Last run: 2021-09-27

Running 10s test @ http://localhost:3000/graphql
100 connections

┌─────────┬──────┬──────┬───────┬───────┬─────────┬─────────┬───────┐
│ Stat    │ 2.5% │ 50%  │ 97.5% │ 99%   │ Avg     │ Stdev   │ Max   │
├─────────┼──────┼──────┼───────┼───────┼─────────┼─────────┼───────┤
│ Latency │ 4 ms │ 5 ms │ 8 ms  │ 15 ms │ 5.48 ms │ 2.07 ms │ 55 ms │
└─────────┴──────┴──────┴───────┴───────┴─────────┴─────────┴───────┘
┌───────────┬─────────┬─────────┬─────────┬─────────┬──────────┬─────────┬─────────┐
│ Stat      │ 1%      │ 2.5%    │ 50%     │ 97.5%   │ Avg      │ Stdev   │ Min     │
├───────────┼─────────┼─────────┼─────────┼─────────┼──────────┼─────────┼─────────┤
│ Req/Sec   │ 9399    │ 9399    │ 17215   │ 18943   │ 16704.73 │ 2427.11 │ 9398    │
├───────────┼─────────┼─────────┼─────────┼─────────┼──────────┼─────────┼─────────┤
│ Bytes/Sec │ 4.11 MB │ 4.11 MB │ 7.52 MB │ 8.27 MB │ 7.3 MB   │ 1.06 MB │ 4.11 MB │
└───────────┴─────────┴─────────┴─────────┴─────────┴──────────┴─────────┴─────────┘

Req/Bytes counts sampled once per second.

184k requests in 11.03s, 80.3 MB read

Gateway GraphQL Server Mode | Without Validation

Last run: 2021-09-27

Running 10s test @ http://localhost:3000/graphql
100 connections

┌─────────┬───────┬───────┬───────┬────────┬──────────┬──────────┬────────┐
│ Stat    │ 2.5%  │ 50%   │ 97.5% │ 99%    │ Avg      │ Stdev    │ Max    │
├─────────┼───────┼───────┼───────┼────────┼──────────┼──────────┼────────┤
│ Latency │ 32 ms │ 38 ms │ 71 ms │ 100 ms │ 40.55 ms │ 13.79 ms │ 237 ms │
└─────────┴───────┴───────┴───────┴────────┴──────────┴──────────┴────────┘
┌───────────┬────────┬────────┬────────┬────────┬─────────┬────────┬────────┐
│ Stat      │ 1%     │ 2.5%   │ 50%    │ 97.5%  │ Avg     │ Stdev  │ Min    │
├───────────┼────────┼────────┼────────┼────────┼─────────┼────────┼────────┤
│ Req/Sec   │ 1079   │ 1079   │ 2577   │ 2853   │ 2434.28 │ 493.75 │ 1079   │
├───────────┼────────┼────────┼────────┼────────┼─────────┼────────┼────────┤
│ Bytes/Sec │ 378 kB │ 378 kB │ 902 kB │ 998 kB │ 852 kB  │ 173 kB │ 378 kB │
└───────────┴────────┴────────┴────────┴────────┴─────────┴────────┴────────┘

Req/Bytes counts sampled once per second.

27k requests in 11.03s, 9.37 MB read

Gateway GraphQL Server Mode | With Validation

Last run: 2021-09-27

Running 10s test @ http://localhost:3000/graphql
100 connections

┌─────────┬───────┬───────┬───────┬────────┬──────────┬──────────┬────────┐
│ Stat    │ 2.5%  │ 50%   │ 97.5% │ 99%    │ Avg      │ Stdev    │ Max    │
├─────────┼───────┼───────┼───────┼────────┼──────────┼──────────┼────────┤
│ Latency │ 32 ms │ 35 ms │ 70 ms │ 103 ms │ 37.97 ms │ 13.33 ms │ 216 ms │
└─────────┴───────┴───────┴───────┴────────┴──────────┴──────────┴────────┘
┌───────────┬────────┬────────┬────────┬─────────┬────────┬────────┬────────┐
│ Stat      │ 1%     │ 2.5%   │ 50%    │ 97.5%   │ Avg    │ Stdev  │ Min    │
├───────────┼────────┼────────┼────────┼─────────┼────────┼────────┼────────┤
│ Req/Sec   │ 1153   │ 1153   │ 2711   │ 2969    │ 2597.4 │ 521.83 │ 1153   │
├───────────┼────────┼────────┼────────┼─────────┼────────┼────────┼────────┤
│ Bytes/Sec │ 404 kB │ 404 kB │ 949 kB │ 1.04 MB │ 909 kB │ 183 kB │ 404 kB │
└───────────┴────────┴────────┴────────┴─────────┴────────┴────────┴────────┘

Req/Bytes counts sampled once per second.

26k requests in 10.03s, 9.09 MB read

Examples

Check GitHub repo for more examples.

License

MIT

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • JavaScript 97.8%
  • TypeScript 1.7%
  • Shell 0.5%