node-graphql-constraint-lambda
GraphQL constraint directive written in functional programming style. This directive provides declarative validation of GraphQL arguments.
Install
yarn add node-graphql-constraint-lambda# or npm install node-graphql-constraint-lambda
Usage
Example GraphQL Schema:
type Query { createUser ( name: String! @constraint(minLength: 5, maxLength: 40) emailAddr: String @constraint(format: "email") otherEmailAddr: String @constraint(format: "email", differsFrom: "emailAddr") age: Int @constraint(min: 18) ): User}
Use the constraint from your code:
// when using es6 modules // when using commonjsconst constraint = // ... initialize your typeDefs and resolvers here ... const server = typeDefs resolvers schemaDirectives: constraint // ... additional graphql server config// ... start your server
You may need to declare the directive in the schema:
directive @constraint( minLength: Int maxLength: Int startsWith: String endsWith: String contains: String notContains: String pattern: String format: String differsFrom: String min: Float max: Float exclusiveMin: Float exclusiveMax: Float notEqual: Float) on ARGUMENT_DEFINITION
API
Available constraints
See stringValidators
, numericValidators
and formatValidator
mapping in src/validators.js.
Available formats
We use some functions from the validator
package.
See format2fun
mapping in src/validators.js.
Customization
Default behavoir
The following code shows how the constraint directive is configured with default behaviour:
// this code: // is equivalent to: const constraint =
Custom error messages
Error messages are generated using a callback function that by default shows a generic error message. It is possible to change this behavior by implementing a custom callback similar to this one:
const myErrorMessageCallback = `Error at field in constraint :, data=`
You might also want to customize certain messages and to keep the default callback as a fallback for all other messages:
const myErrorMessageCallback = { const argName cName cVal data = input if /* decide whether to show custom message */ return "custom error message" // based on input else return } const constraint =
Custom validation functions
Also the validation functions are implemented through a callback function. The constraint directive comes with a set of useful defaults but if you want to add your own validator, it can be done as follows:
// you can merge default validators with your own validatorconst myValidators = ...defaultValidators // your custom validator comes here true/false // Example: numerical pin codes of certain size `@constraint(pin:4)` === size && code const myValidationCallback = // now you can create the constraint classconst constraint =
There is a special format
validator that supports the following:
@constraint(format: "email")
@constraint(format: "base64")
@constraint(format: "date")
@constraint(format: "ipv4")
@constraint(format: "ipv6")
@constraint(format: "url")
@constraint(format: "uuid")
@constraint(format: "futuredate")
@constraint(format: "pastdate")
@constraint(format: "creditcard")
Let's say we want to extend it to support format: "uppercase"
format that checks whether all characters are just uppercase letters:
const customFormat2Fun = ...format2fun x // we could have omitted the `x` parameter due to currying in the // `match` function from ramda const validators = ... ...numericValidators ...stringValidators // now you can create the constraint classconst constraint =