Como usar a composição de política

Você está lendo a documentação do Apigee Edge.
Acesse a documentação da Apigee X.
info

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

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

Fazer o download e testar o exemplo de código

Sobre este exemplo de manual

Este exemplo de manual ilustra um padrão de proxy de API chamado composição de políticas. Esse padrão oferece uma maneira (há outras) de combinar dados de várias fontes de back-end. De modo mais geral, este tópico demonstra como as políticas podem ser combinadas e encadeadas para produzir um resultado desejado. Para uma visão geral desse padrão e de outros relacionados, consulte Padrões de manual de proxy de API.

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

  • A 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).
  • A API Google Elevation: essa API fornece uma interface simples para consultar locais na Terra e obter dados de elevação data. Neste exemplo, as coordenadas retornadas da API Geocoding serão usadas como entrada nessa API.

Os desenvolvedores de apps vão chamar esse proxy de API com dois parâmetros de consulta, um código postal 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 o local geocodificado (latitude/longitude) para o centro da área do código postal fornecido, combinado com a elevação nesse local geocodificado local.

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

Antes de começar

Se você quiser ler uma breve visão geral do padrão de composição de políticas, consulte "O padrão de composição de políticas" em Padrões de manual de proxy de API.

Antes de explorar este exemplo de manual, você também precisa conhecer estes conceitos fundamentais:

  • O que são políticas e como anexá-las a proxies. Para uma boa introdução às políticas, consulte O que é uma política?.
  • A estrutura de um fluxo de proxy de API, conforme explicado em 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 sistema de arquivos, conforme explicado em Referência de configuração de proxy de API. Este tópico do manual demonstra o desenvolvimento local (com base no sistema de arquivos) em vez do desenvolvimento baseado na nuvem, em que você pode usar a interface de gerenciamento para desenvolver o proxy de API.
  • Uso da validação de chave de API. Essa é a forma mais simples de segurança baseada em aplicativo que é possível configurar para uma API. Para mais informações, consulte Chaves de API. Você também pode 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, poderá encontrar todos os arquivos discutidos neste tópico na pasta de exemplo mashup-policy-cookbook. As seções a seguir discutem o exemplo de código em detalhes.

Me deixo levar

Antes de passar para as políticas, vamos conferir o 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 essas políticas são chamadas.

No download de amostra, 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>

Confira 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 se preocupam em criar uma mensagem de solicitação, enviá-la e analisar a resposta. Ao final deste tópico, você vai 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 por processar a resposta final do endpoint de destino (a API Google Elevation).
  • <HttpProxyConnection> : esse elemento especifica detalhes sobre como os apps vão se conectar a esse proxy de API, incluindo o <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 de entrada. Nesse caso, o TargetEndpoint é chamado. Vamos discutir 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 de políticas.

Criar a primeira política AssignMessage

A primeira política AssignMessage, listada abaixo, cria uma mensagem de solicitação que será enviada ao serviço Google Geocoding service.

Vamos começar com o código da política e, em seguida, explicar os elementos dela com mais detalhes. No download de amostra, 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>

Confira uma breve descrição dos elementos dessa política. Leia mais sobre essa política em Política AssignMessage.

  • <AssignMessage name> : atribui 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 ServiceCallout.
  • <QueryParams> : define os parâmetros de consulta necessários para a chamada de API de back-end. Nesse caso, a API Geocoding precisa saber o local, que é expresso com um código postal e um ID do país. O usuário do app fornece essas informações, e nós apenas as extraímos aqui. O parâmetro sensor é exigido pela API e é verdadeiro ou falso. Nós apenas o codificamos como falso aqui.
  • <Verb> : nesse caso, estamos fazendo uma solicitação GET simples para a API.
  • <AssignVariable> : essas variáveis armazenam os valores que estamos transmitindo para a API. Neste exemplo, as variáveis serão acessadas mais tarde na resposta retornada ao cliente.

Enviar a solicitação com ServiceCallout

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

Como antes, vamos conferir o código primeiro. Uma explicação detalhada é apresentada a seguir. Leia mais sobre essa política em Política de chamada de serviço. No download de amostra, 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>

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

  • <ServiceCallout> : como na política anterior, essa tem um nome.
  • <Request variable> : essa é a variável criada na política AssignMessage. Ela encapsula a solicitação que vai para a API de back-end.
  • <Response> : esse elemento nomeia uma variável em que a resposta é armazenada. Como você verá, essa variável será acessada mais tarde 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, vamos processar a resposta.

Analisar a resposta com ExtractVariables

A política ExtractVariables fornece um mecanismo simples para analisar o conteúdo da mensagem de resposta obtida por uma política ServiceCallout. 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 parâmetros 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 policy. No download de amostra, 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> : novamente, o nome da política é usado para se referir à política quando ela é usada em um fluxo.
  • <Source> : especifica a variável de resposta que criamos na política ServiceCallout. Essa é a variável da qual essa 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> : esse 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 de que precisamos para este exemplo. Você pode conferir uma renderização completa do JSON retornado pela API Geocoding na documentação da API. Os valores de geometry.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 cujos nomes consistem no prefixo da variável (geocoderesponse) e nos nomes de variáveis reais especificados na política. Essas variáveis são armazenadas no proxy de API e estarão disponíveis para outras políticas no fluxo de proxy, como você verá. As variáveis são:

  • geocoderesponse.latitude
  • geocoderesponse.longitude

A maior parte do trabalho já foi feita. 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, vamos inserir dados dessa parte do fluxo em outra política AssignMessage, chamar a segunda API de back-end (API Google Elevation) e retornar nossos dados combinados ao desenvolvedor de apps.

Gerar a segunda solicitação com AssignMessage

A política AssignMessage 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). Como observado anteriormente, essas variáveis são geocoderesponse.latitude e geocoderesponse.longitude.

No download de amostra, 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ê examinar a API Google Elevation, verá que ela usa dois parâmetros de consulta. O primeiro é chamado de locations e o valor dele é 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 observar neste momento é que a mensagem de solicitação que criamos aqui não exige uma ServiceCallout. Não precisamos chamar a segunda API de uma ServiceCallout neste momento porque podemos chamar a API de back-end do TargetEndpoint do proxy. Se você pensar bem, temos todos os dados necessários para chamar a API Google Elevations A mensagem de solicitação gerada nesta etapa não exige uma ServiceCallout, assim como a solicitação gerada para o pipeline de solicitação principal, e, portanto, será simplesmente 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 no HTTPConnection para o TargetEndpoint. Documentação da API Elevation se você quiser saber mais. Os QueryParams que armazenamos anteriormente, country e postalcode, não são mais necessários. Portanto, os removemos aqui.

Breve pausa: voltar ao fluxo

Neste momento, você pode se perguntar por que não estamos criando outra política ServiceCallout. Afinal, criamos outra mensagem. Como essa mensagem é enviada para o 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 for executada. O TargetEndpoint especificado por essa <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 amostra, poderá encontrar o XML do TargetProxy 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 ao nosso composto para transformar a resposta de XML para JSON.

Este exemplo usa a política JavaScript chamada GenerateResponse, com um arquivo de recurso contendo o código JavaScript, para realizar a conversão. Confira 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. Você pode conferir esse código no arquivo doc-samples/policy-mashup-cookbook/apiproxy/resources/JSC/GenerateResponse.js.

A Apigee também fornece 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 em vez disso.

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

Como testar o exemplo

Se ainda não fez isso, tente fazer o download, implantar e executar o policy-mashup-cookbook exemplo, que pode ser encontrado na pasta doc-samples no repositório de exemplos do Apigee Edge no GitHub. Basta seguir as instruções no arquivo README na pasta policy-mashup-cookbook. Ou, siga as instruções breves aqui: 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 para o centro do código postal fornecido por o usuário final do app, combinado com a elevação nesse local geocodificado. Os dados foram recuperados de duas APIs de back-end, combinados com 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

Este tópico do manual explicou 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 de políticas é um padrão comum usado no desenvolvimento de proxy de API para adicionar funcionalidades criativas à API.