Como usar a composição de política

Você está vendo a documentação do Apigee Edge.
Acesse a documentação da Apigee X.
informações

Neste tópico, você aprenderá a criar um mashup usando a composição da política. A composição da política é um padrão de proxy da Apigee que permite combinar os resultados de vários destinos de back-end em uma única resposta usando políticas.

Para ter uma visão geral da composição da política, consulte "Padrão de composição da política" em Padrões do manual de proxy da API.

Fazer o download e testar o exemplo de código

Sobre este exemplo de livro de receitas

Neste exemplo de manual, ilustramos um padrão de proxy de API chamado policy composition. Esse padrão fornece uma maneira (há outras) de misturar dados de várias origens de back-end. De modo mais geral, este tópico demonstra como as políticas podem ser combinadas e encadeadas para produzir um resultado pretendido. Para uma visão geral desse e outros padrões relacionados, consulte Padrões do manual de proxy de API.

O exemplo discutido aqui usa a composição de políticas para misturar dados dessas duas APIs públicas:

  • API Google Geocoding: essa API converte endereços (como "1600 Amphitheatre Parkway, Mountain View, CA") em coordenadas geográficas (como latitude 37.423021 e longitude -122.083739).
  • API Google Elevation: essa API oferece uma interface simples para consultar locais na Terra e receber dados de elevação. Neste exemplo, as coordenadas retornadas da API Geocoding são usadas como entrada para essa API.

Os desenvolvedores de apps vão chamar esse proxy de API com dois parâmetros de consulta, um CEP e um ID do país:

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

A resposta é um objeto JSON que inclui a localização geocodificada (latitude/longitude) para o centro da área do código postal fornecida, combinada com a elevação desse local geocodificado.

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

Antes de começar

Para ler uma breve visão geral do padrão de composição da política, consulte "O padrão de composição de políticas" em Padrões do manual de proxy de API.

Antes de ver este exemplo do livro de receitas, conheça estes conceitos fundamentais:

  • O que são políticas e como anexá-las a proxies. Para uma boa introdução a políticas, consulte O que é uma política?.
  • A estrutura de um fluxo de proxy de API, conforme explicado em Como configurar fluxos. Os fluxos permitem especificar a sequência em que as políticas são executadas por um proxy de API. Neste exemplo, várias políticas são criadas e adicionadas ao fluxo do proxy de API.
  • Como um projeto de proxy de API é organizado no seu sistema de arquivos, conforme explicado na Referência de configuração de proxy de API. Este tópico do manual demonstra o desenvolvimento local (baseado em sistema de arquivos) em vez do desenvolvimento baseado na nuvem, em que é possível usar a interface de gerenciamento para desenvolver o proxy de API.
  • Uso de validação da chave de API. Essa é a forma mais simples de segurança baseada em apps que pode ser configurada para uma API. Para mais informações, consulte Chaves de API. Também é possível consultar o tutorial Proteger uma API exigindo chaves de API.
  • Conhecimento prático de XML. Neste exemplo, criamos o proxy de API e as políticas dele com arquivos XML que residem no sistema de arquivos.

Se você fez o download do exemplo de código, pode localizar todos os arquivos discutidos neste tópico na pasta de exemplo mashup-policy-cookbook. As seções a seguir abordam o exemplo de código em detalhes.

Siga o fluxo

Antes de passar para as políticas, vamos dar uma olhada no fluxo principal do nosso exemplo de proxy de API. O XML de fluxo, mostrado abaixo, nos informa muito sobre esse proxy, as políticas que ele usa e onde elas são chamadas.

No download do exemplo, você pode encontrar esse XML no arquivo 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>

Veja um resumo dos elementos do fluxo.

  • <Request>: o elemento <Request> consiste em vários elementos <Step>. Cada etapa chama uma das políticas que vamos criar no restante deste tópico. Essas políticas estão relacionadas à criação de uma mensagem de solicitação, ao envio dela e à análise da resposta. Ao final deste tópico, você entenderá o papel de cada uma dessas políticas.
  • <Response>: o elemento <Response> também inclui <Steps>. Essas etapas também chamam políticas responsáveis pelo processamento da resposta final do endpoint de destino (a API Google Elevation).
  • <HttpProxyConnection>: este elemento especifica detalhes sobre como os apps se conectarão a esse proxy de API, incluindo <BasePath>, que especifica como essa API será chamada.
  • <RouteRule>: esse elemento especifica o que acontece imediatamente após o processamento das mensagens de solicitação recebidas. Nesse caso, o TargetEndpoint é chamado. Falaremos mais sobre essa etapa importante mais adiante neste tópico.

Como criar as políticas

As seções a seguir discutem cada uma das políticas que compõem este exemplo de composição da política.

Criar a primeira políticaAssignMessage

A primeira política AssignMessage, listada abaixo, cria uma mensagem de solicitação que é enviada ao serviço de geocodificação do Google.

Vamos começar com o código da política e depois explicar os elementos dele com mais detalhes. No download do exemplo, você pode encontrar esse XML no arquivo 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>

Veja uma breve descrição dos elementos dessa política. Leia mais sobre essa política em Atribuir política de mensagem.

  • <AssignMessage name>: dá um nome a essa política. O nome é usado quando a política é referenciada em um fluxo.
  • <AssignTo>: cria uma variável nomeada chamada GeocodingRequest. Essa variável encapsula o objeto de solicitação que será enviado ao back-end pela política Service callout.
  • <QueryParams>: define os parâmetros de consulta necessários para a chamada de API do back-end. Nesse caso, a API Geocoding precisa saber o local, que é expresso com um código postal e um ID de país. O usuário do app fornece essas informações, e elas são extraídas aqui. O parâmetro sensor é exigido pela API e é verdadeiro ou falso, e nós apenas o fixamos no código como falso aqui.
  • <Verb>: nesse caso, estamos fazendo uma solicitação GET simples para a API.
  • <AssignVariable>: armazena os valores que estamos transmitindo à API. Neste exemplo, as variáveis serão acessadas posteriormente na resposta retornada ao cliente.

Enviar a solicitação com Service callout

A próxima etapa na sequência de composição da política é criar uma política ServiceCallout. A política Service callout, listada abaixo, envia o objeto de solicitação que criamos na política AttributionMessage anterior para o serviço de geocodificação do Google e salva o resultado em uma variável chamada GeocodingResponse.

Como antes, primeiro vamos analisar o código. Veja a seguir uma explicação detalhada. Saiba mais sobre essa política em Política de frases de destaque de serviço. No download do exemplo, você pode encontrar esse XML no arquivo 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>

Veja uma breve descrição dos elementos dessa política.

  • <ServiceCallout>: assim como a política anterior, essa tem um nome.
  • <Request variables>: é a variável criada na política AttributionMessage. Ele encapsula a solicitação enviada para a API de back-end.
  • <Response>: esse elemento nomeia uma variável na qual a resposta é armazenada. Como você verá, essa variável será acessada posteriormente pela política ExtractVariables.
  • <HTTPTargetConnection>: especifica o URL de destino da API de back-end. Nesse caso, especificamos que a API retorne uma resposta JSON.

Agora temos duas políticas: uma que especifica as informações de solicitação necessárias para usar a API de back-end (API Geocoding do Google) e a segunda que realmente envia a solicitação para a API de back-end. Em seguida, lidaremos com a resposta.

Analisar a resposta com ExtractVariables

A política ExtractVariables oferece um mecanismo simples para analisar o conteúdo da mensagem de resposta recebida por uma política Service callout. O ExtractVariables pode ser usado para analisar JSON ou XML ou para extrair conteúdo de caminhos de URI, cabeçalhos HTTP, parâmetros de consulta e de formulário.

Confira uma lista da política ExtractVariables. Leia mais sobre essa política em Política de extração de variáveis. No download do exemplo, você pode encontrar esse XML no arquivo 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>

Os principais elementos da política ExtractVariable são:

  • <ExtractVariables name>: mais uma vez, o nome da política é usado para se referir à política quando usada em um fluxo.
  • <Source>: especifica a variável de resposta que criamos na política Service callout. É a variável da qual a política extrai dados.
  • <VariablePrefix>: o prefixo da variável especifica um namespace para outras variáveis criadas nessa política. O prefixo pode ser qualquer nome, exceto os nomes reservados definidos pelas variáveis predefinidas do Edge.
  • <JSONPayload>: este elemento recupera os dados de resposta que nos interessam e os coloca em variáveis nomeadas. Na verdade, a API Geocoding retorna muito mais informações do que latitude e longitude. No entanto, esses são os únicos valores necessários para essa amostra. Veja uma renderização completa do JSON retornado pela API Geocoding na documentação da API. Os valores de geometria.location.lat e Geometry.location.lng são simplesmente dois dos muitos campos no objeto JSON retornado.

Pode não ser óbvio, mas é importante observar que ExtractVariables produz duas variáveis com nomes que consistem no prefixo da variável (georesponse) e nos nomes reais especificados na política. Essas variáveis são armazenadas no proxy da API e estarão disponíveis para outras políticas no fluxo do proxy, como você verá. As variáveis são:

  • geocoderesponse.latitude
  • geocoderesponse.longitude

A maior parte do trabalho já foi concluída. Criamos um composto de três políticas que formam uma solicitação, chamam uma API de back-end e analisam os dados JSON retornados. Nas etapas finais, forneceremos os dados dessa parte do fluxo para outra política AttributionMessage, chamaremos a segunda API de back-end (API Google Elevation) e retornaremos os dados combinados para o desenvolvedor do aplicativo.

Gerar a segunda solicitação com AttributionMessage

A política AttributionMessage a seguir usa variáveis retornadas do primeiro back-end (Google Geocoding) que armazenamos e as conecta a uma solicitação destinada à segunda API (Google Elevation). Conforme observado anteriormente, essas variáveis são Geocoderresponse.latitude e georesponse.longitude.

No download do exemplo, você pode encontrar esse XML no arquivo 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>

Se você analisar a API Google Elevation, verá que são necessários dois parâmetros de consulta. O primeiro é chamado de locations, e o valor é a latitude e a longitude (valores separados por vírgula). O outro parâmetro é sensor, que é obrigatório e precisa ser verdadeiro ou falso. O mais importante a ser observado neste momento é que a mensagem de solicitação que criamos aqui não requer uma Service callout. Não precisamos chamar a segunda API de uma Service callout neste momento porque podemos chamar a API de back-end pelo TargetEndpoint do proxy. Temos todos os dados necessários para chamar a API Google Elevations. A mensagem de solicitação gerada nesta etapa não requer uma ServiceChamada, já que a solicitação gerada para o pipeline de solicitação principal. Ela será encaminhada pelo ProxyEndpoint para o TargetEndpoint, seguindo a RouteRule configurada para esse proxy de API. O TargetEndpoint gerencia a conexão com a API remota. Lembre-se de que o URL da API Elevation é definido na HTTPConnection para o TargetEndpoint. documentação da API Elevation se quiser saber mais. Os QueryParams armazenados anteriormente, country e postalcode, não são mais necessários. Por isso, eles são removidos aqui.

Pausa breve: de volta ao fluxo

Talvez você esteja se perguntando por que não estamos criando outra política Service callout. Afinal, criamos outra mensagem. Como essa mensagem é enviada ao destino, a API Google Elevation? A resposta está no elemento <RouteRule> do fluxo. <RouteRule> especifica o que fazer com as mensagens de solicitação restantes depois que a parte <Request> do fluxo é executada. O TargetEndpoint especificado por esta <RouteRule> informa ao proxy de API para entregar a mensagem a http://maps.googleapis.com/maps/api/elevation/xml.

Se você fez o download do proxy de API de exemplo, o XML TargetProxy pode ser encontrado no arquivo 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>

Agora, só precisamos processar a resposta da API Google Elevation e pronto.

Converter a resposta de XML para JSON

Neste exemplo, a resposta da API Google Elevation é retornada como XML. Para "crédito extra", vamos adicionar mais uma política à nossa composição para transformar a resposta de XML para JSON.

Neste exemplo, usamos a política de JavaScript chamada GenerateResponse, com um arquivo de recursos contendo o código JavaScript, para realizar a conversão. Veja abaixo a definição da política GenerateResponse:

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

O arquivo de recurso GenerateResponse.js inclui o JavaScript usado para realizar a conversão. Confira esse código no arquivo doc-samples/policy-mashup-cookbook/apiproxy/resources/JSC/GenerateResponse.js.

A Apigee também oferece uma política pronta para uso, XMLToJSON, para converter XML em JSON. Você pode editar o ProxyEndpoint para usar a política xmltojson mostrada abaixo.

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

Como testar o exemplo

Se você ainda não tiver feito isso, tente fazer o download, implantar e executar a amostra policy-mashup-cookbook, que pode ser encontrada na pasta document-samples no repositório de amostras do Apigee Edge no GitHub. Basta seguir as instruções do arquivo README na pasta policy-mashup-cookbook. Ou siga estas instruções resumidas em Como usar os proxies de API de amostra.

Para resumir, você pode chamar a API composta da seguinte maneira. Substitua {myorg} pelo nome da sua organização:

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

A resposta inclui o local geocodificado do centro do CEP informado pelo usuário final do app, combinado com a elevação nessa localização geocodificada. Os dados foram recuperados de duas APIs de back-end, combinados com as políticas anexadas ao proxy de API e retornados ao cliente em uma única resposta.

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

Resumo

Neste tópico do manual, explicamos como usar o padrão de composição de políticas para criar um mashup de dados de várias fontes de back-end. A composição da política é um padrão comum usado no desenvolvimento de proxy de API para adicionar a funcionalidade dos criativos à API.