Send Docs Feedback

Mapping conditional flows to backend API resources

Understanding API resources and conditional flows

Check out this short video for an introduction to the relationship between your RESTful backend resources and Edge proxy resources, or conditional flows.

RESTful services are collections of API resources. An API resource is a URI path fragment that identifies some entity that developers can access by calling your API. For example, if your service provides weather reports and weather forecasts, your backend service might define two API resources:

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

When you create an API proxy, at a minimum you're creating an alias base URL that maps to your backend service. For example:

Backend base URL New/equivalant API proxy URL
http://mygreatweatherforecast.com http://{your_org}-{environment}.apigee.net/mygreatweatherforecast

At this point you can make API calls to your backend using either base URL. But when you use the API proxy URL, things start to get interesting.

In addition to API analytics that Edge starts to collect when you use the API proxy, proxies also let you define conditional flows that map to the resources on your backend. In essence, "If a GET call comes in to the /reports resource, Edge should do something."

The following image shows the behavior difference between two URLs that ultimately access the same backend. One is the un-proxied resource URL, the other is an Edge API proxy with a conditional flow to the same backend resource. We'll describe conditional flows in more detail below.

How API proxies map to specific backend resources

With an API proxy URL mapped to the base URL of the backend service (when you create the proxy), you can add conditional flows to specific resources, such as the /reports and /forecasts resources mentioned earlier.

Let's say you wanted to have Edge "do something" when calls come in to the /reports or /forecasts resources. At this point you're not telling Edge what to do, just that it should be listening for calls to those resources. You do this with conditions. In your Edge API proxy, you can create conditional flows for /reports and /forecasts. For conceptual purposes, the following API proxy XML shows what those conditions might look like.

<Flows>
    <Flow name="reports">
        <Description/>
        <Request/>
        <Response/>
        <Condition>(proxy.pathsuffix MatchesPath &quot;/reports&quot;) and (request.verb = &quot;GET&quot;)</Condition>
    </Flow>
    <Flow name="forecasts">
        <Description/>
        <Request/>
        <Response/>
        <Condition>(proxy.pathsuffix MatchesPath &quot;/forecasts&quot;) and (request.verb = &quot;GET&quot;)</Condition>
    </Flow>
</Flows>

Those conditions say, "When a GET request comes in with /reports and /forecasts in the URL, Edge will do whatever you (the API developer) tell it to, through the policies you attach to those flows.

Now here's an example of telling Edge what to do when a condition is met. In the following API proxy XML, when a GET request is sent to  https://yourorg-test.apigee.net/mygreatweatherforecast/reports, Edge executes the "XML-to-JSON-1" policy in the response.

<Flows>
    <Flow name="reports">
        <Description/>
        <Request/>
        <Response>
            <Step>
                <Name>XML-to-JSON-1</Name>
            </Step>
        </Response>
        <Condition>(proxy.pathsuffix MatchesPath &quot;/reports&quot;) and (request.verb = &quot;GET&quot;)</Condition>
</Flow>

Note about default flows

In addition to those optional conditional flows, each API proxy also comes with two default flows: a <PreFlow> executed before your conditional flows, and a <PostFlow> executed after your conditional flows. Those are useful for executing policies when any call is made to an API proxy. For example, if you want to verify an app's API key with every call, regardless of the backend resource being accessed, you could put a Verify API Key policy on the <PreFlow>. For more on flows, see Configuring flows.

For a discussion of best practices when designing your base URLs and resources, see RESTful API Design: nouns are good, verbs are bad.

Creating conditional flows to backend resources

Defining conditional flows to backend resources in an API proxy is completely optional. However, those conditional flows give you the ability to apply fine-grained management and monitoring.

You will be able to:

  • Apply management in way that reflects the semantics of your API model
  • Apply policies and scripted behavior to individual resource paths (URIs)
  • Collect fine-grained metrics for Analytics Services

For example, imagine that you need to apply different types of management to /developers than to /apps.

To do so, you add two API resources: /developers and /apps.

In the Develop view of the API proxy builder, select New > Resource.

In the Navigator menu, you can see that two flows have been created: Apps and Developers.

Select one of the flows to view the API resource configuration:

<Flow name="Apps">
    <Description>Apps registered in Developer Services</Description>
    <Request/>
    <Response/>
    <Condition>(proxy.pathsuffix MatchesPath &quot;/apps&quot;)</Condition>
</Flow>

As you can see, API resources are simply conditional Flows that evaluate the URI path of the inbound request. (The proxy.pathsuffix variable identifies the URI of the request that follows the BasePath configured in the ProxyEndpoint configuration.)

Each API resource that you define is implemented by a conditional Flow in the API proxy. (See Configuring flows.)

Once you deploy the API proxy to the test environment, the following request:

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

will cause the condition to evaluate to true, and this flow, along with any associated policies, will execute.

You can further refine resource definitions by specifying the HTTP verb associated with a call:

For example you may need to treat the "create app" method differently than "list apps". To do so, specify the HTTP verb associated with the API resource. In this example, you need to manage the Create App method, so select the POST method.

Select Add.

Adding this API resource results in a new flow. The new flow is added to the ProxyEndpoint for the API proxy that you are building. If you look at the ProxyEndpoint configuration, you will see that the following flow configuration has been added:

<Flow name="CreateApp">
    <Description>Creates an app</Description>
    <Request/>
    <Response/>
    <Condition>(proxy.pathsuffix MatchesPath &quot;/apps&quot;) and (request.verb = &quot;POST&quot;)</Condition>
</Flow>

Building conditions

For more information on building conditions, see the Conditions reference. For example, the following condition uses a Java regular expression to recognize calls made to the /apps resource with or without a trailing forward slash (/apps or /apps/**):

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

For more about this type of condition, see the follwing Apigee Community thread:

https://community.apigee.com/questions/4284/how-do-you-override-at-the-end-of-the-url-when-you.html

Modeling hierarchical URIs

In some cases, you will have hierarchical API resources. For example, the Developer Services API provides a method for listing all apps that belong to a developer. The URI path is:

/developers/{developer_email}/apps

You may have resources where a unique ID is generated for each entity in a collection, which is sometimes annotated as follows:

/genus/:id/species

This path applies equally to the following two URIs:

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

To represent this structure in an API resource, you can use wildcards. For example:

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

will resolve these hierarchical URIs as API resources appropriately.

In some cases, especially for deeply hierarchical APIs, you may simply want to resolve everything below a certain URI fragment. To do so, use a double asterisk wildcard in your resource defintiion. For example, if you define the following API resource:
/developers/**

That API resource will resolve the following URI paths:

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

Here's what the conditional flow condition would look like in the API proxy definition:

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

Help or comments?