Multi tenancy patterns on Apigee

A very common pattern that a lot of Apigee customers come across is having multiple tenants inside of Apigee. So it’s  very common to have multiple target endpoints in Apigee, for instance, one for each tenant. The challenge then becomes: how do you route to the different target endpoints based on who is accessing the different APIs? 

In this article I will explain  a couple of ways you can set up conditional routing in Apigee in a multi tenant environment. 

Apigee is known for its flexibility and the ability to customize the behavior of your proxies to accommodate different use cases, so there are generally multiple ways to tackle the same problem and this is just one way of doing it.

But first let’s get started by explaining some basic Apigee concepts that will help you understand what we are trying to accomplish.

 

Proxy endpoints, target endpoints and route rules

In Apigee you have proxy endpoints and target endpoints. Proxy endpoints manage connections from clients, while target endpoints make connections to backend systems. Route rules allow us to conditionally route calls to the right target endpoint and can use any API context available.

In this case we will use something we know about the client app, which is the tenant ID to make a routing decision. Each target endpoint is configured with the address of the tenant cluster stored in the app. 

The first approach is to use the Apigee built in conditional routing and create one routing rule per tenant. The benefit of this approach is that it’s simple, static, and very easy to implement. It is usually best suited for environments where the number or target servers is finite, and it doesn’t change a lot.

 

Route Rules per Target Endpoint

epbgonzalez_0-1671925016728.png

The proxy configuration would look something like this:

<RouteRule name="route-to-tenant-1">
        <Condition>verifyapikey.verify-api-key.app.tenant_id = "1"</Condition>
        <TargetEndpoint>tenant-1</TargetEndpoint>
</RouteRule>
<RouteRule name="route-to-tenant-2">
        <Condition>verifyapikey.verify-api-key.app.tenant_id = "2"</Condition>
        <TargetEndpoint>tenant-2</TargetEndpoint>
</RouteRule>


This will make use of the conditional routing rules, to send the request to the corresponding tenant.

This approach, however, might not work in more dynamic environments, where your tenants change frequently and you have to constantly maintain and make changes to your routing rules.

For those types of scenarios, you might want to leverage a more dynamic approach like dynamic routing. 

 

Dynamic target configuration

Let’s talk about target URL rewriting in this pattern. We leverage Apigee‘s Key Value Map as a look up table to match a tenant ID linked with the API key with the address of the tenant cluster. We use a single target endpoint with an Assigned Message policy to rewrite the target URL. This pattern is useful when you have a large or dynamic number of tenants and you want to manage them externally. Entries in the key value map can be updated programmatically using the management API and included as part of your CI/CD pipeline. 



epbgonzalez_1-1671925016724.png

 

 

Here are the different policies we use to implement this pattern:

An Assign Message Policy for the proxy endpoint

<AssignVariable>
  <Name>dynamic.target.key</Name>
<Template>{env-name}-{proxy.name}</Template>
</AssignVariable>

A KVM Operation Policy to lookup the tenant address in the proxy endpoint:

<Get assignTo="forward.target.url">
  <Key>
    <Parameter ref="verifyapikey.verify-api-key.app.tenant_id"/>
  </Key>
</Get>

Another Assign Message policy at the target endpoint to append the path suffix:

<AssignVariable>
  <Name>target.url</Name>
  <Ref>forward.target.url</Ref>
</AssignVariable>

<AssignVariable>
  <Name>target.copy.pathsuffix</Name>
  <Value>false</Value>
</AssignVariable>



Contributors
Version history
Last update:
‎12-24-2022 03:45 PM
Updated by: