Utiliser la composition de règles

Vous consultez la documentation d'Apigee Edge.
Consultez la documentation Apigee X.
en savoir plus

Dans cet article, vous allez apprendre à créer une application composite à l'aide de la composition de règles. La composition de règles est un modèle de proxy Apigee qui vous permet de combiner les résultats de plusieurs cibles de backend en une seule réponse à l'aide de règles.

Pour une présentation générale de la composition des règles, consultez "Le modèle de composition des règles" dans Modèles de livre de recettes proxy d'API.

Télécharger et tester l'exemple de code

À propos de cet exemple de livre de recettes

Cet exemple de livre de recettes illustre un modèle de proxy d'API appelé composition de règles. Ce modèle offre une méthode (il en existe d'autres) pour combiner les données provenant de plusieurs sources backend. Plus généralement, cette rubrique montre comment combiner et enchaîner des règles pour produire le résultat souhaité. Pour une présentation générale de ce modèle et d'autres modèles associés, consultez la section Modèles de livre de recettes de proxy d'API.

L'exemple décrit ici utilise la composition de règles pour combiner les données de ces deux API publiques distinctes:

  • API Google Geocoding: cette API convertit des adresses (par exemple, "1600 Amphitheatre Parkway, Mountain View, CA") en coordonnées géographiques (comme latitude 37.423021 et longitude -122.083739).
  • API Google Elevation : cette API fournit une interface simple permettant d'interroger des emplacements sur Terre pour obtenir des données d'altitude. Dans cet exemple, les coordonnées renvoyées par l'API Geocoding seront utilisées en tant qu'entrées dans cette API.

Les développeurs d'applications appelleront ce proxy d'API avec deux paramètres de requête, un code postal et un ID de pays:

$ curl "http://{myorg}-test.apigee.net/policy-mashup-cookbook?country=us&postalcode=08008"

La réponse est un objet JSON qui inclut la position géocodée (latitude/longitude) du centre de la zone de code postal fournie, ainsi que l'altitude à ce point géographique géocodé.

{  
   "ElevationResponse":{  
      "status":"OK",
      "result":{  
         "location":{  
            "lat":"39.7500713",
            "lng":"-74.1357407"
         },
         "elevation":"0.5045232",
         "resolution":"76.3516159"
      }
   }
}

Avant de commencer

Si vous souhaitez lire un bref aperçu du schéma de composition de règles, consultez la section "Modèle de composition de stratégie " dans Modèles de livre de recettes proxy d'API.

Avant d'explorer cet exemple de livre de recettes, vous devez également connaître ces concepts fondamentaux:

  • en quoi consistent les règles et comment les associer aux proxys ; Pour une bonne présentation des règles, consultez la section Qu'est-ce qu'une règle ?.
  • La structure d'un flux de proxy d'API, comme expliqué dans la section Configurer des flux Les flux vous permettent de spécifier la séquence dans laquelle les stratégies sont exécutées par un proxy d'API. Dans cet exemple, plusieurs règles sont créées et ajoutées au flux du proxy d'API.
  • Organisation d'un projet de proxy d'API sur votre système de fichiers, comme expliqué dans la documentation de référence sur la configuration des proxys d'API. Cette rubrique de ce livre de recettes présente le développement local (basé sur un système de fichiers) par opposition au développement basé sur le cloud, où vous pouvez utiliser l'interface utilisateur de gestion pour développer le proxy d'API.
  • Utilisation de la validation des clés API Il s'agit de la forme la plus simple de sécurité basée sur les applications que vous pouvez configurer pour une API. Pour en savoir plus, consultez la page Clés API. Vous pouvez également suivre le tutoriel Sécuriser une API en nécessitant des clés API.
  • Avoir une connaissance pratique du langage XML. Dans cet exemple, nous créons le proxy d'API et ses règles à l'aide de fichiers XML qui résident sur le système de fichiers.

Si vous avez téléchargé l'exemple de code, vous pouvez localiser tous les fichiers abordés dans cet article dans le dossier d'exemple mashup-policy-cookbook. Les sections suivantes décrivent l'exemple de code en détail.

Suivre le flux

Avant de passer aux règles, examinons le flux principal de notre exemple de proxy d'API. Le flux XML, illustré ci-dessous, nous en dit beaucoup sur ce proxy, les règles qu'il utilise et l'endroit où ces règles sont appelées.

Dans l'exemple de téléchargement, ce fichier XML se trouve dans le fichier doc-samples/policy-mashup-cookbook/apiproxy/proxies/default.xml.

<ProxyEndpoint name="default">
  <Flows>
    <Flow name="default">
      <Request>
            <!-- Generate request message for the Google Geocoding API -->
            <Step><Name>GenerateGeocodingRequest</Name></Step>
            <!-- Call the Google Geocoding API -->
            <Step><Name>ExecuteGeocodingRequest</Name></Step>
            <!-- Parse the response and set variables -->
            <Step><Name>ParseGeocodingResponse</Name></Step>
            <!-- Generate request message for the Google Elevation API -->
            <Step><Name>AssignElevationParameters</Name></Step>
      </Request>
      <Response>
            <!-- Parse the response message from the Elevation API -->
            <Step><Name>ParseElevationResponse</Name></Step>
            <!-- Generate the final JSON-formatted response with JavaScript -->
            <Step><Name>GenerateResponse</Name></Step>
      </Response>
    </Flow>
  </Flows>

  <HTTPProxyConnection>
    <!-- Add a base path to the ProxyEndpoint for URI pattern matching-->
    <BasePath>/policy-mashup-cookbook</BasePath>
    <!-- Listen on both HTTP and HTTPS endpoints -->
    <VirtualHost>default</VirtualHost>
    <VirtualHost>secure</VirtualHost>
  </HTTPProxyConnection>
  <RouteRule name="default">
    <!-- Connect ProxyEndpoint to named TargetEndpoint under /targets -->
    <TargetEndpoint>default</TargetEndpoint>
  </RouteRule>
</ProxyEndpoint>

Voici un résumé des éléments du flux.

  • <Request> : l'élément <Request> se compose de plusieurs éléments <Step>. Chaque étape appelle l'une des règles que nous allons créer dans la suite de cet article. Ces règles concernent la création d'un message de requête, son envoi et l'analyse de la réponse. À la fin de cette section, vous comprendrez le rôle de chacune de ces stratégies.
  • <Response> : l'élément <Response> inclut également <Steps>. Ces étapes appellent également les stratégies responsables du traitement de la réponse finale à partir du point de terminaison cible (l'API Google Elevation).
  • <HttpProxyConnection> - Cet élément spécifie les détails de la manière dont les applications se connecteront à ce proxy d'API, y compris <BasePath>, qui spécifie comment cette API sera appelée.
  • <RouteRule> : cet élément spécifie ce qui se passe immédiatement après le traitement des messages de requête entrants. Dans ce cas, TargetEndpoint est appelé. Nous évoquerons cette étape importante plus loin dans cette rubrique.

Créer les règles

Les sections suivantes décrivent chacune des règles composant cet exemple de composition de règles.

Créer la première règle "AssignMessage"

La première règle AssignMessage, répertoriée ci-dessous, crée un message de requête qui sera envoyé au service Google Geocoding.

Commençons par le code de la stratégie, puis nous expliquerons plus en détail ses éléments. Dans l'exemple de téléchargement, ce fichier XML se trouve dans le fichier doc-samples/policy-mashup-cookbook/apiproxy/policies/GenerateGeocodingRequest.xml.

<AssignMessage name="GenerateGeocodingRequest">
  <AssignTo createNew="true" type="request">GeocodingRequest</AssignTo>
  <Set>
    <QueryParams>
      <QueryParam name="address">{request.queryparam.postalcode}</QueryParam>
      <QueryParam name="region">{request.queryparam.country}</QueryParam>
      <QueryParam name="sensor">false</QueryParam>
    </QueryParams>
    <Verb>GET</Verb>
  </Set>
  <!-- Set variables for use in the final response -->
  <AssignVariable>
    <Name>PostalCode</Name>
    <Ref>request.queryparam.postalcode</Ref>
  </AssignVariable>
  <AssignVariable>
    <Name>Country</Name>
    <Ref>request.queryparam.country</Ref>
  </AssignVariable>
</AssignMessage>

Voici une brève description des éléments de ces règles. Pour en savoir plus sur cette règle, consultez la section Attribuer une règle de message.

  • <AssignMessage name> : attribue un nom à cette règle. Ce nom est utilisé lorsque la règle est référencée dans un flux.
  • <AssignTo> : crée une variable nommée appelée GeocodingRequest. Cette variable encapsule l'objet de requête qui sera envoyé au backend par la règle ServiceCallout.
  • <QueryParams> : définit les paramètres de requête nécessaires à l'appel d'API backend. Dans ce cas, l'API Geocoding doit connaître le lieu, qui est exprimé à l'aide d'un code postal et d'un ID de pays. L'utilisateur de l'application fournit ces informations, et nous les extrayons simplement ici. Le paramètre sensor est requis par l'API. Sa valeur est "true" ou "false", et nous le coderons en dur sur "false".
  • <Verb> : dans ce cas, nous envoyons une requête GET simple à l'API.
  • <AssignVariable> - Ces variables stockent les valeurs que nous transmettons à l'API. Dans cet exemple, les variables sont accessibles ultérieurement dans la réponse renvoyée au client.

Envoyer la requête avec ServiceAppel

L'étape suivante de la séquence de composition de règles consiste à créer une règle ServiceCallout. La règle ServiceCallout, listée ci-dessous, envoie l'objet de requête que nous avons créé dans la règleAssignMessage précédente au service Google Geocoding et enregistre le résultat dans une variable appelée GeocodingResponse.

Comme précédemment, examinons d'abord le code. Vous trouverez ci-après une explication détaillée. Pour en savoir plus sur cette règle, consultez la section Règle relative aux appels de service. Dans l'exemple de téléchargement, ce fichier XML se trouve dans le fichier doc-samples/policy-mashup-cookbook/apiproxy/policies/ExecuteGeocodingRequest.xml.

<ServiceCallout name="ExecuteGeocodingRequest">
  <Request variable="GeocodingRequest"/>
  <Response>GeocodingResponse</Response>
  <HTTPTargetConnection>
    <URL>http://maps.googleapis.com/maps/api/geocode/json</URL>
  </HTTPTargetConnection>
</ServiceCallout>

Voici une brève description des éléments de ces règles.

  • <ServiceCallout> : comme la règle précédente, celle-ci a un nom.
  • <Request variable> : il s'agit de la variable créée dans la règle "AssignMessage". Il encapsule la requête envoyée à l'API backend.
  • <Response> : cet élément nomme une variable dans laquelle la réponse est stockée. Comme vous le verrez, la règle ExtractVariables permettra ultérieurement d'accéder à cette variable.
  • <HTTPTargetConnection> : spécifie l'URL cible de l'API backend. Dans ce cas, nous indiquons que l'API renvoie une réponse JSON.

Nous avons maintenant deux règles, la première qui spécifie les informations de requête nécessaires pour utiliser l'API backend (API Geocoding de Google) et la seconde qui envoie réellement la requête à l'API backend. Nous allons maintenant gérer la réponse.

Analyser la réponse avec ExtractVariables

La règle ExtractVariables fournit un mécanisme simple pour analyser le contenu du message de réponse obtenu par une règle ServiceAppel. La classe ExtractVariables peut être utilisée pour analyser des fichiers JSON ou XML, ou pour extraire du contenu des chemins d'URI, des en-têtes HTTP, des paramètres de requête et des paramètres de formulaire.

Voici une liste des règles ExtractVariables. Pour en savoir plus sur cette règle, consultez la section Règle d'extraction de variables. Dans l'exemple de téléchargement, ce fichier XML se trouve dans le fichier doc-samples/policy-mashup-cookbook/apiproxy/policies/ParseGeocodingResponse.xml.

<ExtractVariables name="ParseGeocodingResponse">
  <Source>GeocodingResponse</Source>
  <VariablePrefix>geocoderesponse</VariablePrefix>
  <JSONPayload>
    <Variable name="latitude">
       <JSONPath>$.results[0].geometry.location.lat</JSONPath>
    </Variable>
    <Variable name="longitude">
       <JSONPath>$.results[0].geometry.location.lng</JSONPath>
    </Variable>
  </JSONPayload>
</ExtractVariables>

Les éléments clés de la règle ExtractVariable sont les suivants:

  • <ExtractVariables name> : encore une fois, le nom de la règle est utilisé pour faire référence à la règle lorsqu'elle est utilisée dans un flux.
  • <Source> : spécifie la variable de réponse que nous avons créée dans la règle ServiceCallout. Il s'agit de la variable à partir de laquelle la règle extrait les données.
  • <VariablePrefix> - Le préfixe de variable spécifie un espace de noms pour les autres variables créées dans cette règle. Le préfixe peut être n'importe quel nom, à l'exception des noms réservés définis par les variables prédéfinies de Edge.
  • <JSONPayload> : cet élément récupère les données de réponse qui nous intéressent et les place dans des variables nommées. En fait, l'API Geocoding renvoie beaucoup plus d'informations que la latitude et la longitude. Cependant, ce sont les seules valeurs dont nous avons besoin pour cet exemple. Pour voir le rendu complet du fichier JSON renvoyé par l'API Geocoding, consultez la documentation de l'API. Les valeurs de geometry.location.lat et geometry.location.lng ne sont que deux des nombreux champs de l'objet JSON renvoyé.

Bien que cela ne soit pas évident, il est important de constater qu'ExtractVariables produit deux variables dont les noms se composent du préfixe de la variable (geocoderesponse) et des noms de variables réels spécifiés dans la règle. Ces variables sont stockées dans le proxy d'API et seront disponibles pour d'autres règles dans le flux de proxy, comme vous le verrez. Les variables sont les suivantes:

  • geocoderesponse.latitude
  • geocoderesponse.longitude

La majeure partie du travail est maintenant terminée. Nous avons créé un composite de trois règles qui forment une requête, appellent une API backend et analysent les données JSON renvoyées. Au cours des dernières étapes, nous allons transmettre les données de cette partie du flux à une autre règleAssignMessage, appeler la deuxième API backend (API Google Elevation) et renvoyer nos données combinées au développeur de l'application.

Générer la deuxième requête avec "AssignMessage"

La règle "AssignMessage" suivante utilise des variables renvoyées par le premier backend (Google Geocoding) que nous avons stocké et les intègre dans une requête destinée à la deuxième API (Google Elevation). Comme indiqué précédemment, ces variables sont geocoderesponse.latitude et geocoderesponse.longitude.

Dans l'exemple de téléchargement, ce fichier XML se trouve dans le fichier doc-samples/policy-mashup-cookbook/apiproxy/policies/AssignElevationParameters.xml.

<AssignMessage name="AssignElevationParameters">
<Remove>
    <QueryParams>
      <QueryParam name="country"/>
      <QueryParam name="postalcode"/>
    </QueryParams>
  </Remove>
  <Set>
    <QueryParams>
      <QueryParam name="locations">{geocoderesponse.latitude},{geocoderesponse.longitude}</QueryParam>
      <QueryParam name="sensor">false</QueryParam>
    </QueryParams>
  </Set>
</AssignMessage>

Si vous examinez l'API Google Elevation, vous constaterez qu'elle nécessite deux paramètres de requête. La première s'appelle locations et sa valeur est la latitude et la longitude (valeurs séparées par une virgule). L'autre paramètre est sensor, qui est obligatoire et doit avoir la valeur "true" ou "false". La chose la plus importante à noter à ce stade est que le message de requête que nous créons ici ne nécessite pas d'Appel de service. À ce stade, il n'est pas nécessaire d'appeler la deuxième API à partir d'un ServiceCallout, car nous pouvons appeler l'API backend à partir du TargetEndpoint du proxy. Si vous y réfléchissez, nous disposons de toutes les données dont nous avons besoin pour appeler l'API Google Elevations. Le message de requête généré à cette étape ne nécessite pas d'objet ServiceCallout, car la requête générée pour le pipeline de requêtes principal sera simplement transférée par ProxyEndpoint à TargetEndpoint, selon la règle RouteRule configurée pour ce proxy d'API. TargetEndpoint gère la connexion avec l'API distante. (Rappelez-vous que l'URL de l'API d'élévation est définie dans la classe HTTPConnection du point de terminaison cible. la documentation de l'API Elevation si vous souhaitez en savoir plus. Les QueryParams que nous avons stockés précédemment, country et postalcode, ne sont plus nécessaires. Nous les supprimons donc ici.

Brève pause: retour au flux

À ce stade, vous vous demandez peut-être pourquoi nous ne créons pas d'autres règles ServiceCall. Après tout, nous avons créé un autre message. Comment ce message est-il envoyé à la cible, l'API Google Elevation ? La réponse se trouve dans l'élément <RouteRule> du flux. <RouteRule> spécifie ce qu'il faut faire avec les messages de requête restants après l'exécution de la partie <Request> du flux. Le TargetEndpoint spécifié par cette <RouteRule> indique au proxy d'API de distribuer le message à http://maps.googleapis.com/maps/api/elevation/xml.

Si vous avez téléchargé l'exemple de proxy d'API, vous trouverez le fichier XML TargetProxy dans le fichier doc-samples/policy-mashup-cookbook/apiproxy/targets/default.xml.

<TargetEndpoint name="default">
  <HTTPTargetConnection>
    <!-- This is where we define the target. For this sample we just use a simple URL. -->
    <URL>http://maps.googleapis.com/maps/api/elevation/xml</URL>
  </HTTPTargetConnection>
</TargetEndpoint>

Il ne nous reste plus qu'à traiter la réponse de l'API Google Elevation, puis nous avons terminé.

Convertir la réponse XML en JSON

Dans cet exemple, la réponse de l'API Google Elevation est renvoyée au format XML. Pour une "crédit supplémentaire", ajoutons une autre règle à notre composite afin de transformer la réponse XML en JSON.

Cet exemple utilise la stratégie JavaScript nommée GenerateResponse, avec un fichier de ressources contenant le code JavaScript, pour effectuer la conversion. Vous trouverez ci-dessous la définition de la stratégie GenerateResponse:

<Javascript name="GenerateResponse" timeout="10000">
  <ResourceURL>jsc://GenerateResponse.js</ResourceURL>
</Javascript>

Le fichier de ressources GenerateResponse.js inclut le code JavaScript utilisé pour effectuer la conversion. Vous pouvez voir ce code dans le fichier doc-samples/policy-mashup-cookbook/apiproxy/resources/JSC/GenerateResponse.js.

Apigee fournit également une règle prête à l'emploi, XMLToJSON, pour convertir des fichiers XML en JSON. Vous pouvez modifier le point de terminaison ProxyEndpoint pour utiliser à la place la règle xmltojson indiquée ci-dessous.

<XMLToJSON name="xmltojson">
  <Options>
  </Options>
  <OutputVariable>response</OutputVariable>
  <Source>response</Source>
</XMLToJSON>

Tester l'exemple

Si vous ne l'avez pas déjà fait, essayez de télécharger, de déployer et d'exécuter l'exemple policy-mashup-cookbook, que vous trouverez dans le dossier doc-samples dans le dépôt d'exemples Apigee Edge sur GitHub. Il vous suffit de suivre les instructions du fichier README du dossier "policy-mashup-cookbook". Vous pouvez également suivre les brèves instructions de la section Utiliser les exemples de proxys d'API.

Pour résumer, vous pouvez appeler l'API composite comme suit. Remplacez {myorg} par le nom de votre organisation:

$ curl "http://{myorg}-test.apigee.net/policy-mashup-cookbook?country=us&postalcode=08008"

La réponse inclut la position géocodée pour le centre du code postal fourni par l'utilisateur final de l'application, combinée à l'altitude à cette position géocodée. Les données ont été extraites de deux API backend, fusionnées avec les stratégies associées au proxy d'API, puis renvoyées au client en une seule réponse.

{  
   "country":"us",
   "postalcode":"08008",
   "elevation":{  
      "meters":0.5045232,
      "feet":1.6552599030345978
   },
   "location":{  
      "latitude":39.75007129999999,
      "longitude":-74.1357407
   }
}

Résumé

Cette rubrique de ce livre de recettes explique comment utiliser le modèle de composition de règles pour créer un mélange de données provenant de plusieurs sources backend. La composition de règles est un modèle courant utilisé dans le développement de proxys d'API pour ajouter des fonctionnalités de création à votre API.