GraphQL and form validation errors

With validation logic inside the resolve method, you have complete control over the generated user errors. Here is an example:

// data/mutations/createUser.js
import {
  GraphQLObjectType as ObjectType,
  GraphQLNonNull as NonNull,
  GraphQLList as List,
  GraphQLString as StringType
} from 'graphql';
import validator from 'validator';
import UserType from '../types/UserType';

export default {
  type: new ObjectType({
    name: 'CreateUserResult',
    fields: {
      user: { type: UserType },
      errors: { type: new NonNull(new List(StringType)) }
    }
  }),
  args: {
    email: { type: new NonNull(StringType) },
    password: { type: new NonNull(StringType) }
  },
  resolve(_, { email, password }) {
    let user = null;
    let errors = [];

    if (validator.isNull(email)) {
      errors.push(...['email', 'The email filed must not be empty.']);
    } else if (!validator.isLength(email, { max: 100})) {
      errors.push(...['email', 'The email must be at a max 100 characters long.']);
    }

    // etc.

    return { user, errors };
  }
};

See my blog post on this subject - Validation and User Errors in GraphQL Mutations

Alternatively, create type UserErrorType { key: String!, message: String! } that can be used instead of plain strings when you compile the list of user errors to be returned to the caller.

GraphQL Query

mutation {
  createUser(email: "[email protected]", password: "Passw0rd") {
    user { id, email },
    errors { key, message }
  }
}

Query Response

{
  data: {
    user: null,
    errors: [
      { key: '', message: 'Failed to create a new user account.' },
      { key: 'email', message: 'User with this email already exists.' }
    ]
  }
}

I have created an npm module for handling validations in GraphQL in a better way. Please check the validate-graphql npm package.