Cette page s'applique à Apigee et à Apigee hybrid.
Consultez la documentation d'Apigee Edge.
Quoi
La règle GraphQL peut analyser les charges utiles GraphQL dans des variables de flux de messages, vérifier les requêtes GraphQL par rapport à un schéma, ou les deux.
Vous pouvez utiliser la règle GraphQL pour :
- Assurez-vous que vos API ne traitent que les requêtes conformes au schéma que vous fournissez.
- Imposer des restrictions sur la charge utile en définissant un nombre maximal de fragments autorisés.
- Associer GraphQL aux produits d'API.
- Utiliser les fonctionnalités des règles OAuth2, VerifyAPIKey et Quota exactement comme dans REST.
GraphQL est compatible avec les types de charges utiles suivants :
- POST des charges utiles graphQL avec
Content-Type : application/graphql
- POST des charges utiles graphQL avec
Content-Type: applcation/json
- GET des charges utiles graphQL où la charge utile est un paramètre de requête.
Pour en savoir plus, consultez les ressources suivantes :
Cette règle est une règle standard qui peut être déployée sur n'importe quel type d'environnement. Pour en savoir plus sur les types de règles et la disponibilité avec chaque type d'environnement, consultez la section Types de règles.
Consultez la section Utiliser GraphQL pour obtenir un exemple utilisant cette règle.
Élément <GraphQL>
Définit une règle <GraphQL>
.
Valeur par défaut | Consultez l'onglet Règles par défaut ci-dessous. |
Obligatoire ? | Obligatoire |
Type | TYPE |
Élément parent | N/A |
Éléments enfants | <Action> <MaxDepth> <MaxCount> <MaxPayloadSizeInBytes> <OperationType> <Source> <ResourceURL> |
Syntaxe
L'élément <GraphQL>
utilise la syntaxe suivante :
<GraphQL continueOnError="[false|true]" enabled="[true|false]" name="POLICY_NAME" > <Source>request</Source> <OperationType>[query|mutuation|all]</OperationType> <MaxDepth>MAX_DEPTH</MaxDepth> <MaxCount>MAX_NUMBER_OF_QUERIES</MaxCount> // [Start maxpayloadsize] <MaxPayloadSizeInBytes>MAX_PAYLOAD_SIZE_IN_BYTES</MaxPayloadSizeInBytes> <Action>parse</Action> <ResourceURL>PATH/TO/SCHEMA.xsd</ResourceURL> </GraphQL>
Règle par défaut
L'exemple suivant montre les paramètres par défaut lorsque vous ajoutez une règle <GraphQL>
à votre flux dans l'interface utilisateur d'Apigee :
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <GraphQL name="GraphQLParser"> <Source>request</Source> <OperationType>query</OperationType> <MaxDepth>10</MaxDepth> <MaxCount>10</MaxCount> <MaxPayloadSizeInBytes></MaxPayloadSizeInBytes> <Action>parse</Action> <ResourceURL></ResourceURL> </GraphQL>
Cet élément possède les attributs suivants qui sont communs à toutes les règles :
Attribut | Par défaut | Obligatoire ? | Description |
---|---|---|---|
name |
ND | Obligatoire |
Nom interne de la règle. La valeur de l'attribut Vous pouvez également utiliser l'élément |
continueOnError |
faux | Facultatif | Définissez sur false pour afficher une erreur en cas d'échec d'une règle. Il s'agit du comportement attendu pour la plupart des règles. Définissez sur true pour que l'exécution du flux se poursuive même après l'échec d'une règle. Voir aussi :
|
enabled |
true | Facultatif | Définissez sur true pour appliquer la règle. Définissez sur false pour désactiver la règle. La règle ne sera pas appliquée même si elle reste associée à un flux. |
async |
faux | Obsolète | Cet attribut est obsolète. |
Le tableau suivant fournit une description détaillée des éléments enfants de <GraphQL>
:
Élément enfant | Obligatoire ? | Description |
---|---|---|
Opérations courantes | ||
<Action> |
Facultatif | Spécifie l'action à effectuer pour une requête : parse , verify ou parse_verify (les deux).
|
<MaxCount> |
Facultatif | Nombre maximal de requêtes ou de fragments qu'une requête GraphQL peut générer. La valeur par défaut est 10. |
<MaxDepth> |
Facultatif | Profondeur maximale de l'arborescence pour la requête. La valeur par défaut est 4. |
<MaxPayloadSizeInBytes> |
Facultatif | Taille maximale d'une charge utile en kilo-octets. |
<OperationType> |
Requis | Spécifie le type de requête pouvant être analysé : query , mutation ou query_mutation (soit). |
<ResourceURL> |
Facultatif | DESCRIPTION Emplacement du fichier de schéma GraphQL. |
<Source> |
Requis | request |
Chacun des éléments enfants est décrit dans les sections ci-après.
Référence d'élément enfant
Cette section décrit les éléments enfants de <GraphQL>
.
<Action>
L'action représente l'une des actions GraphQL suivantes :
parse
: Apigee analyse la charge utile GraphQL dans les variables de flux de messages. Pour en savoir plus sur les variables définies lorsqueAction
est défini surparse
, consultez la section Exemples de représentations de variables de flux de messages. Cela peut vous faire gagner un temps CPU précieux dans le backend. Notez queverify
vérifie également la charge utile.verify
: Apigee vérifie que la charge utile GraphQL est conforme au schéma importé dans le proxy.parse_verify
: Apigee analyse et vérifie la requête GraphQL.
Valeur par défaut | parse |
Obligatoire ? | Facultatif |
Type | Chaîne |
Élément parent | <GraphQL> |
Éléments enfants | aucun |
L'élément <Action>
utilise la syntaxe suivante :
Syntaxe
<GraphQL continueOnError="[false|true]" enabled="[true|false]" name="POLICY_NAME" > <Action>parse</Action> </GraphQL>
<MaxCount>
Nombre maximal de fragments dans la charge utile. Cela permet d'éviter que le serveur de backend GraphQL du client n'exécute des requêtes extrêmement complexes, ce qui oblige les clients à diviser leur logique en charges utiles plus petites.
Valeur par défaut | 10 |
Obligatoire ? | Facultatif |
Type | Chaîne |
Élément parent | <GraphQL> |
Éléments enfants | aucun |
L'élément <MaxCount>
utilise la syntaxe suivante :
Syntaxe
<GraphQL continueOnError="[false|true]" enabled="[true|false]" name="POLICY_NAME" > <MaxCount>MAX_NUMBER_OF_QUERIES</MaxCount> </GraphQL>
<MaxDepth>
Profondeur maximale de la requête lorsqu'elle est représentée sous forme d'arborescence.
MaxDepth
vous permet de bloquer les requêtes avancées dans la charge utile afin qu'Apigee n'ait pas besoin de créer des variables de flux très volumineuses pour contenir les valeurs.
Cependant, la charge utile est envoyée telle quelle, quelle que soit la valeur MaxDepth
.
La valeur par défaut est 10.
Valeur par défaut | 10 |
Obligatoire ? | Facultatif |
Type | Entier |
Élément parent | <GraphQL> |
Éléments enfants | aucun |
L'élément <MaxDepth>
utilise la syntaxe suivante :
Syntaxe
<GraphQL continueOnError="[false|true]" enabled="[true|false]" name="POLICY_NAME" > <MaxDepth>MAX_DEPTH</MaxDepth> </GraphQL>
<MaxPayloadSizeInBytes>
Taille maximale d'une charge utile en kilo-octets. Vous pouvez utiliser cette valeur pour limiter la taille de la charge utile afin d'éviter les problèmes de performances.
Remarque : Si MaxPayloadSizeInByte
n'est pas fourni dans la règle, aucune restriction de taille n'est appliquée.
Valeur par défaut | request |
Obligatoire ? | Facultatif |
Type | Chaîne |
Élément parent | <GraphQL> |
Éléments enfants | aucun |
L'élément <MaxPayloadSizeInBytes>
utilise la syntaxe suivante :
Syntaxe
<GraphQL continueOnError="[false|true]" enabled="[true|false]" name="POLICY_NAME" > <MaxPayloadSizeInBytes>MAX_PAYLOAD_SIZE_IN_BYTES</MaxPayloadSizeInBytes> </GraphQL>
<OperationType>
Indique le type de requête pouvant être analysé :
query
: requête GraphQL.mutation
: mutation GraphQLquery_mutation
: requête ou mutation GraphQL.
Si le champ d'application est query
et qu'une requête de mutation est transmise, la requête échoue et renvoie une erreur 4xx
.
Valeur par défaut | query |
Obligatoire ? | Facultatif |
Type | Chaîne |
Élément parent | <GraphQL> |
Éléments enfants | aucun |
L'élément <OperationType>
utilise la syntaxe suivante :
Syntaxe
<GraphQL continueOnError="[false|true]" enabled="[true|false]" name="POLICY_NAME" > <OperationType>[query|mutation|query_mutation]</OperationType> </GraphQL>
<ResourceURL>
Chemin d'accès au fichier de schéma GraphQL que la règle GraphQL utilise pour vérifier les requêtes. Consultez la section Exemple pour découvrir comment importer un schéma GraphQL dans Apigee.
Si le nom de votre fichier de schéma importé est my-schema.graphql
, l'élément <ResourceURL>
est
<ResourceURL>graphql://my-schema.graphql</ResourceURL>
Valeur par défaut | N/A |
Obligatoire ? | Facultatif |
Type | Chaîne |
Élément parent | <GraphQL> |
Éléments enfants | aucun |
L'élément ResourceURL
utilise la syntaxe suivante :
Syntaxe
<GraphQL continueOnError="[false|true]" enabled="[true|false]" name="POLICY_NAME" > <ResourceURL>PATH/TO/SCHEMA.graphql</ResourceURL> </GraphQL>
<Source>
Source sur laquelle cette règle s'exécute.
Valeur par défaut | request |
Obligatoire ? | Facultatif |
Type | Chaîne |
Élément parent | <GraphQL> |
Éléments enfants | aucun |
L'élément <Source>
utilise la syntaxe suivante :
Syntaxe
<GraphQL continueOnError="[false|true]" enabled="[true|false]" name="POLICY_NAME" > <Source>request</Source> </GraphQL>
Analyseur GraphQL
L'analyseur graphQL est compatible avec toutes les fonctionnalités d'une requête graphQL et représente la requête sous forme de graphique dans la notation en pointillés du flux de messages. Une requête peut comprendre une définition d'opération et éventuellement des fragments identifiés comme définition de fragment. Consultez la spécification GraphQL.
Anatomie d'une requête graphQL
Le schéma ci-dessous illustre l'anatomie d'une requête graphQL.
Représentation de définitions d'opération dans le flux de messages
L'implémentation de l'analyseur couvre tous les aspects de la syntaxe graphQL, y compris la compatibilité avec les requêtes et les mutations. Consultez la section Variable de flux de messages.
Les variables de flux de messages suivent cette convention :
graphql.(root-index).(root definition)[(sub-indices).(child-definitions)…]
où :
graphql
: préfixe statique indiquant qu'il s'agit de variables de flux de messages liées à graphQL.root-Index
: index basé sur l'index des définitions de requête au niveau racine (par défaut, jusqu'à 4 par requête).root-definition
: corps, arguments et valeurs du message de la requête graphQL de niveau racine.sub-indices
: index enfants.child-definitions
: définitions au niveau de la feuille qui correspondent à des champs spécifiques et à leurs valeurs.
Représentation de définitions d'opération dans la variable de flux de messages
Champs dans le message | Type | Description |
---|---|---|
nom | Chaîne | Nom de l'opération graphQL. Notez que ce nom n'est pas lié au nom dans le flux de messages. |
definition | Chaîne - Opération | Indique qu'il contient le corps du message principal de la requête. |
operationType | requête ou mutation | Type d'opération en cours. |
variableDefinition | Entier | Ils fonctionnent exactement comme les définitions des arguments d'une fonction dans un langage saisi. Elle répertorie toutes les variables, précédées de $ et suivies de leur type. |
directives | Entier | @include et @skip sont les deux instructions actuellement proposées pour effectuer un filtrage sur la base de valeurs transmises de façon dynamique. |
selectionSet | Entier | Regroupement logique en un niveau de tous les attributs associés à un objet. |
Représentation de définitions de fragment dans le flux de messages
Nom de la variable de flux de messages | Type | Description |
---|---|---|
nom | Chaîne | Nom du fragment. |
definition | Chaîne - Fragment | Indique que le corps de la requête est un fragment de la requête principale. |
typeCondition | Chaîne | Condition sous laquelle le fragment est appelé. |
variableDefinition | Entier | Définition des variables transmise au fragment sous forme d'arguments. |
Exemples de représentations de variables de flux de messages
Les exemples suivants montrent les représentations de variables de flux de messages pour les exemples de charges utiles de requête.
Exemple de requête 1
Cet exemple montre une requête effectuée avec des arguments transmis en entrée, qui interroge trois attributs pour les employés.
{ employee(id: 123) { id firstName lastName } }
Le tableau affiche les représentations des variables de flux de messages correspondantes.
Variable de flux de messages | Valeur |
---|---|
graphql.operation.operationType |
QUERY |
graphql.fragment.count |
1 |
graphql.operation.selectionSet.count |
1 |
graphql.operation.variableDefinitions.count |
0 |
graphql.operation.selectionSet.1.name |
employee |
graphql.operation.selectionSet.1.argument.count |
1 |
graphql.operation.selectionSet.1.argument.1.name |
id |
graphql.operation.selectionSet.1.argument.1.value |
IntValue{value=123} |
graphql.operation.selectionSet.1.directive.count |
0 |
graphql.operation.selectionSet.1.selectionSet.count |
3 |
graphql.operation.selectionSet.1.selectionSet.1.name |
id |
graphql.operation.selectionSet.1.selectionSet.2.name |
firstName |
graphql.operation.selectionSet.1.selectionSet.3.name |
lastName |
Exemple de requête 2
Cet exemple montre une requête effectuée avec des arguments transmis en entrée, qui interroge les noms d'amis.
query Characters($episode: Episode, $withFriends: Boolean!) { friends @include(if: $withFriends) { friendsName } }
Le tableau ci-dessous montre les représentations des variables de flux de messages correspondantes.
Variable de flux de messages | Valeur |
---|---|
graphql.operation.operationType |
QUERY |
graphql.operation.selectionSet.count |
1 |
graphql.operation.name |
Characters |
graphql.fragment.count |
0 |
graphql.operation.selectionSet.1.name |
friends |
graphql.operation.variableDefinitions.count |
2 |
graphql.operation.variableDefinitions.1.name |
episode |
graphql.operation.variableDefinitions.1.type |
TypeName{name='Episode'} |
graphql.operation.variableDefinitions.2.name |
withFriends |
graphql.operation.variableDefinitions.2.type |
NonNullType{type=TypeName{name='Boolean'}} |
graphql.operation.selectionSet.1.argument.count |
0 |
graphql.operation.selectionSet.1.selectionSet.count |
1 |
graphql.operation.selectionSet.1.selectionSet.1.name |
friendsName |
graphql.operation.selectionSet.1.directive.count |
1 |
graphql.operation.selectionSet.1.directive.1.argument.1.name |
if |
graphql.operation.selectionSet.1.directive.1.argument.1.value |
VariableReference{name='withFriends'} |
Exemple de requête 3
Cet exemple comporte une définition de variable avec un alias.
query getUsers { admins: users(role: ADMIN) { lastName } accountants: users(role: ACCOUNTANT) { firstName } }
Le tableau ci-dessous montre les représentations des variables de flux de messages correspondantes.
Variable de flux de messages | Valeur |
---|---|
graphql.operation.operationType |
QUERY |
graphql.operation.selectionSet.count |
2 |
graphql.operation.selectionSet.1.name |
users |
graphql.operation.selectionSet.1.alias |
admins |
graphql.operation.variableDefinitions.count |
0 |
graphql.operation.selectionSet.1.argument.count |
1 |
graphql.operation.selectionSet.1.argument.1.name |
role |
graphql.operation.selectionSet.1.argument.1.value |
EnumValue{name='ADMIN'} |
graphql.operation.selectionSet.1.argument.2.name |
null |
graphql.operation.selectionSet.1.argument.2.value |
null |
graphql.operation.selectionSet.1.selectionSet.count |
1 |
graphql.operation.selectionSet.1.selectionSet.count |
1 |
graphql.operation.selectionSet.1.selectionSet.1.name |
lastName |
graphql.operation.selectionSet.1.selectionSet.1.alias |
null |
graphql.operation.selectionSet.1.selectionSet.2.name |
null |
graphql.operation.selectionSet.1.selectionSet.2.alias |
null |
graphql.operation.selectionSet.1.directive.count |
0 |
graphql.operation.selectionSet.1.directive.1.argument.1.name |
null |
graphql.operation.selectionSet.1.directive.1.argument.1.value |
null |
graphql.operation.selectionSet.2.name |
users |
graphql.operation.selectionSet.2.alias |
accountants |
graphql.operation.selectionSet.2.argument.count |
1 |
graphql.operation.selectionSet.2.argument.1.name |
role |
graphql.operation.selectionSet.2.argument.1.value |
EnumValue{name='ACCOUNTANT'} |
graphql.operation.selectionSet.2.selectionSet.count |
1 |
graphql.operation.selectionSet.2.selectionSet.1.name |
firstName |
graphql.operation.selectionSet.2.directive.count |
0 |
graphql.operation.selectionSet.2.selectionSet.1.alias |
null |
graphql.operation.selectionSet.2.selectionSet.2.name |
null |
graphql.operation.selectionSet.2.selectionSet.2.alias |
null |
graphql.operation.selectionSet.2.directive.count |
0 |