Usa la composición de políticas

Estás consultando la documentación de Apigee Edge.
Consulta la documentación de Apigee X.
Información

En este tema, aprenderás a crear una mashup mediante la composición de políticas. La composición de políticas es un patrón de proxy de Apigee que te permite combinar resultados de varios objetivos de backend en una sola respuesta mediante políticas.

Para obtener una descripción general de la composición de la política, consulta “El patrón de composición de políticas” en Patrones de la guía de soluciones del proxy de la API.

Descarga y prueba el código de muestra

Acerca de este ejemplo de libro de recetas

En este ejemplo de la guía de soluciones, se ilustra un patrón de proxy de API llamado composición de políticas. Este patrón proporciona una forma (hay otras) de combinar datos de varias fuentes de backend. En términos más generales, en este tema se demuestra cómo las políticas se pueden combinar y encadenar para producir un resultado deseado. Para obtener una descripción general de este patrón y otros relacionados, consulta Patrones de la guía de soluciones del proxy de API.

En el ejemplo que se analiza aquí, se usa la composición de políticas para combinar datos de estas dos APIs públicas distintas:

  • API de Google Geocoding: Esta API convierte direcciones (como "1600 Amphitheatre Parkway, Mountain View, CA") en coordenadas geográficas (como latitud 37.423021 y longitud -122.083739).
  • API de Google Elevation: Esta API proporciona una interfaz simple para realizar consultas sobre ubicaciones de la Tierra y datos de elevación. En este ejemplo, las coordenadas que muestra la API de Geocoding se usarán como entrada en esta API.

Los desarrolladores de apps llamarán a este proxy de API con dos parámetros de consulta, un código postal y un ID de país:

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

La respuesta es un objeto JSON que incluye la ubicación geocodificada (latitud y longitud) del centro del área de código postal proporcionada, combinada con la elevación de esa ubicación geocodificada.

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

Antes de comenzar

Si deseas leer una breve descripción general del patrón de composición de políticas, consulta “Patrón de composición de políticas” en Patrones de la guía de soluciones del proxy de la API.

Antes de que explores este ejemplo de la guía de soluciones, también debes estar familiarizado con estos conceptos fundamentales:

  • Qué son las políticas y cómo adjuntarlas a los proxies Para obtener una buena introducción a las políticas, consulta ¿Qué es una política?.
  • La estructura de un flujo de proxy de API, como se explica en Configura flujos. Los flujos te permiten especificar la secuencia en la que un proxy de API ejecuta las políticas. En este ejemplo, se crean varias políticas y se agregan al flujo del proxy de la API.
  • Cómo se organiza un proyecto de proxy de API en el sistema de archivos, como se explica en la referencia de configuración de proxy de API. En este tema de la guía de soluciones, se muestra el desarrollo local (basado en el sistema de archivos) en comparación con el desarrollo basado en la nube, en el que podrías usar la IU de administración para desarrollar el proxy de API.
  • Uso de la validación de la clave de API Esta es la forma más simple de seguridad basada en apps que puedes configurar para una API. Para obtener más información, consulta Claves de API. También puedes revisar el instructivo Protege una API mediante la solicitud de claves de API.
  • Conocimiento práctico de XML En este ejemplo, compilamos el proxy de la API y sus políticas con archivos en formato XML que se encuentran en el sistema de archivos.

Si descargaste el código de muestra, puedes encontrar todos los archivos analizados en este tema en la carpeta de muestra mashup-policy-cookbook. En las siguientes secciones, se analiza el código de muestra en detalle.

Sigue la fluidez

Antes de pasar a las políticas, veamos el flujo principal de nuestro proxy de API de ejemplo. El XML de flujo, que se muestra a continuación, nos brinda mucha información sobre este proxy, las políticas que usa y el nombre de su nombre.

En la descarga de muestra, puedes encontrar este XML en el archivo 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>

Este es un resumen de los elementos del flujo.

  • <Request>: El elemento <Request> consta de varios elementos <Step>. En cada paso, se llama a una de las políticas que crearemos en el resto del tema. Estas políticas se relacionan con la creación de un mensaje de solicitud, su envío y el análisis de la respuesta. Al final de este tema, comprenderás la función de cada una de estas políticas.
  • <Response>: El elemento <Response> también incluye <Steps>. Estos pasos también llaman a las políticas que son responsables de procesar la respuesta final del extremo objetivo (la API de Google Elevation).
  • <HttpProxyConnection>: Este elemento especifica detalles sobre cómo se conectarán las apps a este proxy de API, incluido <BasePath>, que especifica cómo se llamará esta API.
  • <RouteRule>: Este elemento especifica lo que sucede inmediatamente después de que se procesan los mensajes de solicitud entrantes. En este caso, se llama a TargetEndpoint. Analizaremos más este paso importante más adelante en el tema.

Crea las políticas

En las siguientes secciones, se analiza cada una de las políticas que conforman este ejemplo de composición de políticas.

Crea la primera política de AssignMessage

La primera política AssignMessage que se indica a continuación crea un mensaje de solicitud que se enviará al servicio de Google Geocoding.

Comencemos con el código de la política y, luego, explicaremos sus elementos con más detalle. En la descarga de muestra, puedes encontrar este XML en el archivo 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>

A continuación, se incluye una breve descripción de los elementos de esta política. Puedes obtener más información sobre esta política en la política de Asignar mensajes.

  • <AssignMessage name>: Asigna un nombre a esta política. El nombre se usa cuando se hace referencia a la política en un flujo.
  • <AssignTo>: Crea una variable con nombre llamada GeocodingRequest. Esta variable encapsula el objeto de solicitud que enviará la política ServiceHighlight al backend.
  • <QueryParams>: establece los parámetros de consulta que necesita la llamada a la API de backend. En este caso, la API de Geocoding necesita conocer la ubicación, que se expresa con un código postal y un ID del país. El usuario de la app proporciona esta información, que simplemente debemos extraer aquí. La API requiere el parámetro sensor, que es verdadero o falso. Aquí solo se codifica como falso.
  • <Verb>: en este caso, realizaremos una solicitud GET simple a la API.
  • <AssignVariable>: Estas variables almacenan los valores que pasamos a la API. En este ejemplo, se accederá a las variables más adelante en la respuesta que se muestre al cliente.

Envía la solicitud con ServicePrompt

El siguiente paso en la secuencia de composición de la política es crear una política ServiceCallout. La política ServiceReferencia, que se indica a continuación, envía el objeto de solicitud que creamos en la política AssignMessage anterior al servicio Google Geocoding y guarda el resultado en una variable llamada GeocodingResponse.

Como antes, primero veamos el código. A continuación, se incluye una explicación detallada. Puedes obtener más información sobre esta política en la política de Service Featured. En la descarga de muestra, puedes encontrar este XML en el archivo 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>

A continuación, se incluye una breve descripción de los elementos de esta política.

  • <ServiceCallout>: Al igual que con la política anterior, esta tiene nombre.
  • <Variable de solicitud>: Esta es la variable que se creó en la políticaAssignMessage. Encapsula la solicitud que se dirige a la API de backend.
  • <Response>: Este elemento nombra una variable en la que se almacena la respuesta. Como verás, la política ExtractVariables accederá a esta variable más adelante.
  • <HTTPTargetConnection>: Especifica la URL de destino de la API de backend. En este caso, especificamos que la API muestre una respuesta JSON.

Ahora tenemos dos políticas: una que especifica la información de solicitud necesaria para usar la API de backend (API de Geocoding de Google) y la segunda que realmente envía la solicitud a la API de backend. A continuación, controlaremos la respuesta.

Analiza la respuesta con ExtractVariables

La política ExtractVariables proporciona un mecanismo simple para analizar el contenido del mensaje de respuesta obtenido por una política ServiceFeatured. ExtractVariables se puede usar para analizar JSON o XML, o bien para extraer contenido de rutas de URI, encabezados HTTP, parámetros de consulta y de formulario.

A continuación, se muestra una lista de la política ExtractVariables. Puedes obtener más información sobre esta política en la política de extracción de variables. En la descarga de muestra, puedes encontrar este XML en el archivo 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>

Los elementos clave de la política ExtractVariable son los siguientes:

  • <ExtractVariables name>: Nuevamente, el nombre de la política se usa para hacer referencia a la política cuando se usa en un flujo.
  • <Source>: Especifica la variable de respuesta que creamos en la política ServiceHighlight. Esta es la variable de la que esta política extrae los datos.
  • <VariablePrefix>: El prefijo de la variable especifica un espacio de nombres para otras variables creadas en esta política. El prefijo puede ser cualquier nombre, excepto los nombres reservados que definen las variables predefinidas de Edge.
  • <JSONPayload>: Este elemento recupera los datos de respuesta que nos interesan y los coloca en variables con nombre. De hecho, la API de Geocoding muestra mucha más información que la latitud y la longitud. Sin embargo, estos son los únicos valores que necesitamos para esta muestra. Puedes ver una renderización completa del JSON que muestra la API de Geocoding en la documentación de la API. Los valores de geomet.location.lat y energy.location.lng son simplemente dos de los numerosos campos en el objeto JSON que se muestra.

Puede que no sea evidente, pero es importante ver que ExtractVariables produce dos variables cuyos nombres constan del prefijo de la variable (georesponse) y los nombres reales de las variables que se especifican en la política. Estas variables se almacenan en el proxy de API y estarán disponibles para otras políticas dentro del flujo del proxy, como verás. Las variables son:

  • geocoderesponse.latitude
  • geocoderesponse.longitude

Ya terminamos la mayor parte del trabajo. Creamos un compuesto de tres políticas que forman una solicitud, llaman a una API de backend y analizan los datos JSON que se muestran. En los últimos pasos, incorporaremos los datos de esta parte del flujo a otra política deAssignMessage, llamaremos a la segunda API de backend (API de Google Elevation), y mostraremos la combinación de datos al desarrollador de la app.

Genera la segunda solicitud conAssignMessage

La siguiente política de OfferMessage usa variables que se muestran desde el primer backend (Google Geocoding) que almacenamos y las conecta a una solicitud dirigida a la segunda API (Google Elevation). Como se indicó anteriormente, estas variables son codingresponse.latitude y georesponse.longitude.

En la descarga de muestra, puedes encontrar este XML en el archivo 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 examinas la Google Elevation API, verás que toma dos parámetros de consulta. El primero se llama locations y su valor es la latitud y la longitud (valores separados por comas). El otro parámetro es sensor, que es obligatorio y debe ser verdadero o falso. Lo más importante que debes tener en cuenta en este punto es que el mensaje de solicitud que creamos aquí no requiere un ServiceReferencia. En este momento, no es necesario llamar a la segunda API desde un ServiceReferencia, ya que se puede llamar a la API de backend desde el TargetEndpoint del proxy. Si lo piensas, tenemos todos los datos que necesitamos para llamar a la API de Elevations de Google. El mensaje de solicitud generado en este paso no requiere un ServiceReferencia, ya que la solicitud generada para la canalización de la solicitud principal la reenviará el ProxyEndpoint al TargetEndpoint, siguiendo la RouteRule configurada para este proxy de API. TargetEndpoint administra la conexión con la API remota. (Recuerda que la URL de la API de Elevation se define en HTTPConnection para el TargetEndpoint. documentación de la API de Elevation si deseas obtener más información. Los QueryParams que almacenamos antes, country y postalcode, ya no son necesarios, por lo que los quitamos aquí.

Pausa breve: Vuelve al flujo

En este punto, es posible que se pregunte por qué no creamos otra política de ServiceReferencia. Después de todo, creamos otro mensaje. ¿Cómo se envía ese mensaje al destino, la API de Google Elevation? La respuesta está en el elemento <RouteRule> del flujo. <RouteRule> especifica qué hacer con los mensajes de solicitud restantes después de que se haya ejecutado la parte <Request> del flujo. El TargetEndpoint especificado por esta <RouteRule> le indica al proxy de API que entregue el mensaje a http://maps.googleapis.com/maps/api/elevation/xml.

Si descargaste el proxy de API de muestra, puedes encontrar el XML de TargetProxy en el archivo 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>

Ahora, solo necesitamos procesar la respuesta de la API de Elevation de Google y listo.

Convierte la respuesta de XML a JSON

En este ejemplo, la respuesta de la Google Elevation API se muestra en formato XML. Para obtener "crédito adicional", agregaremos una política más a nuestro compuesto para transformar la respuesta de XML a JSON.

En este ejemplo, se usa la política de JavaScript denominada GenerateResponse con un archivo de recursos que contiene el código JavaScript para realizar la conversión. A continuación, se muestra la definición de la política GenerateResponse:

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

El archivo de recursos GenerateResponse.js incluye el código JavaScript que se usa para realizar la conversión. Puedes ver ese código en el archivo doc-samples/policy-mashup-cookbook/apiproxy/resources/JSC/GenerateResponse.js.

Apigee también proporciona una política lista para usar, XMLToJSON, a fin de convertir de XML a JSON. Puedes editar el ProxyEndpoint para que use la política xmltojson que se muestra a continuación.

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

Prueba el ejemplo

Si aún no lo hiciste, intenta descargar, implementar y ejecutar el ejemplo policy-mashup-cookbook, que puedes encontrar en la carpeta doc-samples en el repositorio de muestras de Apigee Edge de GitHub. Solo sigue las instrucciones del archivo README en la carpeta policy-mashup-cookbook. También puedes seguir estas instrucciones breves: Cómo usar los proxies de API de muestra.

En resumen, puedes llamar a la API compuesta de la siguiente manera. Sustituye {myorg} por el nombre de tu organización:

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

En la respuesta, se incluye la ubicación geocodificada del centro del código postal que proporciona el usuario final de la app, combinada con la elevación de esa ubicación geocodificada. Los datos se recuperaron de dos API de backend, se combinaron con políticas adjuntas al proxy de API y se mostraron al cliente en una sola respuesta.

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

Resumen

En este tema de la guía de soluciones, se explicó cómo usar el patrón de composición de políticas para crear una mashup de datos de varias fuentes de backend. La composición de políticas es un patrón común que se usa en el desarrollo del proxy de API para agregar funciones de creatividades a la API.