Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use the names in a GraphQLEnumType as the defaultValue of a GraphQL query argument?

When defining a query in a schema, how do I refer to a value of an GraphQLEnumType declared previously, to use it as the default value of an argument?

Let's say I've defined following ObservationPeriod GraphQLEnumType:

observationPeriodEnum = new GraphQLEnumType {
  name: "ObservationPeriod"
  description: "One of the performance metrics observation periods"
  values:
    Daily:
      value: '1D'
      description: "Daily"
    […]
}

and use it as the type of query argument period:

queryRootType = new GraphQLObjectType {
  name: "QueryRoot"
  description: "Query entry points to the DWH."
  fields:
    performance:
      type: performanceType
      description: "Given a portfolio EID, an observation period (defaults to YTD)
                    and as-of date, as well as the source performance engine,
                    return the matching performance metrics."
      args:
        period:
          type: observationPeriodEnum 
          defaultValue: observationPeriodEnum.Daily ← how to achieve this?
      […]
}

Currently I'm using the actual '1D' string value as the default value; this works:

        period:
          type: observationPeriodEnum 
          defaultValue: '1D'

But is there a way I could use the Daily symbolic name instead? I couldn't find a way to use the names within the schema itself. Is there something I overlooked?

I'm asking, because I was expecting an enum type to behave as a set of constants also, and to be able to use them like this in the schema definition:

        period:
          type: observationPeriodEnum 
          defaultValue: observationPeriodEnum.Daily

Naïve workaround:

##
# Given a GraphQLEnumType instance, this macro function injects the names 
# of its enum values as keys the instance itself and returns the modified
# GraphQLEnumType instance.
#
modifiedWithNameKeys = (enumType) ->
  for ev in enumType.getValues()
    unless enumType[ ev.name]?
      enumType[ ev.name] = ev.value
    else
      console.warn "SCHEMA> Enum name #{ev.name} conflicts with key of same
        name on GraphQLEnumType object; it won't be injected for value lookup"
  enumType

observationPeriodEnum = modifiedWithNameKeys new GraphQLEnumType {
  name: "description: "Daily""
  values:
    […]

which allows to use it as desired in schema definition:

        period:
          type: observationPeriodEnum 
          defaultValue: observationPeriodEnum.Daily

Of course, this modifier fullfils its promise, only as long as the enum names do not interfere with GraphQLEnumType existing method and variable names (which are currently: name, description, _values, _enumConfig, _valueLookup, _nameLookup, getValues, serialize, parseValue, _getValueLookup, _getNameLookup and toString — see definition of GraphQLEnumType class around line 687 in https://github.com/graphql/graphql-js/blob/master/src/type/definition.js#L687)

like image 926
olange Avatar asked Apr 16 '16 16:04

olange


People also ask

How do you pass multiple arguments in GraphQL query?

Multiple arguments can be used together in the same query. For example, you can use the where argument to filter the results and then use the order_by argument to sort them.

What is the name of Grapql includes reusable units in queries and mutations?

A GraphQL fragment lets you build multiple fields, and include them in multiple queries. You can think of it as functions in programming languages, that are reusable units. A GraphQL Fragment is a reusable unit of a GraphQL query, which creates a shared piece of query logic.


1 Answers

I just ran into this. My enum:

const contributorArgs = Object.assign(
  {},
  connectionArgs, {
    sort: {
      type: new GraphQLEnumType({
        name: 'ContributorSort',
        values: {
          top: { value: 0 },
        },
      })
    },
  }
);

In my queries, I was doing:

... on Topic {
  id
  contributors(first: 10, sort: 'top') {
    ...
  }
}

Turns out you just don't quote the value (which after thinking about it makes sense; it's a value in the enum type, not an actual value:

... on Topic {
  id
  contributors(first: 10, sort: top) {
    ...
  }
}
like image 124
Matthew Herbst Avatar answered Oct 26 '22 10:10

Matthew Herbst