Validations
Validations are a powerful feature that keep the DocumentStore in check and maintain consistency after every transaction. They flexibly describe and define the set of rules to which the Document Store must conform to.
The default rules provided by the library enforce sensible defaults (see Provided and Default Validators section) for GraphQL and connections between documents. If there are particular restrictions to your GraphQL API and its data then adding custom validators can be a great way to enforce these rules (see the Creating Custom Validator sections).
Validations are provided by Validators which come in two flavors Document Validators and Field Validators. Which combination of validators are used can be specified, along with custom validators, too.
The validators are located on a Paper instance under the validators property:
paper.validators = {
document: [],
field: [],
}
where the document property contains an array of Document Validators and the field property contains an array of Field validators. See the next section for the defaults the are provided for each.
Provided and Default Validators
documentPropertyExistsAsFieldOnTypeValidator
- Type: Document Validator
- Included by default
Enforces that any property that exists on a document also exists on the GraphQL type
listFieldValidator
- Type: Field Validator
- Included by default
Enforces that lists are represented by arrays or connections to other documents
nonNullFieldValidator
- Type: Field Validator
- Note included by default
Enforces that non-fields are not null. This is a stricter validator and is not included by default because there are cases where non-null fields may represent derived/computed data and may not be represented by data stored on the document.
objectFieldValidator
- Type: Field Validator
- Included by default
Enforces that a field represented by an object is an object if it's not represented by connection(s).
scalarFieldValidator
- Type: Field Validator
- Included by default
Enforces that a field represented by a scalar is a scalar.
uniqueIdFieldValidator
- Type: Field
- Included by default
Enforces that a type with one ID field is unique amongst other documents of the same type.
Removing a Default Validator
Validators are functions that exist on the Paper instance under the validators.document or validators.field arrays for Document Validators or Field Validators, respectively. To remove a validator from an instance set the array to a new array with the validators excluded.
In this example uniqueIdFieldValidator and documentPropertyExistsAsFieldOnTypeValidator are filtered out from being used by the instance of Paper.
import {
uniqueIdFieldValidator,
documentPropertyExistsAsFieldOnTypeValidator
} from 'graphql-paper/validations';
const excludedValidators = [
uniqueIdFieldValidator,
documentPropertyExistsAsFieldOnTypeValidator
];
paper.validators.document = paper.validators.document.filter(
validator => !excludedValidators.includes(validator)
);
paper.validators.field = paper.validators.field.filter(
validator => !excludedValidators.includes(validator)
);
Creating Custom Document Validators
A Document Validator enforces validation at the document-level, for the field-level use a Field Validator (see below). Document Validators implement the DocumentTypeValidator interface with an object that has validate function/method. If anything is found on the Document that is invalid the the validate method should thrown an Error or a class that extends Error.
{
function validate({
type: GraphQLObjectType<any>,
document: Document,
graphqlSchema: GraphQLSchema,
store: DocumentStore
})
}
Available within validate:
documentrepresents the document being validatedtyperepresents theGraphQLTypeof the document being validatedgraphqlSchemais an instance of theGraphQLSchemastoreis read-only version of theDocumentStore
Creating Custom Field Validators
Field Validators that implement the FieldValidator interface with an object that has validate function/method and the skipConnectionValue, skipNullValue properties. If anything is found on the Document that is invalid the the validate method should thrown an Error or a class that extends Error. See the section below on Adding a Custom Validator Function. See the section below on Adding a Custom Validator Function.
{
skipConnectionValue: boolean;
skipNullValue: boolean;
function validate({
graphqlSchema: GraphQLSchema,
type: GraphQLObjectType,
field: GraphQLField,
document: Document,
fieldName: string,
fieldValue: any,
fieldConnections: DocumentKey[] | undefined,
store: DocumentStore
})
}
skipConnectionValueskips validation when the field is represented by a connected value on the documentskipNullValueskips validation when the field is represented by a null or undefined value on the document
Available within validate:
documentrepresents the document being validatedtyperepresents theGraphQLTypeof the document being validatedfieldrepresents theGraphQLFieldof the document property being validatedfieldNamerepresents a string for the property on the document (and the field on the GraphQL type)graphqlSchemais an instance of theGraphQLSchemafieldValuerepresents the value of the field (keep in mind that the field might be have connections to other documents underfieldConnectionsin which case those would be the representative value when the property is accessed)storeis read-only version of theDocumentStorefieldConnectionsis an array of document keys orundefinedif none exist (in which casefieldValueis the representative value when the property is accessed)
Adding a Custom Validator Function to Paper
To add a custom validator function to an instance of Paper import the function and push it on to the corresponding document or field array depending on if it's a Document Validator or Field Validator, respectively.
import { customFieldValidator, customDocumentValidator } from './custom-validators';
paper.validators.field.push(customFieldValidator);
paper.validators.document.push(customDocumentValidator);