A problem recently came up with a customer that may also come up for you. I’ll state the problem and then walk through a number of different possible solutions, all with their own pros and cons. Based on your own scenario, you may find that a different solution will work better for you.
Problem: As an Apigee proxy developer/architect, I would like to best architect API proxies so that I can modify the backend URLs for a given resource for subset of API consumers. API consumers will have their own unique domains that they use to access the APIs.
To have the same context throughout, here is some material we can use to work with:
Consumer Groups that represent groups of consumers that access resources at the same domain for that consumer group:
consumer group A
consumer group B
The backends that may change out:
Backend A
Backend B
Solutions: This may sound like a simple problem on its surface, but as we dig in deeper, we’ll see the seams. It’s at those seams that we will have to pick and choose what advantages we want and what concerns we can accept. Let’s start with a bad solution and work from there.
A Bad Solution:
Create a single proxy for resource1 with multiple target endpoints to accommodate for each API Consumer Group. All virtual hosts are included in the proxy endpoint for that proxy. If a backend URL needs to change for a consumer group, update the target endpoint and redeploy the proxy. E.g., consumer group A and consumer group B both use backend X. Target endpoint 1 (for consumer group A) and target endpoint 2 (for consumer group B) both point to backend X. But now there is a change required where consumer group A needs to use backend X and consumer group B needs to use backend Y, and so target endpoint 2 is updated and the whole proxy is redeployed.
Why is this bad? Every time a backend needs to change for 1 consumer group, all other consumer groups are also affected because they all share the same proxy. This causes unnecessary downtime. In addition, this design introduces unnecessary risk by requiring changes to a proxy that may affect consumer groups that are not changing. Also, this design is brittle since the proxy endpoint is shared between all consumer groups. You could try to push that logic to the target endpoint, but you lose the flexibility in the proxy endpoint. Last, this proxy will be huge and will keep growing with additional consumer groups; it may take a long time for the supporting runtime infrastructure to load such a large proxy bundle (and worse yet, many of them!).
Better Solutions: Here are other solutions that are better, but each has their own drawbacks. Which one did we use in the end? You’ll have to read on to find out.
Option A
A. Reserve an environment per consumer group. In this solution, the vhost name will be the same (e.g., vhost1), but the vhost will map to a different domain name in each environment (this is out-of-the-box in Edge). As a change in target URL is required, create a new revision and deploy that new revision to the corresponding environment.
Option B
B. Create 2 proxy layers with the first layer directing to the appropriate proxy in the second layer. Can use KVM/JS to maintain mapping relationship between proxy layers so that redeployment isn’t required with changes. The first proxy layer can be varying levels of abstraction: a single proxy for all proxies or 2-to-n set of proxies than fan out to the second layer where n is the total number of resources. The first proxy layer could also employ multiple target endpoints depending on how much flexibility is needed (e.g., if you wish to use proxy chaining).
Option C
C. 1 vhost per consumer group with a separate proxy per consumer group for a given resource (e.g., proxy1-consumergroupA, resource1-consumergroupB, etc.).
Option D
D. 1 vhost per consumer group with a single proxy shared across consumer groups - rearrange vhost assignments in proxy revisions. When a consumer group, as represented by its own vhost, needs to be partitioned out, create a new revision with the new vhosts separated out.
And so where did we end up? Turns out we went with option A since it was easiest to manage and had clear separation between environments. It also didn’t have huge problems like option D. Your mileage may vary, as your requirements and what pros/cons are most important to you will change your decision making.
Please post feedback, as we’d love to hear your thoughts.