Condiciones con variables de flujo

Estás viendo la documentación de Apigee Edge.
Ve a la Documentación de Apigee X.
información

Las sentencias condicionales son una estructura de control común en todos los lenguajes de programación. Al igual que un lenguaje de programación, la configuración del proxy de API admite sentencias condicionales para flujos, políticas, pasos y RouteRules. Con la definición de sentencias condicionales, se define el comportamiento dinámico de la API. Este comportamiento dinámico te permite realizar acciones como convertir XML en JSON solo para dispositivos móviles o enrutar a una URL de backend en función del tipo de contenido o el verbo HTTP del mensaje de la solicitud.

En este tema, se muestra cómo usar las sentencias para aplicar funciones de administración de API de forma dinámica en el entorno de ejecución sin escribir ningún código.

Configura sentencias condicionales

El comportamiento condicional se implementa en los proxies de API mediante una combinación de condiciones y variables. Una sentencia condicional se crea con un elemento de condición. La siguiente es una condición vacía:

<Condition></Condition>

Para crear una sentencia condicional, agrega un operador condicional y una variable para crear la la siguiente estructura:

<Condition>{variable.name}{operator}{"value"}</Condition>

Los operadores condicionales compatibles incluyen = (igual), != (no igual) y > (mayor que). Para facilitar la lectura, también puedes escribir los condicionales como texto: equals, notequals, greaterthan.

Cuando trabajas con rutas de URI, puedes usar ~/ o MatchesPath. Puedes hacer coincidir las expresiones regulares de JavaRegex con el operador ~~.

Las condiciones se usan para definir los flujos condicionales del proxy de API sobre los recursos de API de backend, que se describen en Crea flujos condicionales a recursos de API de backend. Para obtener una lista completa de condicionales, consulta Referencia de las condiciones.

Variables

El trabajo de las condiciones es evaluar los valores de las variables. Una variable es una propiedad de una transacción HTTP ejecutada por un proxy de API, o una propiedad de una configuración de proxy de API en sí. Cada vez que un proxy de API recibe una solicitud de una aplicación, Apigee Edge propaga un una larga lista de variables asociadas con aspectos como la hora del sistema, la red información, los encabezados HTTP en los mensajes, la configuración del proxy de API, las ejecuciones de políticas, etc. Esto crea un contexto enriquecido que puedes usar para configurar declaraciones condicionales.

Las variables siempre usan una notación de puntos. Por ejemplo, los encabezados HTTP del mensaje de solicitud están disponibles como variables llamadas request.header.{header_name}. Entonces, para evaluar Encabezado de tipo de contenido, puedes usar la variable request.header.Content-type. Para el ejemplo request.header.Content-type = "application/json" indica que el contenido tipo de solicitud debe ser JSON.

Imagina que necesitas crear una sentencia condicional que haga que una política sea solo se aplicará cuando un mensaje de solicitud sea GET. Para crear una condición que evalúe el verbo HTTP de una solicitud, crea la siguiente sentencia condicional. La variable en esta condición es request.verb El valor de la variable es GET. El operador es =

<Condition>request.verb = "GET"</Condition>
También podrías usar:
<Condition>request.verb equals "GET"</Condition>

Edge usa esta declaración para evaluar las condiciones. El ejemplo anterior se evalúa como verdadero si el El verbo HTTP asociado con la solicitud es GET. Si el verbo HTTP asociado con la solicitud es POST, la sentencia se evalúa como falsa.

Para habilitar el comportamiento dinámico, puedes adjuntar condiciones a los flujos, los pasos y las RouteRules.

Cuando adjuntas una condición a un flujo, creas un “flujo condicional”. Flujos condicionales ejecutar solo cuando la condición se evalúa como verdadera. Puedes adjuntar tantas políticas como desees a un flujo condicional. Un flujo condicional te permite crear reglas de procesamiento altamente especializadas para mensajes de solicitud o respuesta que cumplan determinados criterios.

Por ejemplo, para crear un flujo que se ejecute solo cuando el verbo de la solicitud sea GET, sigue estos pasos:

<Flows>
  <Flow name="ExecuteForGETs">
  <Condition>request.verb="GET"</Condition>
  </Flow>
</Flows>

Si deseas crear un flujo para solicitudes GET y otro flujo para POST, sigue estos pasos:

<Flows>
  <Flow name="ExecuteForGETs">
  <Condition>request.verb="GET"</Condition>
  </Flow>
  <Flow name="ExecuteForPOSTs">
  <Condition>request.verb="POST"</Condition>
  </Flow>
</Flows>

Como se muestra en el siguiente ejemplo, puedes aplicar la condición al paso de política en sí. El siguiente condición hace que la política VerifyApiKey se aplique solo si un mensaje de solicitud es un PUBLICAR

<PreFlow name="PreFlow">
    <Request>
        <Step>
            <Condition>request.verb equals "POST"</Condition>
            <Name>VerifyApiKey</Name>
        </Step>
    </Request>
</PreFlow>

Una vez que hayas definido esos flujos condicionales, puedes adjuntarles políticas y habilitar una API para aplicar un conjunto de políticas para las solicitudes GET y otro conjunto para las POST solicitudes.

Para obtener información de referencia completa, consulta los siguientes recursos:

Ejemplo 1

En el siguiente ejemplo, se muestra un solo flujo condicional llamado Convert-for-devices, configurado en el flujo de respuesta de ProxyEndpoint. Agrega la condición como elemento en la entidad a la que se aplica la condición. En este ejemplo, la condición es un componente del flujo. Por lo tanto, el flujo se ejecutará cuando la instrucción se evalúe como verdadera.

<Flows>
  <Flow name="Convert-for-devices">
  <Condition>(request.header.User-Agent = "Mozilla")</Condition>
    <Response>
      <Step><Name>ConvertToJSON</Name></Step>
    </Response>
  </Flow>
</Flows>

Para cada solicitud recibida de una app, Edge almacena los valores de todos los encabezados HTTP presentes como variables. Si la solicitud contiene un encabezado HTTP llamado User-Agent, ese encabezado y su valor se almacenan como una variable llamada request.header.User-Agent.

Dada la configuración de ProxyEndpoint mencionada anteriormente, Edge verifica el valor del La variable request.header.User-Agent para ver si la condición se evalúa como true.

Si la condición se evalúa como verdadera, es decir, el valor de la variable request.header.User-Agent es igual a Mozilla; luego, el flujo condicional y se aplica la política XMLtoJSON llamada ConvertToJSON. De lo contrario, el flujo no se ejecuta y la respuesta XML se muestra sin modificar (en formato XML) a la app solicitante.

Ejemplo 2

Veamos un ejemplo específico en el que necesitas transformar el mensaje de respuesta de XML a JSON, pero solo para dispositivos móviles. Primero, crea la política que convertirá la respuesta con formato XML de la API de Weather a JSON:

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

La configuración de política anterior indica al proxy de la API que tome el mensaje de respuesta, realice una conversión de XML a JSON con la configuración predeterminada y, luego, escriba el resultado en el nuevo mensaje de respuesta. Si quieres convertir un mensaje request de XML a JSON, solo debes establecer ambos valores como request.

Dado que deseas convertir las respuestas de XML a JSON, debes configurar un flujo de respuesta condicional para realizar la conversión. Por ejemplo, para convertir todas las respuestas de XML a JSON antes de que se muestren en la aplicación cliente, configura el siguiente flujo de respuesta ProxyEndpoint.

<Flows>
  <Flow name="Convert-for-devices">
    <Response>
      <Step><Name>ConvertToJSON</Name></Step>
    </Response>
  </Flow>
</Flows>

Cuando invocas la API mediante la solicitud estándar, la respuesta tiene el formato JSON.

Sin embargo, tu objetivo solo es convertir los informes de Weather a JSON cuando el cliente solicitante es un dispositivo móvil. Para habilitar este comportamiento dinámico, debes agregar una sentencia condicional al flujo.

Prueba el flujo condicional

En esta solicitud de muestra, el encabezado HTTP User-Agent se establece en Mozilla, lo que hace que la sentencia condicional se evalúe como verdadera y el flujo condicional Convert-for-devices se ejecute.

$ curl -H "User-Agent:Mozilla" http://{org_name}-test.apigee.net/weather/forecastrss?w=12797282

O hace que se imprima con formato estilístico si Python está disponible:

$ curl -H "User-Agent:Mozilla" http://{org_name}-test.apigee.net/weather/forecastrss?w=12797282 | python -mjson.tool

Respuesta de muestra:

. . .

"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"
          }
      ]
  }

. . .

Una solicitud enviada sin el encabezado User-Agent o con un valor diferente a Mozilla, generará una respuesta con formato XML.

$ curl http://{org_name}-test.apigee.net/weather/forecastrss?w=12797282

Se muestra la respuesta XML sin modificar.

Respuesta de muestra:

<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" />

Coincidencia de patrones

En esta sección, se describe cómo usar la coincidencia de patrones con condiciones en un flujo de Apigee.

Operadores

En esta sección, se describe cómo usar los siguientes operadores de coincidencia de patrones en las sentencias condicionales:

Coinciden

Echemos un vistazo a "Coincidencias" o "~" condicional primero. Estos dos operadores son los misma: la versión en inglés, "Matches", se considera una opción más legible.

Resumen: Las "coincidencias" te da dos posibilidades. Haz coincidir string literalmente o hacer una coincidencia comodín con “*”. Como es de esperar, el comodín coincide con cero o más caracteres. Veamos cómo funciona este proceso.

El siguiente XML muestra una condición de paso. Ejecuta la política SomePolicy cuando la condición se evalúa como verdadera. En este ejemplo, probamos la variable proxy.pathsuffix, un una variable integrada en Edge que almacena el sufijo de la ruta de acceso de la solicitud. Sin embargo, ten en cuenta que puedes probar el valor de cualquier variable de flujo que contenga una string. Entonces, en este caso, si la ruta base de la solicitud entrante es /animals y la solicitud es /animals/cat, luego el el sufijo de la ruta de acceso es la string literal "/cat".

    <PreFlow name="PreFlow">
        <Request>
            <Step>
                <Condition>(proxy.pathsuffix Matches "/cat")</Condition>
                <Name>SomePolicy</Name>
            </Step>
        </Request>
        <Response/>
    </PreFlow>

Pregunta: ¿Qué sufijo de ruta del proxy hará que se ejecute SomePolicy? Solo hay una posibilidad.

Llamada a la API:

GET http://artomatic-test.apigee.net/matchtest/cat

¿La política se ejecuta? Sí, porque el sufijo de la ruta de acceso del proxy coincide con “/cat” exactamente. No se ejecutará si el sufijo es /bat o /dog, o “/” o cualquier otra cosa.

Ahora, considera esta sentencia condicional en la que usamos el carácter comodín “*”:

<Condition>(proxy.pathsuffix Matches "/*at")</Condition>

Llamada a la API:

GET http://artomatic-test.apigee.net/matchtest/cat

¿La política se ejecuta? Sí, porque el comodín coincide con cualquier carácter y "/cat" es una coincidencia.

Llamada a la API:

GET http://artomatic-test.apigee.net/matchtest/bat

¿La política se ejecuta? Sí, porque el comodín coincide con cualquier carácter y "/bat" es una coincidencia.

Llamada a la API:

GET http://artomatic-test.apigee.net/matchtest/owl

¿La política se ejecuta? Por supuesto que no, aunque el comodín coincide con "o", las letras "wl" no coinciden.

Ahora, movamos el comodín al final del sufijo:

<Condition>(proxy.pathsuffix Matches "/cat*")</Condition>

Llamada a la API:

GET http://artomatic-test.apigee.net/matchtest/cat

¿La política se ejecuta? Sí, porque el comodín coincide con cero o más caracteres de cualquier tipo.

Llamada a la API:

GET http://artomatic-test.apigee.net/matchtest/bat

¿La política se ejecuta? No, "/bat" no es una coincidencia.

Llamada a la API:

GET http://artomatic-test.apigee.net/matchtest/cat123

¿La política se ejecuta? Sí, el comodín coincide con cero o más caracteres, por lo que “123” produce una coincidencia.

Llamada a la API:

GET http://artomatic-test.apigee.net/matchtest/cat/bird/mouse

¿La política se ejecuta? Sí, porque el comodín coincide con cero o más caracteres de cualquier carácter. “/bird/mouse” produce una coincidencia. Ten en cuenta que una expresión como esta puede causar problemas, ya que coincide con todo lo que se encuentra después de los caracteres literales.

Pregunta: ¿El operador Coincidencias distingue mayúsculas de minúsculas?

Sí. Supongamos que tienes una condición como la que se muestra a continuación:

<Condition>(proxy.pathsuffix Matches "/*At")</Condition>

Llamada a la API:

GET http://artomatic-test.apigee.net/matchtest/cat

¿La política se ejecuta? No, el comodín coincide con cualquier letra (independientemente de las mayúsculas y minúsculas), pero el “a” minúscula no coincide con “A”.

Llamada a la API:

GET http://artomatic-test.apigee.net/matchtest/bAt

¿La política se ejecuta? Sí, las mayúsculas coinciden.

Pregunta: ¿Cómo puedo escapar caracteres con el operador Coincidencias?

Usar el porcentaje “%” para escapar los caracteres reservados. Por ejemplo:

<Condition>(proxy.pathsuffix Matches "/c%*at")</Condition>

Llamada a la API:

GET http://artomatic-test.apigee.net/matchtest/cat

¿La política se ejecuta? No, el operador Matches busca la cadena literal. “c*at”.

Llamada a la API:

GET http://artomatic-test.apigee.net/matchtest/c*at

Pregunta: ¿La política se ejecuta?

Sí, esta ruta coincide, pese a ser algo inusual.

JavaRegex

Como puedes ver, la columna "Coincidencias" es excelente para situaciones simples. Pero puedes usar otro “JavaRegex” o "~~" como "autor" y "título" usando un operador lógico. Estos dos son el mismo operador, pero se considera que JavaRegex es más legible. Se llama JavaRegex porque permite usar expresiones regulares la coincidencia de patrones, y Edge sigue las mismas reglas que las clases en la clase java.util.regex. package en el lenguaje Java. El funcionamiento del operador JavaRegex es muy diferente del de coincide con el operador, así que es importante no confundirlos.

Resumen: "JavaRegex" te permite usar la sintaxis de expresiones regulares en las instrucciones condicionales.

El siguiente código muestra una condición de paso. Ejecuta la política SomePolicy si la condición evalúa como true. En este ejemplo, probamos la variable proxy.pathsuffix, una aplicación en Edge que almacena el sufijo de la ruta de acceso de la solicitud. Si la ruta base de la solicitud entrante es /animals y la solicitud es /animals/cat, luego el el sufijo de la ruta de acceso es la string literal "/cat".

    <PreFlow name="PreFlow">
        <Request>
            <Step>
                <Condition>(proxy.pathsuffix JavaRegex "/cat")</Condition>
                <Name>SomePolicy</Name>
            </Step>
        </Request>
        <Response/>
    </PreFlow>

Pregunta: ¿Qué sufijo de ruta del proxy hará que se ejecute SomePolicy? Tal como con el operador Matches, solo hay una posibilidad en este caso.

Llamada a la API:

GET http://artomatic-test.apigee.net/matchtest/cat

¿La política se ejecuta? Sí, porque el sufijo de la ruta de acceso del proxy coincide con “/cat” exactamente. No se ejecutará si el sufijo es /bat, /dog, o cualquier otro.

Ahora, creemos una expresión regular con “*” cuantificador. Este cuantificador coincide con cero o más del carácter anterior.

<Condition>(proxy.pathsuffix JavaRegex "/c*t")</Condition>

Llamada a la API:

GET http://artomatic-test.apigee.net/matchtest/cat

¿La política se ejecuta? ¡No! El símbolo "*" el cuantificador coincide con cero o más de las carácter anterior, que es “c”.

Llamada a la API:

GET http://artomatic-test.apigee.net/matchtest/ccccct

¿La política se ejecuta? Sí, porque el comodín coincide con cero o más ocurrencias del carácter anterior.

Luego, usaremos "?" cuantificador, que coincide una vez con el carácter anterior, o no en absoluto.

<Condition>(proxy.pathsuffix JavaRegex "/ca?t")</Condition>

Llamada a la API:

GET http://artomatic-test.apigee.net/matchtest/cat

¿La política se ejecuta? Sí. "?" el cuantificador coincide con cero o una ocurrencia de el carácter anterior, que es "a".

Llamada a la API:

GET http://artomatic-test.apigee.net/matchtest/ct

¿La política se ejecuta? Sí. "?" el cuantificador coincide con uno o ninguno del carácter anterior. En este caso, no existe la letra “a” el carácter, por lo que condición se evalúa como verdadera.

Llamada a la API:

GET http://artomatic-test.apigee.net/matchtest/caat

¿La política se ejecuta? No. El símbolo "?" el cuantificador coincide con uno de los valores anteriores carácter, que es "a".

Luego, usaremos "[abc]" o "agrupación" estilo de expresión de regex. Coincide con el caracteres "a" o "b" o "c".

<Condition>(proxy.pathsuffix JavaRegex "/[cbr]at")</Condition>

Llamada a la API:

GET http://artomatic-test.apigee.net/matchtest/cat

¿La política se ejecuta? Sí. Aquí usamos expresiones regulares y “[cbr]” coincide con “c”, “b” O “r”. Estas llamadas también coinciden:

GET http://artomatic-test.apigee.net/matchtest/bat

GET http://artomatic-test.apigee.net/matchtest/rat

Pero esto no es una coincidencia:

GET http://artomatic-test.apigee.net/matchtest/mat

Pregunta: ¿El operador JavaRegex distingue mayúsculas de minúsculas?

Sí. Supongamos que tienes una condición como la que se muestra a continuación:

<Condition>(proxy.pathsuffix JavaRegex "/ca?t")</Condition>

Llamada a la API:

GET http://artomatic-test.apigee.net/matchtest/cat

¿La política se ejecuta? Sí, la regex coincide con cero o uno de los caracteres anteriores, lo que es “a”.

Llamada a la API:

GET http://artomatic-test.apigee.net/matchtest/cAt

Pregunta: ¿La política se ejecuta?

No, porque la “A” mayúscula no coincide con la “a” en minúscula.

MatchesPath

El operador MatchesPath también se puede especificar de la siguiente manera: “~/”. Se parece un poco a Matches (~) y los operadores JavaRegex (~~). Sin embargo, MatchesPath es completamente diferente.

Solo recuerda que este operador considera una ruta de acceso como una serie de partes. Por lo tanto, si la ruta es /animals/cats/wild, puedes pensar que la ruta de acceso consta de las partes "/animals", "/cats" y "/wild".

El operador MatchesPath te permite usar dos notaciones de comodines: un solo asterisco (*) y un asterisco doble (**). El asterisco único coincide con un elemento de ruta de acceso. El doble asterisco coincide con uno o varios elementos de ruta.

Veamos un ejemplo. En este ejemplo, probamos la variable proxy.pathsuffix, una variable integrada en Edge que almacena el sufijo de la ruta de acceso de la solicitud. Sin embargo, ten en cuenta que puedes probar el valor de cualquier variable de flujo que contenga una string.

    <PreFlow name="PreFlow">
        <Request>
            <Step>
                <Condition>(proxy.pathsuffix MatchesPath "/animals/*")</Condition>
                <Name>SomePolicy</Name>
            </Step>
        </Request>
        <Response/>
    </PreFlow>

Pregunta: ¿Qué sufijo de ruta del proxy hará que se ejecute SomePolicy?

Llamada a la API:

GET http://artomatic-test.apigee.net/matchtest/animals

Pregunta: ¿La política se ejecuta?

No, porque la condición requiere otro elemento de ruta de acceso después de "/animals", según lo especificado por "/*".

Llamada a la API:

GET http://artomatic-test.apigee.net/matchtest/animals/

¿La política se ejecuta? Sí, la ruta de acceso tiene otro elemento de ruta de acceso (la parte después de "/animals/"), pero solo está vacía.

Llamada a la API:

GET http://artomatic-test.apigee.net/matchtest/animals/cats

¿La política se ejecuta? Sí, porque la ruta tiene claramente un elemento ("/cats") que viene después de "/animals"

Llamada a la API:

GET http://artomatic-test.apigee.net/matchtest/animals/cats/wild

Pregunta: ¿La política se ejecuta?

No, porque el asterisco único solo coincide con un elemento de ruta de acceso. esta API tiene más de un elemento después de "/animals".

Ahora, usemos el asterisco doble:

    <PreFlow name="PreFlow">
        <Request>
            <Step>
                <Condition>(proxy.pathsuffix MatchesPath "/animals/**")</Condition>
                <Name>SomePolicy</Name>
            </Step>
        </Request>
        <Response/>
    </PreFlow>

Pregunta: ¿Qué sufijo de ruta del proxy hará que se ejecute SomePolicy?

Llamada a la API:

GET http://artomatic-test.apigee.net/matchtest/animals

¿La política se ejecuta? No, porque la condición requiere al menos un elemento de ruta de acceso siguiente especificado por "/**".

Llamada a la API:

GET http://artomatic-test.apigee.net/matchtest/animals/

¿La política se ejecuta?

Sí, la ruta de acceso tiene otro elemento de ruta de acceso (la parte después de "/animals/"), pero solo está vacía.

Llamada a la API:

GET http://artomatic-test.apigee.net/matchtest/animals/cats

¿La política se ejecuta?

Sí, porque la ruta tiene al menos un elemento que viene después “/animals

Llamada a la API:

GET http://artomatic-test.apigee.net/matchtest/animals/cats/wild

¿La política se ejecuta?

Sí, porque la ruta tiene más de un elemento después de “/animals

Mezcla asteriscos

Puedes usar combinaciones del asterisco simple (*) y doble (**) para definir mejor la coincidencia de rutas.

    <PreFlow name="PreFlow">
        <Request>
            <Step>
                <Condition>(proxy.pathsuffix MatchesPath "/animals/*/wild/**")</Condition>
                <Name>SomePolicy</Name>
            </Step>
        </Request>
        <Response/>
    </PreFlow>

Llamada a la API:

Todas estas llamadas a la API producirán una coincidencia:

GET http://artomatic-test.apigee.net/matchtest/animals/cats/wild/

y

GET http://artomatic-test.apigee.net/matchtest/animals/dogs/wild/austrailian

y

GET http://artomatic-test.apigee.net/matchtest/animals/birds/wild/american/finches

Recursos de la API

Los servicios RESTful son colecciones de recursos de API. Un recurso de API es un fragmento de ruta de URI que identifica algunas entidades a las que los desarrolladores pueden acceder mediante una llamada a tu API. Por ejemplo, si tu servicio proporciona informes y pronósticos del clima, tu servicio de backend podría definir dos recursos de API:

  • http://mygreatweatherforecast.com/reports
  • http://mygreatweatherforecast.com/forecasts

Cuando creas un proxy de API (como se muestra en Compila tu primer proxy de API), como mínimo, creas una URL base de alias que se asigna a tu servicio de backend. Por ejemplo:

URL base del backend URL del proxy de API nueva o equivalente
http://mygreatweatherforecast.com http://{your_org}-{environment}.apigee.net/mygreatweatherforecast

En este punto, puedes realizar llamadas a la API de tu backend mediante la URL base. Sin embargo, cuando usas la URL del proxy de API, las cosas ser vuelven interesantes.

Además de las estadísticas de API que Edge comienza a recopilar cuando usa el proxy de API, los proxies te permiten definir flujos condicionales que se asignan a los recursos en tu backend. En esencia, "si entra una llamada GET al recurso /reports, Edge debería hacer algo".

En la imagen siguiente, se muestra la diferencia de comportamiento entre dos URL que acceden al mismo backend. Una es la URL del recurso sin proxy, el otro es un proxy de la API de Edge con un flujo condicional al mismo recurso de backend. A continuación, describiremos los flujos condicionales con más detalle.

Cómo asignar proxies de API a recursos de backend específicos

Con una URL de proxy de API asignada a la URL base del servicio de backend (cuando creas el proxy), puedes agregar flujos condicionales a recursos específicos, como los recursos /reports y /forecasts que se mencionó anteriormente.

Supongamos que quieres que Edge "haga algo" Cuando las llamadas ingresan a la Recursos /reports o /forecasts. En este punto, no le estás informando a Edge qué hacer, solo que debería estar escuchando las llamadas a esos recursos. Esto se hace con las condiciones. En el proxy de la API de Edge, puedes crear flujos condicionales para /reports y /forecasts. Para fines conceptuales, el siguiente XML del proxy de API muestra cómo podrían ser esas condiciones.

<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>

Esas condiciones indican lo siguiente: "Cuando una solicitud GET ingresa con /reports y /forecasts en la URL, Edge hará lo que le indiques (el desarrollador de la API) a través de las políticas que adjuntas a esos flujos.

Este es un ejemplo para indicarle a Edge qué hacer cuando se cumple una condición. En la siguiente API XML del proxy, cuando se envía una solicitud GET al https://yourorg-test.apigee.net/mygreatweatherforecast/reports, se ejecuta Edge. el espacio de nombres “XML-to-JSON-1” política en la respuesta.

<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>

Además de esos flujos condicionales, cada proxy de API también incluye dos flujos predeterminados: un <PreFlow> que se ejecuta antes de tus flujos condicionales y un <PostFlow> que se ejecuta después de los flujos condicionales. Esos son útiles para ejecutar políticas cuando se realiza cualquier llamada a un proxy de API. Por ejemplo, si deseas verificar la clave de API de una app con cada llamada, sin importar el recurso de backend al que se accede, puedes colocar una política de verificación de la clave de API en <PreFlow>. Para obtener más información sobre los flujos, consulta Configura flujos.

Crea flujos condicionales a recursos de backend

Definir flujos condicionales en los recursos de backend de un proxy de API es completamente opcional. Sin embargo, esos flujos condicionales te permiten aplicar una administración y supervisión detalladas.

con el que podrás:

  • Aplicar la administración, de manera que refleje la semántica de tu modelo de API
  • Aplicar políticas y comportamiento con secuencias de comandos a rutas de recursos individuales (URI)
  • Recopilar métricas detalladas para los servicios de Analytics

Por ejemplo, imagina que necesitas aplicar diferentes tipos de lógica a tu backend /developers a /apps.

Para hacerlo, debes agregar dos flujos condicionales en tu proxy de API: /developers y /apps.

En la vista Develop del panel del navegador del editor de proxy de API, haz clic en el ícono +. junto al valor predeterminado en los extremos del proxy.

En el "Nuevo flujo condicional" deberías ingresar las siguientes configuraciones de clave:

  • Nombre del flujo: Desarrolladores
  • Tipo de condición: Ruta de acceso
  • Ruta de acceso: /developers

Si se envía una llamada al proxy, se activará la condición (y se ejecutarán las políticas). con /developers al final del URI.

Ahora, agrega un flujo condicional para /apps y imagina que deseas que la condición se active en el URI y el verbo POST en una solicitud. Debes aplicar la siguiente configuración:

  • Nombre del flujo: Aplicaciones
  • Condition Type: Path and Verb
  • Ruta de acceso: /apps
  • Verbo: POST

Si se envía una llamada al proxy, se activará la condición (y se ejecutarán las políticas). con /apps al final del URI y un verbo POST.

En el panel Navigator, verás nuevos flujos para Apps y Desarrolladores.

Selecciona uno de los flujos para ver la configuración de flujo condicional en la vista de código del editor de proxy de 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>

Como puedes ver, los recursos de API son simplemente flujos condicionales que evalúan la ruta de URI de la solicitud entrante. (La variable proxy.pathsuffix identifica el URI de la solicitud que sigue la BasePath que se configuró en la configuración de ProxyEndpoint).

Cada recurso de API que defines se implementa mediante un flujo condicional en el proxy de API. (Consulta Configura flujos).

Una vez que implementes el proxy de API en el entorno de prueba, ocurrirá lo siguiente con esta solicitud:

http://{org_name}-test.apigee.net/{proxy_path}/apps

hará que la condición se evalúe como verdadera y este flujo, junto con cualquier políticas, se ejecutarán.

En la siguiente condición de ejemplo, se usa una expresión regular de Java para reconocer las llamadas realizadas al recurso /apps con o sin una barra diagonal final (/apps o /apps/**):

<Condition>(proxy.pathsuffix JavaRegex "/apps(/?)") and (request.verb = "POST")</Condition>

Para obtener más información sobre este tipo de condición, consulta Cómo hacer la coincidencia sin importar ... en la Comunidad de Apigee.

Modela URI jerárquicos

En algunos casos, tendrás recursos de API jerárquicos. Por ejemplo, los Servicios para desarrolladores La API proporciona un método para mostrar una lista de todas las apps que pertenecen a un desarrollador. Esta es la ruta del URI:

/developers/{developer_email}/apps

Es posible que tengas recursos en los que se genere un ID único para cada entidad de una colección, lo que a veces se anota de la siguiente manera:

/genus/:id/species

Esta ruta se aplica de la misma manera a los siguientes dos URI:

/genus/18904/species
/genus/17908/species

Para representar esta estructura en un recurso de API, puedes usar comodines. Por ejemplo:

/developers/*/apps
/developers/*example.com/apps
/genus/*/species

resolverá estos URI jerárquicos como recursos de API de forma adecuada.

En algunos casos, en especial para las API muy jerárquicas, es posible que desees resolver todo debajo de un fragmento de URI determinado. Para hacerlo, usa un comodín de asterisco doble en la definición del recurso. Por ejemplo, si defines el siguiente recurso de API:
/developers/**

Ese recurso de API resolverá las siguientes rutas de URI:

/developers/{developer_email}/apps
/developers/{developer_email}/keys
/developers/{developer_email}/apps/{app_id}/keys

Así se vería la condición del flujo condicional en la definición del proxy de API:

<Condition>(proxy.pathsuffix MatchesPath "/developers/**") and (request.verb = "POST")</Condition>

Más ejemplos

Condición adjunta a 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>

Condición adjunta a una política

<Step>
<!--the policy MaintenancePolicy only executes if the response status code is exactly 503-->
  <Condition>response.status.code = 503</Condition>
  <Name>MaintenancePolicy</Name>
</Step>

Flujo condicional

<!-- 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>

Ejemplos de operadores en condiciones

Estos son algunos ejemplos de operadores que se usan para crear condiciones:

  • 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

Ejemplo práctico: Omite "/" a las final de una ruta de acceso

Por lo general, los desarrolladores de Edge quieren controlar estos dos sufijos de ruta: “/cat” y “/cat/” Esto se debe a que algunos usuarios o clientes podrían llamar a tu API con el código al final de la ruta de acceso y debes poder controlarlo en tu regla declaraciones. Este caso de uso exacto en la comunidad de Apigee.

Si lo prefieres, puedes lograrlo sin usar Regex, de la siguiente manera:

    <PreFlow name="PreFlow">
        <Request>
            <Step>
                <Condition>((proxy.pathsuffix = "/cat") OR (proxy.pathsuffix = "/cat/")</Condition>
                <Name>SomePolicy</Name>
            </Step>
        </Request>
        <Response/>
    </PreFlow>

Esta es una buena opción. Es claro y legible.

Sin embargo, puedes hacer lo mismo con Regex como este. Los paréntesis se usan para agrupar la parte de regex de la declaración, pero no son obligatorios.

<Condition>(proxy.pathsuffix JavaRegex "/cat(/?)"</Condition>

Llamadas a la API:

GET http://artomatic-test.apigee.net/matchtest/cat
or

GET http://artomatic-test.apigee.net/matchtest/cat/

¿La política se ejecuta? Sí. Ten en cuenta que, en una expresión regular, el símbolo “?” carácter significa: coincidir con cero o uno de los caracteres anteriores. Por lo tanto, tanto “/cat” y "/cat/" son coincidencias.

Llamada a la API:

GET http://artomatic-test.apigee.net/matchtest/cat/spotted

¿La política se ejecuta? No. La expresión regular coincide con cero o una ocurrencia del carácter anterior y no se permite nada más.

Haz coincidir strings arbitrarias con JavaRegex

En todos los ejemplos de este tema, mostramos cómo hacer coincidir una de las variables de flujo integradas: proxy.pathsuffix. Puedes hacer coincidencias de patrones en cualquier cadena arbitraria o sin importar si es una variable de flujo integrada, como proxy.pathsuffix.

Por ejemplo, si tienes una condición que prueba una string arbitraria, tal vez una string que se muestra en una carga útil de backend, o una string que se muestra en una búsqueda del servidor de autenticación, puedes usar operadores coincidentes para probarla. Si usas JavaRegex, se comparará la expresión regular. en toda la cadena del asunto. Si el asunto es "abc", y la expresión regular es “[a-z]”, no hay coincidencia, porque “[a-z]” coincide exactamente con un carácter alfa. El expresión "[a-z]+" funciona, al igual que "[a-z]*" y "[a-z]{3}.

Revisemos un ejemplo concreto. Supongamos que el servidor de autenticación devuelve una lista de roles como una cadena delimitada por comas: "editor, author, guest".

Para probar la presencia del rol de editor, esta construcción no funcionará porque "editor". es solo una parte de la cadena completa.

<Condition>returned_roles ~~ "editor"</Condition>

Sin embargo, esta construcción funcionará:

<Condition>returned_roles ~~ ".*\beditor\b.*")</Condition>

Funciona porque tiene en cuenta las rupturas de palabras y cualquier otra parte de la cadena con el .* y el sufijo.

En este ejemplo, también puedes probar “editor” con el operador Matches (Coincidencias):

<Condition>returned_roles ~~ "*editor*")</Condition>

Sin embargo, JavaRegex suele ser una mejor opción si necesitas más precisión.

Escapa comillas dobles en las expresiones de JavaRegex

La sintaxis de condición requiere que una expresión JavaRegex esté entre comillas dobles. por lo tanto, si tienes un Es una expresión de regex que incluye comillas dobles. Necesitas una forma alternativa de hacer coincidir las comillas. La respuesta es Unicode. Por ejemplo, supongamos que pasas un encabezado que incluye comillas dobles, como el siguiente:
 -H 'content-type:multipart/related; type="application/xop+xml"'
Si intentas hacer coincidir ese encabezado en una condición de regex, obtendrás un error de condición no válida porque la expresión incluye las comillas dobles:
request.header.Content-Type ~~ "(multipart\/related)(; *type="application\/xop\+xml\")"
La solución es reemplazar las comillas dobles basadas en ASCII con su equivalente de Unicode, \u0022. Por ejemplo, la siguiente expresión es válida y produce el resultado esperado:
request.header.Content-Type ~~ "(multipart\/related)(; *type=\u0022application\/xop\+xml\u0022)"