4
votes

Les types d'énumérations GraphQL résolvent-ils leurs valeurs automatiquement?

Dois-je m'attendre à ce que les types enum se résolvent automatiquement ou les types n'existent-ils que pour limiter les options?

Étant donné un schéma GraphQL de ce qui suit:

const getQuestionStatus = ({ status }) => ['PENDING_REVIEW', 'PENDING_APPROVAL', 'APPROVED'][status];

et une requête qui ressemble à:

{ "description": "Some irrelevant job description", "status": "PENDING_APPROVAL" }

Si ma base de données a renvoyé ce qui suit:

{ "description": "Some irrelevant job description", "status": 1 }

Je m'attendrais à ce que GraphQL renvoie: p>

query job {
  description
  status
}

Ai-je mal configuré quelque chose, ou est-ce que ce comportement attendu va m'obliger à écrire un résolveur pour status

type Job {
  description: String!
  status: Status!
}

enum Status {
  PENDING_REVIEW
  PENDING_APPROVAL
  APPROVED
}


0 commentaires

4 Réponses :


0
votes

Je pense que vous devez implémenter un résolveur pour cela.

Cependant, si vous utilisez Apollo Server , il dispose d'une fonctionnalité appelée Internal Values ​​ où vous pouvez utiliser 1 comme valeur interne dans le résolveur, Apollo Server mappez-le automatiquement à PENDING_APPROVAL lors du renvoi de la réponse.


0 commentaires

0
votes

Cela dépend du langage dans lequel vous implémentez GraphQL. Les types enum dans GraphQL sont juste des types enum et rien de plus. Cela signifie, par exemple, que votre type d'énumération APPROVED ne correspond à rien. Cela donne au développeur plus d'espace pour faire ce qu'il veut avec lui. Si vous voulez qu'une énumération soit mappée à des entiers, vous aurez besoin d'un résolveur comme vous l'avez décrit.

De l ' article GraphQL sur les schémas et les types:

Notez que les implémentations de service GraphQL dans différents langages auront leur propre manière spécifique au langage de traiter les énumérations. Dans les langues qui prennent en charge les énumérations en tant que citoyen de première classe, l'implémentation pourrait en tirer parti; dans un langage comme JavaScript sans prise en charge d'énumération, ces valeurs peuvent être mappées en interne sur un ensemble d'entiers.


0 commentaires

9
votes

Dans GraphQL.js, chaque valeur enum d'un type Enum peut avoir une valeur associée. La définition de cette valeur est facultative; il utilise par défaut la représentation sous forme de chaîne du nom de la valeur. Autrement dit, pour une énumération comme:

const ExampleEnumType = new GraphQLEnumType({
  name: 'ExampleEnum',
  values: {
    FOO: {
      value: 11,
    },
    BAR: {
      value: 23,
    },
  },
})

par défaut, la valeur de FOO sera "FOO" . Si vous utilisez graphql-tools pour construire votre schéma (ou utilisez apollo-server , qui utilise graphql-tools sous le capot`) nous pouvons passer les valeurs d'un type Enum directement dans nos résolveurs:

ExampleEnum: {
  FOO: 'FOO',
  BAR: 'BAR',
}

Une fois que nous avons fait cela, nous pouvons renvoyer la valeur définie dans notre résolveur et ce sera sérialisé dans la valeur Enum appropriée. Remarque: il en va de même pour les énumérations qui sont utilisées comme arguments - si FOO est passé en argument, le résolveur recevra en fait une valeur de 11 . p>

Ne pas fournir de valeurs équivaut à faire:

const resolvers = {
  Query: {
    example: () => 11, // field with ExampleEnum type
  },
  ExampleEnum: {
    FOO: 11,
    BAR: 23,
  },
}

Il est également intéressant de noter que fournir des valeurs n'a aucun impact sur la façon dont les valeurs d'énumération sont affichées dans la réponse . Lorsque le résultat de l'exécution est sérialisé en JSON, les valeurs d'énumération sont toujours affichées sous forme de valeurs de chaîne qui correspondent aux noms des valeurs d'énumération (c'est-à-dire "FOO" et "BAR" dans notre exemple).

Qu'en est-il de vanilla GraphQL.js?

Les valeurs des valeurs d'énumération peuvent également être fournies si vous définissez votre schéma par programme. Voici un équivalent de l'exemple ci-dessus:

enum ExampleEnum {
  FOO
  BAR
}


1 commentaires

Qu'en est-il des valeurs d'énumération par défaut? Mes tests ont montré que le résolveur reçoit soit l'énumération comme un chaîne ou indéfini .



1
votes

Oui, vous devez écrire un résolveur à partir des valeurs d'énumération vers ce dont vous avez besoin, par exemple numéros, conformément à la documentation apollo-server pour les valeurs internes . Voici comment procéder avec TypeScript:

export enum Status {
  DRAFT,
  PENDING,
  APPROVED
}

const typeDefs = gql`
  enum Status {
    DRAFT
    PENDING
    APPROVED
  }

  type Query {
    echo(status: Status!): Int!
  }
`;

const resolvers = {
  Status: {
    DRAFT: Status.DRAFT,
    PENDING: Status.PENDING,
    APPROVED: Status.APPROVED
  },

  Query: {
    echo(_, { status }): String {
      console.log(status);
      return status;
    }
  }
};

Voici un Code Sandbox affichant l'analyse et le retour automatiques de l'énumération .

Notez cependant que pour les valeurs d'énumération par défaut qui sont des paramètres de requête, le comportement est douteux - le résolveur peut recevoir la valeur d'énumération sous forme de chaîne, ou undefined .


0 commentaires