Send Docs Feedback

API resources and conditional flows

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 backend provides weather reports and weather forecasts, your API might define two API resources: /reports and /forecasts.

Edge API proxies let you define conditional flows that map to the actual resources on your backend. 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.

Say your RESTful backend service has a base URL of

http://mygreatweatherforecast.com

along with the /reports and /forecasts resources.

After you create an API proxy to that backend in Edge, your new API proxy base URL would look something like this:

https://yourorg-test.apigee.net

At that point, any requests that got sent to https://yourorg-test.apigee.net would be sent to http://mygreatweatherforecast.com.

You could also send requests to

https://yourorg-test.apigee.net/reports
and
https://yourorg-test.apigee.net/forecasts

to access the backend resources.

But at this point, without any extra configuration, the Edge API proxy is serving mostly as a passthrough while collecting some analytics.

Adding conditional flows to backend API resources

However, let's say you wanted to use Edge to transform the response from the /reports resource and you wanted to apply message throttling to the /forecasts resources. In essence, you want to configure Edge to do something when a call to those resources comes in.

Enter conditional flows. In your Edge API proxy, you can create two proxy resources (/reports and /forecasts), which are really conditional flows. For example, after you add those conditional flows to the API proxy, the underlying proxy XML configuration looks something like this:

<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. In the following example, when a GET request is sent to  https://yourorg-test.apigee.net/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>

With this condition, Edge can also collect statistics on calls to that specific backend resource.

Note about default flows

In additional 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 Flows.

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

Defining API resources

Defining API resources in an API proxy is completely optional. However, by defining API resources in an API proxy, you gain 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 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.

If you have a WADL for your API, create an API resource for each resource in the WADL. This will enable you to configure fine-grained management over your API.

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?

  • If something's not working: Ask the Apigee Community or see Apigee Support.
  • If something's wrong with the docs: Click Send Docs Feedback on this page.
    (Incorrect? Unclear? Broken link? Typo?)