Vous consultez la documentation d'Apigee Edge.
Accéder à la documentation sur Apigee X en savoir plus
Les instructions conditionnelles sont une structure de contrôle commune à tous les langages de programmation. À l'instar d'un langage de programmation, la configuration des proxys d'API accepte les instructions conditionnelles pour les flux, les règles, les étapes et les règles de routage. La définition d'instructions conditionnelles vous permet de définir le comportement dynamique de votre API. Ce comportement dynamique vous permet par exemple de convertir le format XML au format JSON uniquement pour les appareils mobiles, ou de router vers une URL de backend en fonction du type de contenu ou du verbe HTTP du message de requête.
Cette rubrique explique comment utiliser des conditions pour appliquer dynamiquement les fonctionnalités de gestion des API lors de l'exécution, sans avoir à écrire de code.
Configurer des instructions conditionnelles
Le comportement conditionnel est mis en œuvre dans les proxys d'API à l'aide d'une combinaison de conditions et de variables. Une instruction conditionnelle est créée à l'aide d'un élément de condition. La condition suivante est vide :
<Condition></Condition>
Pour créer une instruction conditionnelle, ajoutez un opérateur conditionnel et une variable pour créer la structure suivante :
<Condition>{variable.name}{operator}{"value"}</Condition>
Les opérateurs conditionnels acceptés incluent =
(est égal à), !=
(différent de) et >
(supérieur à). Pour plus de lisibilité, vous pouvez également écrire les conditions sous forme de texte : equals
, notequals
, greaterthan
.
Lorsque vous travaillez avec des chemins d'accès d'URI, vous pouvez utiliser ~/
ou MatchesPath
. Vous pouvez également faire correspondre des expressions régulières JavaRegex avec l'opérateur ~~.
Les conditions permettent de définir les flux conditionnels du proxy d'API pour les ressources de l'API backend, décrites dans la section Créer des flux conditionnels aux ressources de l'API backend. Pour obtenir une liste complète des conditions, consultez la documentation de référence sur les conditions.
Variables
Les conditions réalisent leur tâche en évaluant les valeurs des variables. Une variable est une propriété d'une transaction HTTP exécutée par un proxy d'API ou une propriété de configuration de proxy d'API elle-même. Chaque fois qu'un proxy d'API reçoit une requête d'une application, Apigee Edge renseigne une longue liste de variables associées à des éléments tels que l'heure système, les informations réseau de l'application, les en-têtes HTTP des messages, la configuration du proxy d'API, les exécutions de stratégies, etc. Cela permet de créer un contexte enrichi que vous pouvez utiliser pour configurer des instructions conditionnelles.
Les variables utilisent toujours une notation en pointillés. Par exemple, les en-têtes HTTP du message de requête sont disponibles sous la forme de variables appelées request.header.{header_name}
. Ainsi, pour évaluer l'en-tête Content-type, vous pouvez utiliser la variable request.header.Content-type
. Par exemple, request.header.Content-type = "application/json"
indique que le type de contenu de la requête doit être JSON.
Imaginez que vous deviez créer une instruction conditionnelle qui entraîne l'application d'une stratégie uniquement lorsqu'un message de requête est de type GET. Pour créer une condition qui évalue le verbe HTTP d'une requête, vous devez créer l'instruction conditionnelle ci-dessous. La variable de cette condition est request.verb
. La valeur de la variable est GET
. L'opérateur est =
.
<Condition>request.verb = "GET"</Condition>Vous pouvez également utiliser :
<Condition>request.verb equals "GET"</Condition>
Edge utilise une telle instruction pour évaluer les conditions. L'exemple ci-dessus renvoie la valeur "true" si le verbe HTTP associé à la requête est GET. Si le verbe HTTP associé à la requête est POST, l'instruction renvoie la valeur "false".
Pour activer le comportement dynamique, vous pouvez associer des conditions aux flux, aux étapes et aux règles de routage.
Lorsque vous associez une condition à un flux, vous créez un "flux conditionnel". Les flux conditionnels ne s'exécutent que lorsque la condition est évaluée à true. Vous pouvez associer autant de stratégies que vous le souhaitez à un flux conditionnel. Un flux conditionnel vous permet de créer des stratégies de traitement très spécialisées pour les messages de demande ou de réponse qui répondent à certains critères.
Par exemple, pour créer un flux qui ne s'exécute que lorsque le verbe de la requête est "GET" :
<Flows> <Flow name="ExecuteForGETs"> <Condition>request.verb="GET"</Condition> </Flow> </Flows>
Pour créer un flux pour les requêtes GET et un autre pour les requêtes POST, procédez comme suit :
<Flows> <Flow name="ExecuteForGETs"> <Condition>request.verb="GET"</Condition> </Flow> <Flow name="ExecuteForPOSTs"> <Condition>request.verb="POST"</Condition> </Flow> </Flows>
Comme l'illustre l'exemple ci-dessous, vous pouvez appliquer la condition à l'étape de la règle elle-même. La condition suivante force l'application de la règle "VerifyApiKey" uniquement si un message est une requête POST.
<PreFlow name="PreFlow"> <Request> <Step> <Condition>request.verb equals "POST"</Condition> <Name>VerifyApiKey</Name> </Step> </Request> </PreFlow>
Une fois que vous avez défini de tels flux conditionnels, vous pouvez leur associer des règles qui activent un proxy d'API pour appliquer un ensemble de règles aux requêtes GET et un autre ensemble aux requêtes POST.
Pour obtenir des informations de référence complètes, consultez les ressources suivantes :
Exemple 1
L'exemple suivant montre un flux conditionnel unique nommé Convert-for-devices
, configuré dans le flux de réponse ProxyEndpoint. Ajoutez la condition en tant qu'élément à l'entité à laquelle la condition s'applique. Dans cet exemple, la condition est un composant du flux.
Par conséquent, le flux s'exécute chaque fois que l'instruction renvoie la valeur "true".
<Flows> <Flow name="Convert-for-devices"> <Condition>(request.header.User-Agent = "Mozilla")</Condition> <Response> <Step><Name>ConvertToJSON</Name></Step> </Response> </Flow> </Flows>
Pour chaque requête reçue d'une application, Edge stocke les valeurs de tous les en-têtes HTTP présents sous forme de variables. Si la requête contient un en-tête HTTP appelé User-Agent
, cet en-tête et sa valeur sont stockés sous forme de variable appelée request.header.User-Agent
.
Compte tenu de la configuration de "ProxyEndpoint" ci-dessus, Edge vérifie la valeur de la variable request.header.User-Agent
pour déterminer si la condition est égale à "true".
Si la condition renvoie la valeur "true", c'est-à-dire que la valeur de la variable request.header.User-Agent
est Mozilla
, le flux conditionnel s'exécute et la stratégie XMLtoJSON appelée ConvertToJSON
est appliquée. Dans le cas contraire, le flux n'est pas exécuté et la réponse XML est renvoyée sans modification (au format XML) à l'application à l'origine de la requête.
Exemple 2
Prenons un exemple spécifique dans lequel vous devez convertir un message de réponse du format XML vers le format JSON, mais uniquement pour les appareils mobiles. Commencez par créer la règle qui convertit la réponse au format XML de l'API Weather vers le format JSON :
<XMLToJSON name="ConvertToJSON"> <Options> </Options> <OutputVariable>response</OutputVariable> <Source>response</Source> </XMLToJSON>
La configuration des règles ci-dessus indique au proxy d'API de récupérer le message de réponse, d'en effectuer une conversion de XML à JSON selon les paramètres par défaut, puis d'écrire le résultat dans le nouveau message de réponse. (Si vous convertissez un message request au format XML en JSON, il vous suffit de définir ces deux valeurs sur request
.)
Étant donné que vous souhaitez convertir les réponses du format XML vers le format JSON, vous devez configurer un flux de réponse conditionnel pour effectuer la conversion. Par exemple, pour convertir toutes les réponses du format XML vers le format JSON avant qu'elles ne soient renvoyées à l'application cliente, configurez le flux de réponse ProxyEndpoint suivant.
<Flows> <Flow name="Convert-for-devices"> <Response> <Step><Name>ConvertToJSON</Name></Step> </Response> </Flow> </Flows>
Lorsque vous appelez l'API à l'aide de la requête standard, la réponse est au format JSON.
Toutefois, votre objectif est de convertir les rapports météorologiques au format JSON lorsque le client demandeur est un appareil mobile. Pour activer ce comportement dynamique, vous devez ajouter une instruction conditionnelle au flux.
Tester le flux conditionnel
Dans cet exemple de requête, l'en-tête HTTP User-Agent
est défini sur Mozilla
, ce qui a pour effet de rendre l'instruction conditionnelle égale à "true" et de lancer l'exécution du flux conditionnel Convert-for-devices
.
$ curl -H "User-Agent:Mozilla" http://{org_name}-test.apigee.net/weather/forecastrss?w=12797282
ou, pour imprimer une version correctement formatée du code en Python, si disponible :
$ curl -H "User-Agent:Mozilla" http://{org_name}-test.apigee.net/weather/forecastrss?w=12797282 | python -mjson.tool
Exemple de réponse :
. . . "yweather_forecast": [ { "code": "11", "date": "12 Dec 2012", "day": "Wed", "high": "55", "low": "36", "text": "Showers" }, { "code": "32", "date": "13 Dec 2012", "day": "Thu", "high": "56", "low": "38", "text": "Sunny" } ] } . . .
Une requête envoyée sans en-tête User-Agent
ou avec une valeur différente de Mozilla
entraînera une réponse au format XML.
$ curl http://{org_name}-test.apigee.net/weather/forecastrss?w=12797282
La réponse XML non modifiée est renvoyée.
Exemple de réponse :
<yweather:forecast day="Wed" date="12 Dec 2012" low="36" high="55" text="Showers" code="11" /> <yweather:forecast day="Thu" date="13 Dec 2012" low="38" high="56" text="Sunny" code="32" />
Correspondance de modèles
Cette section explique comment utiliser la correspondance de modèle avec des conditions dans un flux Apigee.
Opérateurs
Cette section explique comment utiliser les opérateurs de mise en correspondance de modèles suivants dans les instructions conditionnelles :
- Opérateur Matches : simple correspondance de format
- Opérateur "JavaRegex" : contrôle plus précis de la mise en correspondance
- Opérateur MatchesPath : correspondance de fragment de chemin
Correspondances
Commençons par examiner l'opérateur conditionnel "Matches" ou "~". Ces deux opérateurs sont identiques : la version en toutes lettres, "Matches", est considérée comme une option plus lisible.
Résumé : l'opérateur "Matches" vous offre deux possibilités. Soit faire correspondre la chaîne littéralement, soit au moyen d'un caractère générique comme "*". Comme vous pouvez le supposer, le caractère générique correspond à zéro ou plusieurs caractères. Voyons comment cela fonctionne.
Le code XML suivant montre une condition d'étape. Elle exécute la stratégie SomePolicy lorsque la condition est évaluée à "true". Dans cet exemple, nous testons la variable proxy.pathsuffix
, une variable intégrée dans Edge qui stocke le suffixe de chemin d'accès de la requête. Toutefois, vous pouvez tester la valeur de toute variable de flux contenant une chaîne. Ainsi, dans ce cas, si le chemin de base de la requête entrante est /animals
et que la requête est /animals/cat
, le suffixe du chemin d'accès correspond à la chaîne littérale "/cat
".
<PreFlow name="PreFlow"> <Request> <Step> <Condition>(proxy.pathsuffix Matches "/cat")</Condition> <Name>SomePolicy</Name> </Step> </Request> <Response/> </PreFlow>
Question : quel suffixe de chemin d'accès au proxy entraîne l'exécution de "SomePolicy" ? Il n'y a qu'une seule possibilité.
Appel d'API :
GET http://artomatic-test.apigee.net/matchtest/cat
La règle s'exécute-t-elle ? Oui, car le suffixe du chemin d'accès du proxy correspond exactement à "/cat
". Elle ne s'exécutera pas si le suffixe est /bat
, /dog
, "/
" ou autre.
Soit maintenant cette instruction conditionnelle où nous utilisons le caractère générique "*
" :
<Condition>(proxy.pathsuffix Matches "/*at")</Condition>
Appel d'API :
GET http://artomatic-test.apigee.net/matchtest/cat
La règle s'exécute-t-elle ? Oui, car le caractère générique correspond à n'importe quel caractère, et ""/cat
" est une correspondance.
Appel d'API :
GET http://artomatic-test.apigee.net/matchtest/bat
La règle s'exécute-t-elle ? Oui, puisque le caractère générique correspond à n'importe quel caractère, "/bat"
est une correspondance.
Appel d'API :
GET http://artomatic-test.apigee.net/matchtest/owl
La règle s'exécute-t-elle ? Certainement pas. Bien que le caractère générique corresponde à "o
", les lettres "wl
" ne correspondent pas.
Maintenant, déplacez le caractère générique à la fin du suffixe :
<Condition>(proxy.pathsuffix Matches "/cat*")</Condition>
Appel d'API :
GET http://artomatic-test.apigee.net/matchtest/cat
La règle s'exécute-t-elle ? Oui, car le caractère générique correspond à zéro ou plusieurs caractères.
Appel d'API :
GET http://artomatic-test.apigee.net/matchtest/bat
La règle s'exécute-t-elle ? Non, "/bat
" n'est pas une correspondance.
Appel d'API :
GET http://artomatic-test.apigee.net/matchtest/cat123
La règle s'exécute-t-elle ? Oui, le caractère générique correspond à zéro ou plusieurs caractères. Par conséquent, "123
" génère une correspondance.
Appel d'API :
GET http://artomatic-test.apigee.net/matchtest/cat/bird/mouse
La règle s'exécute-t-elle ? Oui, car le caractère générique correspond à zéro ou plusieurs caractères. Par conséquent, "/bird/mouse
" génère une correspondance. Notez qu'une telle expression peut poser problème, car elle correspond à tous les éléments situés après les caractères littéraux !
Question : l'opérateur "Matches" est-il sensible à la casse ?
Oui. Supposons une condition comme celle-ci :
<Condition>(proxy.pathsuffix Matches "/*At")</Condition>
Appel d'API :
GET http://artomatic-test.apigee.net/matchtest/cat
La règle s'exécute-t-elle ? Non, le caractère générique correspond à n'importe quelle lettre (indépendamment du cas), mais "a" minuscule ne correspond pas à "A".
Appel d'API :
GET http://artomatic-test.apigee.net/matchtest/bAt
La règle s'exécute-t-elle ? Oui, la casse correspond.
Question : comment échapper les caractères avec l'opérateur "Matches" ?
Utilisez le caractère de pourcentage "%" pour échapper les caractères réservés. Exemple :
<Condition>(proxy.pathsuffix Matches "/c%*at")</Condition>
Appel d'API :
GET http://artomatic-test.apigee.net/matchtest/cat
La règle s'exécute-t-elle ? Non, l'opérateur "Matches" recherche la chaîne littérale "c*at".
Appel d'API :
GET http://artomatic-test.apigee.net/matchtest/c*at
Question : la règle s'exécute-t-elle ?
Oui, bien que ce chemin d'accès soit légèrement inhabituel.
JavaRegex
Comme vous pouvez le voir, l'opérateur "Matches" est idéal pour les situations simples. Toutefois, vous pouvez utiliser un autre opérateur : l'opérateur "JavaRegex" ou "~~". Ces deux opérateurs sont les mêmes, mais "JavaRegex" est considéré comme plus lisible. Il se nomme "JavaRegex", car il autorise la mise en correspondance des modèles d'expression régulière, et Edge suit les mêmes règles que les classes du package java.util.regex du langage Java. Le fonctionnement de l'opérateur "JavaRegex" est très différent de celui de l'opérateur "Matches". Il est donc important de ne pas les confondre !
Résumé : l'opérateur "JavaRegex" vous permet d'utiliser la syntaxe des expressions régulières dans les instructions conditionnelles.
Le code suivant montre une condition d'étape. Elle exécute la stratégie SomePolicy si la condition est évaluée à "true". Dans cet exemple, nous testons la variable proxy.pathsuffix
, une variable intégrée dans Edge qui stocke le suffixe de chemin d'accès de la requête. Si le chemin de base de la requête entrante est /animals
et que la requête est /animals/cat
, le suffixe du chemin est la chaîne littérale "/cat
".
<PreFlow name="PreFlow"> <Request> <Step> <Condition>(proxy.pathsuffix JavaRegex "/cat")</Condition> <Name>SomePolicy</Name> </Step> </Request> <Response/> </PreFlow>
Question : quel suffixe de chemin d'accès au proxy entraîne l'exécution de "SomePolicy" ? Comme pour l'opérateur "Matches", il n'existe qu'une seule possibilité dans ce cas.
Appel d'API :
GET http://artomatic-test.apigee.net/matchtest/cat
La règle s'exécute-t-elle ? Oui, car le suffixe du chemin d'accès du proxy correspond exactement à "/cat
". Elle ne s'exécutera pas si le suffixe est /bat
, /dog
, ou un autre élément.
Nous allons maintenant créer une expression régulière à l'aide du quantificateur *. Ce quantificateur correspond à zéro ou plusieurs des caractères précédents.
<Condition>(proxy.pathsuffix JavaRegex "/c*t")</Condition>
Appel d'API :
GET http://artomatic-test.apigee.net/matchtest/cat
La règle s'exécute-t-elle ? Non. Le quantificateur "*" correspond à zéro ou plusieurs occurrences du caractère qui précède, soit un caractère "c
".
Appel d'API :
GET http://artomatic-test.apigee.net/matchtest/ccccct
La règle s'exécute-t-elle ? Oui, car le caractère générique correspond à zéro ou plusieurs occurrences du caractère qui précède.
Nous utilisons ensuite le quantificateur "?
", qui correspond une fois au caractère qui précède, ou n'y correspond pas du tout.
<Condition>(proxy.pathsuffix JavaRegex "/ca?t")</Condition>
Appel d'API :
GET http://artomatic-test.apigee.net/matchtest/cat
La règle s'exécute-t-elle ? Oui. Le quantificateur "?
" correspond à zéro ou une occurrence du caractère qui précède, soit le caractère "a
".
Appel d'API :
GET http://artomatic-test.apigee.net/matchtest/ct
La règle s'exécute-t-elle ? Oui. Le quantificateur "?
" correspond à une occurrence du caractère qui précède ou n'y correspond pas. Dans ce cas, il n'y a pas de caractère "a", la condition est donc égale à "true".
Appel d'API :
GET http://artomatic-test.apigee.net/matchtest/caat
La règle s'exécute-t-elle ? Non. Le caractère quantificateur "?" correspond à une occurrence du caractère qui précède, qui est un "a
".
Nous utilisons ensuite le style "[abc]
" ou "groupement" d'expression régulière. Il correspond aux caractères "a
", "b
" ou "c
".
<Condition>(proxy.pathsuffix JavaRegex "/[cbr]at")</Condition>
Appel d'API :
GET http://artomatic-test.apigee.net/matchtest/cat
La règle s'exécute-t-elle ? Oui. Nous utilisons ici des expressions régulières et l'expression "[cbr]
" correspond à "c", "b", OU "r". Ces appels correspondent également :
GET http://artomatic-test.apigee.net/matchtest/bat
GET http://artomatic-test.apigee.net/matchtest/rat
Mais dans ce cas, il n'y pas de correspondance :
GET http://artomatic-test.apigee.net/matchtest/mat
Question : l'opérateur "JavaRegex" est-il sensible à la casse ?
Oui. Supposons une condition comme celle-ci :
<Condition>(proxy.pathsuffix JavaRegex "/ca?t")</Condition>
Appel d'API :
GET http://artomatic-test.apigee.net/matchtest/cat
La règle s'exécute-t-elle ? Oui, l'expression régulière correspond à zéro ou à une occurrence du caractère qui précède, qui est "a".
Appel d'API :
GET http://artomatic-test.apigee.net/matchtest/cAt
Question : la règle s'exécute-t-elle ?
Non, car le "A" majuscule ne correspond pas au "a" minuscule.
MatchesPath
L'opérateur MatchesPath
peut également être spécifié comme suit : "~/". Il ressemble à peu près aux opérateurs Matches
(~) et "JavaRegex" (~~). Cependant, "MatchesPath" est complètement différent.
Gardez à l'esprit que cet opérateur considère un chemin d'accès comme une série de parties. Par conséquent, si le chemin d'accès est /animals/cats/wild
, vous pouvez le considérer comme composé des parties "/animals
", "/cats
" et "/wild
".
L'opérateur MatchesPath
vous permet d'utiliser deux notations génériques : un astérisque unique (*) et un double astérisque (**). L'astérisque unique correspond à un élément de chemin d'accès. Le double astérisque correspond à un ou plusieurs éléments du chemin d'accès.
Prenons un exemple. Dans cet exemple, nous testons la variable proxy.pathsuffix
, une variable intégrée dans Edge qui stocke le suffixe de chemin d'accès de la requête. Toutefois, vous pouvez tester la valeur de toute variable de flux contenant une chaîne.
<PreFlow name="PreFlow"> <Request> <Step> <Condition>(proxy.pathsuffix MatchesPath "/animals/*")</Condition> <Name>SomePolicy</Name> </Step> </Request> <Response/> </PreFlow>
Question : quel suffixe de chemin d'accès au proxy entraîne l'exécution de "SomePolicy" ?
Appel d'API :
GET http://artomatic-test.apigee.net/matchtest/animals
Question : la règle s'exécute-t-elle ?
Non, car la condition nécessite un autre élément de chemin d'accès après "/animals
", comme spécifié par "/*
".
Appel d'API :
GET http://artomatic-test.apigee.net/matchtest/animals
/
La règle s'exécute-t-elle ? Oui, le chemin d'accès comporte un autre élément de chemin d'accès (la partie située après "/animals/
"), mais il est vide.
Appel d'API :
GET http://artomatic-test.apigee.net/matchtest/animals/cats
La règle s'exécute-t-elle ? Oui, car le chemin d'accès comporte clairement un élément ("/cats
") après "/animals
"
Appel d'API :
GET http://artomatic-test.apigee.net/matchtest/animals/cats/wild
Question : la règle s'exécute-t-elle ?
Non, car l'astérisque unique ne correspond qu'à un seul élément de chemin, et cette API comporte plusieurs éléments après "/animals
".
Utilisons maintenant le double astérisque :
<PreFlow name="PreFlow"> <Request> <Step> <Condition>(proxy.pathsuffix MatchesPath "/animals/**")</Condition> <Name>SomePolicy</Name> </Step> </Request> <Response/> </PreFlow>
Question : quel suffixe de chemin d'accès au proxy entraîne l'exécution de "SomePolicy" ?
Appel d'API :
GET http://artomatic-test.apigee.net/matchtest/animals
La règle s'exécute-t-elle ? Non, car la condition requiert au moins un élément de chemin à la suite, spécifié par "/**
".
Appel d'API :
GET http://artomatic-test.apigee.net/matchtest/animals
/
La règle s'exécute-t-elle ?
Oui, le chemin d'accès comporte un autre élément de chemin d'accès (la partie située après "/animals/
"), mais il est vide.
Appel d'API :
GET http://artomatic-test.apigee.net/matchtest/animals/cats
La règle s'exécute-t-elle ?
Oui, car le chemin d'accès comporte au moins un élément situé après "/animals
".
Appel d'API :
GET http://artomatic-test.apigee.net/matchtest/animals/cats/wild
La règle s'exécute-t-elle ?
Oui, car le chemin d'accès comporte plusieurs éléments placés après "/animals
".
Astérisques mixtes
Vous pouvez combiner l'astérisque unique (*) et le double astérisque (**) pour affiner la correspondance avec le chemin d'accès.
<PreFlow name="PreFlow"> <Request> <Step> <Condition>(proxy.pathsuffix MatchesPath "/animals/*/wild/**")</Condition> <Name>SomePolicy</Name> </Step> </Request> <Response/> </PreFlow>
Appel d'API :
Tous ces appels d'API génèrent une correspondance :
GET http://artomatic-test.apigee.net/matchtest/animals/cats/wild/
et
GET http://artomatic-test.apigee.net/matchtest/animals/dogs/wild/austrailian
etGET
http://artomatic-test.apigee.net/matchtest/animals/birds/wild/american/finches
Ressources liées aux API
Les services RESTful sont des collections de ressources d'API. Une ressource d'API est un fragment de chemin d'URI qui identifie une entité à laquelle les développeurs peuvent accéder en appelant votre API. Par exemple, si votre service fournit des rapports et des prévisions météorologiques, votre service de backend peut définir deux ressources d'API :
- http://mygreatweatherforecast.com/reports
- http://mygreatweatherforecast.com/forecasts
Lorsque vous créez un proxy d'API (comme indiqué dans la section Créer votre premier proxy d'API), vous créez au minimum une URL d'alias de base qui correspond à votre service de backend. Exemple :
URL de base du backend | URL de proxy d'API nouvelle/équivalente |
---|---|
http://mygreatweatherforecast.com | http://{your_org}-{environment}.apigee.net/mygreatweatherforecast |
À ce stade, vous pouvez effectuer des appels d'API vers votre backend à l'aide de l'une ou l'autre des URL de base. Toutefois, lorsque vous utilisez l'URL de proxy d'API, la situation commence à s'intéresser.
En plus des analyses d'API qu'Edge commence à collecter lorsque vous utilisez le proxy d'API, les proxys vous permettent également de définir des flux conditionnels mappés aux ressources de votre backend. Concrètement, "si un appel GET parvient à la ressource /reports, Edge doit faire quelque chose."
L'image suivante montre la différence de comportement entre deux URL qui accèdent finalement au même backend. L'une est l'URL de la ressource sans proxy, l'autre est un proxy d'API Edge avec un flux conditionnel à la même ressource backend. Vous trouverez ci-dessous une description détaillée des flux conditionnels.
Mappage des proxys d'API vers des ressources backend spécifiques
Avec une URL de proxy d'API mappée à l'URL de base du service de backend (lorsque vous créez le proxy), vous pouvez ajouter des flux conditionnels à des ressources spécifiques, telles que les ressources /reports
et /forecasts
mentionnées plus haut.
Supposons que vous vouliez qu'Edge effectue une "action" lorsque les appels sont transmis aux ressources /reports
ou /forecasts
. À ce stade, vous ne demandez pas à Edge de faire ce qu'il faut faire, mais vous devez simplement écouter les appels à ces ressources. Pour ce faire, utilisez des conditions. Dans votre proxy d'API Edge, vous pouvez créer des flux conditionnels pour /reports
et /forecasts
. À des fins de concept, le fichier XML de proxy d'API suivant illustre ce à quoi pourraient ressembler ces conditions.
<Flows> <Flow name="reports"> <Description/> <Request/> <Response/> <Condition>(proxy.pathsuffix MatchesPath "/reports") and (request.verb = "GET")</Condition> </Flow> <Flow name="forecasts"> <Description/> <Request/> <Response/> <Condition>(proxy.pathsuffix MatchesPath "/forecasts") and (request.verb = "GET")</Condition> </Flow> </Flows>
Les conditions sont les suivantes : "Lorsqu'une requête GET est effectuée avec une URL comportant /reports
et /forecasts
, Edge effectue toutes les opérations que vous (le développeur de l'API) lui précisez, via les règles que vous appliquez à ces flux.
Maintenant, voici un exemple d'indication à Edge de ce qu'il doit faire lorsqu'une condition est remplie. Dans le fichier XML de proxy d'API ci-dessous, lorsqu'une requête GET est envoyée à https://yourorg-test.apigee.net/mygreatweatherforecast/reports
, Edge exécute la règle "XML-to-JSON-1" dans la réponse.
<Flows> <Flow name="reports"> <Description/> <Request/> <Response> <Step> <Name>XML-to-JSON-1</Name> </Step> </Response> <Condition>(proxy.pathsuffix MatchesPath "/reports") and (request.verb = "GET")</Condition> </Flow>
En plus de ces flux conditionnels facultatifs, chaque proxy d'API est également doté de deux flux par défaut : un <PreFlow>
exécuté avant vos flux conditionnels et un <PostFlow>
exécuté après. Ils sont utiles pour exécuter des règles lorsque tout appel est envoyé à un proxy d'API. Par exemple, si vous souhaitez valider la clé API d'une application à chaque appel, quelle que soit la ressource de backend accessible, vous pouvez placer une règle "Verify API Key" sur <PreFlow>
. Pour plus d'informations sur les flux, consultez la section Configurer les flux.
Créer des flux conditionnels sur des ressources de backend
La définition de flux conditionnels sur des ressources de backend dans un proxy d'API est totalement facultative. Toutefois, ces flux conditionnels vous permettent d'appliquer une gestion et une surveillance précises.
Vous bénéficierez entre autres des avantages suivants :
- Appliquer la gestion de manière à refléter la sémantique de votre modèle d'API
- Appliquer des règles et un comportement scripté à des chemins d'accès de ressources individuels (URI)
- Collecter des métriques détaillées pour les services d'analyse
Par exemple, imaginez que vous deviez appliquer différents types de logique aux ressources /apps de votre backend /developers.
Pour ce faire, ajoutez deux flux conditionnels dans votre proxy d'API : /developers
et /apps
.
Dans la vue "Develop" du volet de navigation de l'éditeur du proxy d'API, cliquez sur l'icône + à côté de la valeur par défaut de Proxy Endpoints.
Dans la fenêtre "New Conditional Flow", saisissez les configurations de clé suivantes :
- Flow name : "Developers"
- Condition Type : "Path"
- Path : "/developers"
La condition est déclenchée (et les règles sont exécutées) si un appel comportant "/developers" à la fin de l'URI est envoyé au proxy.
Ajoutez maintenant un flux conditionnel pour /apps et supposons que vous souhaitez que la condition soit déclenchée à la fois par l'URI et par le verbe "POST" d'une requête. La configuration implique de définir les éléments suivants :
- Flow Name : "Apps"
- Condition Type (Type de condition) : chemin et verbe
- Path : "/apps"
- Verb : "POST"
La condition est déclenchée (et les règles sont exécutées) si un appel comportant "/apps" à la fin de l'URI et un verbe "POST" est envoyé au proxy.
Dans le volet de navigation, de nouveaux flux s'affichent pour Applications et Developers.
Sélectionnez l'un des flux pour afficher la configuration du flux conditionnel dans la vue Code de l'éditeur de proxy d'API :
<Flow name="Apps"> <Description>Developer apps registered in Developer Services</Description> <Request/> <Response/> <Condition>(proxy.pathsuffix MatchesPath "/apps") and (request.verb = "POST")</Condition> </Flow>
Comme vous pouvez le voir, les ressources de l'API sont simplement des flux conditionnels qui évaluent le chemin d'accès URI de la requête entrante. (La variable "proxy.pathsuffix" identifie l'URI de la requête qui suit le chemin "BasePath" configuré dans la configuration "ProxyEndpoint".)
Chaque ressource d'API que vous définissez est mise en œuvre par un flux conditionnel dans le proxy d'API. (Consultez la section Configurer les flux.)
Une fois que vous avez déployé le proxy d'API dans l'environnement de test, la requête suivante :
http://{org_name}-test.apigee.net/{proxy_path}/apps
provoquera l'évaluation de la condition à "true", et ce flux, ainsi que toutes les règles associées, seront exécutés.
L'exemple de condition suivant utilise une expression régulière Java pour reconnaître les appels passés à la ressource /apps
avec ou sans barre oblique finale (/apps
ou /apps/**
) :
<Condition>(proxy.pathsuffix JavaRegex "/apps(/?)") and (request.verb = "POST")</Condition>
Pour en savoir plus sur ce type de condition, consultez la section Comment effectuer une correspondance avec ou sans "/" de fin ... dans la communauté Apigee.
Modéliser des URI hiérarchiques
Dans certains cas, vous aurez des ressources d'API hiérarchiques. Par exemple, l'API Developer Services permet de répertorier toutes les applications appartenant à un développeur. Le chemin de l'URI est le suivant :
/developers/{developer_email}/apps
Il peut arriver que des ressources à identifiant unique soient générées pour chaque entité d'une collection, qui est parfois annotée comme suit :
/genus/:id/species
Ce chemin d'accès s'applique également aux deux URI suivants :
/genus/18904/species /genus/17908/species
Pour représenter cette structure dans une ressource d'API, vous pouvez utiliser des caractères génériques. Exemple :
/developers/*/apps
/developers/*example.com/apps
/genus/*/species
résoudra ces URI hiérarchiques en tant que ressources d'API en conséquence.
Dans certains cas, en particulier pour les API profondément hiérarchiques, vous pouvez simplement résoudre toutes les ressources sous un certain fragment d'URI. Pour ce faire, utilisez un caractère générique à deux astérisques dans votre définition de ressource. Par exemple, si vous définissez la ressource d'API suivante :/developers/**
Cette ressource d'API résout les chemins d'accès URI suivants :
/developers/{developer_email}/apps /developers/{developer_email}/keys /developers/{developer_email}/apps/{app_id}/keys
Voici à quoi ressemblerait la condition de flux conditionnelle dans la définition du proxy d'API :
<Condition>(proxy.pathsuffix MatchesPath "/developers/**") and (request.verb = "POST")</Condition>
Autres exemples
Condition associée à "RouteRule"
<RouteRule name="default">
<!--this routing executes if the header indicates that this is an XML call. If true, the call is routed to the endpoint XMLTargetEndpoint-->
<Condition>request.header.content-type = "text/xml"</Condition>
<TargetEndpoint>XmlTargetEndpoint</TargetEndpoint>
</RouteRule>
Condition associée à une stratégie
<Step> <!--the policy MaintenancePolicy only executes if the response status code is exactly 503--> <Condition>response.status.code = 503</Condition> <Name>MaintenancePolicy</Name> </Step>
Flux conditionnel
<!-- this entire flow is executed only if the request verb is a GET--> <Flow name="GetRequests"> <Condition>request.verb="GET"</Condition> <Request> <Step> <!-- this policy only executes if request path includes a term like statues--> <Condition>request.path ~ "/statuses/**"</Condition> <Name>StatusesRequestPolicy</Name> </Step> </Request> <Response> <Step> <!-- this condition has multiple expressions. The policy executes if the response code status is exactly 503 or 400--> <Condition>(response.status.code = 503) or (response.status.code = 400)</Condition> <Name>MaintenancePolicy</Name> </Step> </Response> </Flow>
Exemples d'opérateurs dans les conditions
Voici quelques exemples d'opérateurs utilisés pour créer des conditions :
request.header.content-type = "text/xml"
request.header.content-length < 4096 && request.verb = "PUT"
response.status.code = 404 || response.status.code = 500
request.uri MatchesPath "/*/statuses/**"
request.queryparam.q0 NotEquals 10
Exemple pratique : ignorer "/" à la fin d'un chemin d'accès
Les développeurs Edge souhaitent généralement gérer les deux suffixes de chemin d'accès suivants: "/cat
" et "/cat/
". En effet, certains utilisateurs ou clients peuvent appeler votre API avec une barre oblique supplémentaire à la fin du chemin d'accès, ce que vous devez être en mesure de gérer dans vos instructions conditionnelles. Ce cas d'utilisation précis a été abordé par la communauté Apigee.
Vous pouvez le faire sans utiliser d'expression régulière de la manière suivante :
<PreFlow name="PreFlow"> <Request> <Step> <Condition>((proxy.pathsuffix = "/cat") OR (proxy.pathsuffix = "/cat/")</Condition> <Name>SomePolicy</Name> </Step> </Request> <Response/> </PreFlow>
Cette option est intéressante. Elle est claire et lisible.
Vous pouvez faire la même chose avec les expressions régulières. Les parenthèses servent à regrouper la partie expression régulière de l'instruction, mais elles ne sont pas obligatoires.
<Condition>(proxy.pathsuffix JavaRegex "/cat(/?)"</Condition>
Appels d'API :
GET http://artomatic-test.apigee.net/matchtest/cat
or GET http://artomatic-test.apigee.net/matchtest/cat
/
La règle s'exécute-t-elle ? Oui. Notez que dans une expression régulière, le caractère "?
" signifie: faire correspondre à zéro ou l'un des caractères précédents. Par conséquent, /cat
et /cat/
sont des correspondances.
Appel d'API :
GET http://artomatic-test.apigee.net/matchtest/cat/spotted
La règle s'exécute-t-elle ? Non. L'expression régulière correspond à zéro ou une seule occurrence du caractère qui précède, et rien d'autre n'est autorisé.
Mise en correspondance des chaînes arbitraires avec "JavaRegex"
Dans tous les exemples de cette rubrique, nous expliquons comment mettre en correspondance l'une des variables de flux intégrées : "proxy.pathsuffix". Bon à savoir : vous pouvez effectuer une correspondance de modèle sur n'importe quelle chaîne ou variable de flux arbitraire, qu'il s'agisse ou non d'une variable de flux intégrée telle que "proxy.pathsuffix".
Par exemple, si vous avez une condition qui teste une chaîne arbitraire, éventuellement une chaîne renvoyée dans une charge utile du backend, ou une chaîne renvoyée par une recherche de serveur d'authentification, vous pouvez utiliser des opérateurs correspondants pour la tester. Si vous utilisez JavaRegex, l'expression régulière est comparée à l'ensemble de la chaîne d'objet. Si l'objet est "abc" et que l'expression régulière est "[a-z]", il n'y a pas de correspondance, car "[a-z]" correspond exactement à un caractère alphanumérique. L'expression "[a-z]+" fonctionne, tout comme "[a-z]*" et "[a-z]{3}".
Examinons un exemple concret. Supposons que le serveur d'authentification renvoie une liste de rôles sous forme de chaîne délimitée par des virgules: "éditeur, auteur, invité".
Pour tester la présence du rôle d'éditeur, cette structure ne fonctionnera pas, car "editor" ne fait partie que de la chaîne entière.
<Condition>returned_roles ~~ "editor"</Condition>
Toutefois, cette structure fonctionnera :
<Condition>returned_roles ~~ ".*\beditor\b.*")</Condition>
Cela fonctionne, car elle tient compte des espaces entre les mots et de toute autre partie de la chaîne comportant le préfixe et le suffixe ".*".
Dans cet exemple, vous pouvez également tester le terme "editor" à l'aide de l'opérateur "Matches" :
<Condition>returned_roles ~~ "*editor*")</Condition>
Toutefois, si vous avez besoin d'une plus grande précision, "JavaRegex" est souvent mieux adapté.
Échapper les guillemets doubles dans les expressions JavaRegex
La syntaxe de la condition nécessite qu'une expression JavaRegex soit placée entre guillemets doubles. Par conséquent, si vous disposez d'une expression régulière incluant des guillemets doubles, vous avez besoin d'une autre méthode pour les faire correspondre. La réponse est Unicode. Par exemple, disons que vous transmettez dans un en-tête contenant des guillemets doubles, comme suit :-H 'content-type:multipart/related; type="application/xop+xml"'Si vous essayez de faire correspondre cet en-tête à une condition d'expression régulière, vous obtiendrez une erreur de condition non valide, car l'expression inclut les guillemets doubles :
request.header.Content-Type ~~ "(multipart\/related)(; *type="application\/xop\+xml\")"La solution consiste à remplacer les guillemets doubles ASCII par leur équivalent Unicode,
\u0022
. Par exemple, l'expression suivante est valide et produit le résultat attendu :
request.header.Content-Type ~~ "(multipart\/related)(; *type=\u0022application\/xop\+xml\u0022)"