graphqlgraphql-js

How to declare strings in enum


With graphql, enum can make a predefined list of elements but strings don't work.

For example:

enum Dias {
  lunes
  martes
  miércoles
  jueves
  viernes
  sábado
  domingo
}

This returns an error GraphQLError: Syntax Error: Cannot parse the unexpected character "\u00E9".

how is it possible to make a predefined list of strings?


Edit: to give more context, I want to reflect the database schema, which is like this (with mongoose):

dias: {
  type: String,
  enum: ['lunes', 'martes', 'miércoles', 'jueves', 'viernes', 'sábado', 'domingo'],
  lowercase: true,
  required: true
}

Solution

  • Your syntax is correct, the only issue is that the "é" and "á" characters are not supported. The specification outlines rules for naming operations, fields, etc. The supported pattern is:

    /[_A-Za-z][_0-9A-Za-z]*/
    

    Furthermore:

    Names in GraphQL are limited to this ASCII subset of possible characters to support interoperation with as many other systems as possible.

    So, unfortunately, you will have to convert those accented characters to valid ones in order for your schema to be considered valid.

    EDIT: You could create a custom scalar. Here's a function that takes a name, description and an array and returns a custom scalar:

    const makeCustomEnumScalar = (name, description, validValues) => {
      const checkValue = (value) => {
        const coerced = String(value)
        if (!validValues.includes(coerced)) {
          throw new TypeError(`${coerced} is not a valid value for scalar ${name}`)
        }
        return coerced  
      }
      return new GraphQLScalarType({
        name,
        description,
        serialize: checkValue,
        parseValue: checkValue,
        parseLiteral: (ast) => checkValue(ast.value),
      })
    }
    

    Now you can do something like:

    const DayOfWeek = makeCustomEnumScalar('Day of Week', 'day of week enum', [
      'lunes',
      'martes',
      'miércoles',
      'jueves',
      'viernes',
      'sábado',
      'domingo'
    ])
    

    Add it to your resolvers:

    const resolvers = {
      DayOfWeek,
      // Query, Mutation, etc.
    }
    

    And your type definitions:

    scalar DayOfWeek
    

    And then you can use it like any other scalar. If an invalid value is provided as an input or output by a query, then GraphQL will throw an error like with an enum. The only caveat is that if you're entering the values directly into your query (as opposed to using variables), you'll still need to wrap them in double quotes.