graphqlgraphql-jsgraphql-schema

How to create an alias for a GraphQLString type?


In some languages you can rename a basic type like string to something else:

type alias UUID = String

It's still a string type, but now you can reason better about the code. Because is not all the strings in the universe.. is just UUID shape of strings. And you can spot an error faster.

I tried to do the same in graphql, but it does not work:

function UUID (){
  return new GraphQLScalarType({
    name: 'UUID',
    serialize: uidAsString => { return uidAsString },
    parseValue:  uidAsString => { return uidAsString },
    parseLiteral(ast) {

      console.log(ast)                       // log below

      if (ast.kind === Kind.GraphQLString) {
        return ast.value;
      }
      return null;
    }
  });
}

Error is:

{
  "errors": [
    {
      "message": "Expected type UUID!, found \"what?\"; Kind is not defined",
      "locations": [
        {
          "line": 2,
          "column": 30
        }
      ]
    }
  ]
}

When console.log the ast i see this:

{
  kind: 'StringValue',
  value: 'what?',
  block: false,
  loc: { start: 41, end: 48 }
}

So what code should i have here? Im not fully understanding what im supposed to return .. and obviously ast.value is not correct.

Is it even possible to create aliases for basic types like string, int, other enums etc? Objects are already properly(specifically) named - i don't find myself needing to rename them too often.


Solution

  • First, the log looks correct to me. You need to differentiate between the AST value (it only has a few value types) and the type of the value. So in your case the AST value is string type and your scalar is supposed to only read strings, so all good!

    Second, I don't think that this line is correct: ast.kind === Kind.GraphQLString. It should be ast.kind === Kind.STRING from what I understand from the source code.

    Third, is there a reason you are putting the scalar into a function instead of simply assigning it to a variable? Scalars are usually referenced directly. Here you are creating new instances of the scalar all the time when you use UUID() in your code...

    const UUID = new GraphQLScalarType({
    

    You might also want to use more validation on the string level, otherwise I would simply suggest to use the built in ID scalar.