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.
- Install
- Quick Start
- Examples
- Benchmarks
- API
- Registration
- JSON Schema Validation
- JTD Validation
- Function Validation
- Directive Validation
npm i fastify mercurius mercurius-validation
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)
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)
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
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
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
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
Check GitHub repo for more examples.
MIT