Duplicate BasePath with Wildcard Domain

Hi guys,

instead of having a unique base-path we want to use a Wildcard Domain such as  *.api.example.com and then every proxy gets his unique name such as:

 

test-api1.api.example.com
test-foo.api.example.com
xxx.api.example.com

...
there-are-more.api.example.com
...

 

 

As far from the documentation I've seen its possible to Setup a Virtual Host with a Wildcard Domain, but How can I configure: Proxy is enabled on VHost X for Domain [singlematch].api.example.com

 

Background is that we have multiple APIs having the same path structures and we don't want to prefix them.

1 19 760
19 REPLIES 19

I've seen its possible to Setup a Virtual Host with a Wildcard Domain...

Yes, In Apigee Edge, It's possible to set up a Virtual Host with a wildcard hostname and wildcard certificate.

But in Apigee Edge, an API proxy listens on one or more Virtual Hosts. You cannot configure a proxy to listen to only a subset of hostnames that are supported by the wildcard virtualhost.

You could ... design a "front door" proxy that listens on the wildcard vhost, and then interrogates the hostname, and routes to a different proxy based on that hostname. As an example, the front door might:

  • route requests for host1.example.com and host2.example.com into proxyA,
  • route requests for host3.example.com into proxyB
  • route all other requests into proxyC

And it can be done via LocalTargetConnection, which means it will be relatively fast to invoke the second-layer proxies. 

The "inner proxies" (behind the front door) would listen on a virtualhost that has an unpublished hostalias associated to it.  So they would never receive direct requests.  Only indirect requests from the front door. 

This will "work" in that inbound requests will be handled by different proxies. But it would not use the vhost and hostalias for the 2nd layer of routing.  For that you would need routing rules encoded in the front door proxy. 

I am not sure if this solves the particular problem you are facing. 

@dchiesa1  do you have any example for such a Front-Door proxy? Ideal would be an example which dynamically set the LocalTargetConnection, because I am talking about 200-800 different apis. We have naming schema, so that would be no problem for me then to adapt.

Thank you in advance

800 different APIs routed this way?  While the "front door" proxy pattern might be useful for some limited purpose, I think it is not a suitable pattern to route to 800 different proxies based on hundreds of different hostnames. 

I think it's a mistake to try to use Apigee in this way.  Apigee is designed to route requests into proxies based on vhost+basepath, where the vhost can have one or more host names associated to it (or a wildcard).  What you are trying to do is not in harmony with that aspect of  the design of Apigee. It will be difficult to express and difficult to maintain. 

Also, I believe that the design choice to route to different proxies based on different hostnames, even with the same basepaths!, is a poor one if you are supporting API clients.  

We see some people trying to adapt Apigee to support non-API use cases, trying to convert Apigee into a general purpose proxy. That's not what it is, not what it is intended to do. 

If I were you I would look for better ways to solve the problem.  Two I can think of are: 

  • use a different tool to solve the problem you described
  • change the problem, change the design you are aiming for and abandon the idea to use 100's of different hostnames for your API endpoint, or abandon the idea to use DISTINCT PROXIES for those different hostnames. 

Are you sure you need to route requests for specific hostnames to specific proxies?  And 800 of them?  That seems really odd and unique. 

@dchiesa1 we have already a subscription and the plan is to use apigee as a company wide API-Gateway-Solution. So you can imagine we have a lot of different APIs. 

 

So you're telling me apigee is no fit for having > 500 proxies and using this as a company wide solution? Because the sales persons told us back then that's something easy to handle for apigee or do I understand it wrongly?

 

Main goal is not having at the end of the day long workaround base-path-prefixes to avoid collisions.

 

Since I've seen that only 20 vhosts are allowed, but on private cloud there is no limitation. Do you know if we can raise that limit via a support request or even get rid of it? So we could just create one vhost per proxy.

 

Thank you.

So you're telling me apigee is no fit for having > 500 proxies and using this as a company wide solution? Because the sales persons told us back then that's something easy to handle for apigee or do I understand it wrongly?

Apigee is not a good solution for routing to ~500 proxies based on 500 hostnames. That's not how Apigee works. In my response above, I explained that Apigee routes based on the tuple of vhost and basepath. If you want to use a wildcard vhost, Apigee cannot route by hostname. This is all explained in my lengthy replies previously. If you re not clear on this point, maybe you can read them again and ask questions to clarify if necessary.

Apigee is used in many companies with 1000's of API proxies, tens of 1000's. These companies use the routing that Apigee is designed for. They don't route to proxies based on hostname, with a single wildcard vhost. There is o(10) hostnames, often ONE hostname. And then route to proxies based on the inbound basepath. That is the model Apigee uses. That is the convention happy customers observe. If you or your team did not understand that when you committed to Apigee, then there's been a mistake somewhere in the dialogue.

The front door approach I described works for a handful of hostnames. Not for 100's of hostnames. It's a bad idea. It's against the design of Apigee. It won't be fun to maintain. I cannot endorse that pattern of usage for ~500 proxies.

Do you know if we can raise that limit via a support request or even get rid of it? So we could just create one vhost per proxy.

You cannot raise the limit. The support team cannot raise the limit if you ask, even if you insist. It is not possible.

I suggest you re-consider your technical requirements and try to adapt your solution to the ability of the tool, or use a different tool. 

@dchiesa1 Thanks for giving that quite fast answers. So these companies just use a bunch of virtual hosts and have their > 1000 proxies behind the basePath structure or do they just use multiple apigee orgs, so they sharded these things?

 

Regarding the limit question, just to be 100% sure, I meant here the 20 Virtual Hosts per organisation. So that's a full hard limit? Even it was not enforced longer time ago?

You are limited to 20 vhosts per organization in Apigee Saas. You have apparently seen the documentation, since you quoted the limit to me. 

screenshot-20220330-150330.png

Most companies map their Apigee organizations to SDLC stages.  Production gets one organization. 

I am a bit slow, but at this point I have got the feeling you are just scanning me for information. And maybe beyond collecting information, you're not really trying to solve a problem at all. 

If you do have a specific problem to solve, please do contact your Customer Engineer directly for further information!  That person will be able to help you.

Good luck in any case.

@dchiesa1 In case its both - information + solving a real problem. A system that is planned to be replaced by apigee used to have everything sorted out by different hostnames such as "foo-api.[stage].somedomain.com" so people just got injected in their deployments a different hostname as an Environment-Variable. What we try to avoid here that people have to change their code.

Thanks for questions and answers, exactly as same as our case.

 

@dchiesa1 , 

If I use the way you recommend, and proxies behind "front door" is about 100 -200 proxies.

Do you think it is workable? Thanks.

```

You could ... design a "front door" proxy that listens on the wildcard vhost, and then interrogates the hostname, and routes to a different proxy based on that hostname. As an example, the front door might:

  • route requests for host1.example.com and host2.example.com into proxyA,
  • route requests for host3.example.com into proxyB
  • route all other requests into proxyC

```

Well I don't know  if my prior suggestion is workable or preferable at this point. The answers I provided pertained to Apigee Edge. Of course now, for new deployments of Apigee, people will use Apigee X.  And if you are using Apigee X,  you can perform routing and URL rewriting at the External Load Balancer within Google Cloud.  You have complete control  and you can modify paths at the load balancer to take the role of the "front door" that I described .  And by modifying the path, you would be able to invoke different API proxies. 

I would like to make an additional comment.  If what we are talking about is allowing different customers or partners to invoke distinct API proxies that have been set up specifically FOR THEM, I  think the idea is a poor one. The idea of having distinct API proxies for each customer is not scalable, nor is it particularly maintainable. Do you maintain different phone numbers for every person who might contact you?  Of course not.  You have one phone number.  OK, maybe you have a work number and a personal number, but just a handful, not a different number for every person who might reach out to you. 

In the same way, why have a distinct hostname for each partner or customer? Your business can be reachable at api.buinessname.com . Why does it need to be different?     Better to publish a single endpoint, and then distinguish between requests from different partners or customers based on the CREDENTIALS that the inbound API request carries. This is an OAuth token, or an API key, or something else, maybe a digitally-signed payload that carries a keyid.   But regardless , the inbound request will identify the source of the request , including the customer ID.  And then you can conditionally handle the request based on the identity of the customer if you wish.  

For example, customer A might have permission to do X,Y, and Z, while customer B might have access only to X.  This is easy and straightforward to do in Apigee, using the power of API products and API credentials (keys and secrets and tokens). 

So. 

Maybe that gives you something to think about. 

 

Thanks @dchiesa1  for your suggestions.

Could we set aside "API domain design" temporarily and talk about apigee technical possibility.

I tried with "one front door proxy" as  https://www.youtube.com/watch?v=gSv48sGJMls, seems not work.

Design:

One vhost: vs-johntest-frontdoor-project1
Three host alias:
svc01-project1.dev.oc.hp.com
svc02-project1.dev.oc.hp.com
svc03-project1.dev.oc.hp.com

Here is proxy design:

Proxy:
johntest-frontdoor-project1
=>
johntest-svc01-project1 => targetServer: https://httpbin.org/get?id=svc01-project1
johntest-svc02-project1 => targetServer: https://httpbin.org/get?id=svc02-project1
johntest-svc03-project1 => targetServer: https://httpbin.org/get?id=svc031-project1

Note that all basepath is same: "/"

During my proxy creation, it is required to select virtual host. So, I link all proxies with one virtual host "vs-johntest-frontdoor-project1". I created four proxies successfully.

Now I deployed johntest-svc01-project1  proxy, and it works as expected.

I want to deploy another proxy johntest-svc02-project1 , it failed with below error:

Error Deploying Revision 1 to dev
Path / conflicts with existing deployment path for revision 1 of the APIProxy johntest-svc01-project1 in organization hpcorp-columbia, environment dev

Seems virtualHost + BasePath must be unique!

Do you know how to resolve it? Thanks.

 

 

 

 

Hi, John.

Seems virtualHost + BasePath must be unique!

Correct. Apigee Edge uses the VirtualHost concept, and in Apigee Edge, the combination of vhost+basepath must be unique across all deployed proxy revisions. There is no way to change that behavior.

I am not clear on exactly the reqiurement here, because we've resuscitated a thread from nearly 2 years ago. But I think you want to route requests to multiple different proxies. In Apigee Edge, the easiest way to route inbound requests to different proxies is to use the left-most path segment as the discriminator. The basepath that you use in a proxyendpoint specifies the leftmost path segment for requests that the proxy will handle. So supposing you have these proxies

proxy name basepath
proxy1 /p1
proxy2 /p2
proxy3 /p3
   

..then , for an inbound request to https://myhost/p1 gets routed to proxy1, and https://myhost/p2 gets routed to proxy2.

Another way you can discriminate inbound requests in Apigee Edge is using the hostname. If you create multiple different VirtualHosts with distinct host names , and deploy proxy1 to vhost1, and proxy2 to vhost2,  then you can do something like this:

inbound request proxy that handles it
https://myhost1/anything proxy1
https://myhost2/anything proxy2
...  

If you don't like either of those options, because for some reason you don't want to use the leftmost pathsegment and you ALSO don't want to use the hostname as a discriminator, then you need to do something else to be able to "route" inbound requests to different proxies.  The options  as I see them are: 

  • use an external WAF or load balancer or url rewriter to do that.    OR
  • build what we are calling a "front door" proxy that does the rewriting.

It's the same approach, it's just that in the latter case you are using Apigee itself as the router/load-balancer.

In either case, you're just building a layer on top of the request routing facility that exists in Apigee Edge. The only benefit is, the hostname or leftmost path segment isn't exposed to external callers or clients.   But Edge will still use the combination of hostname+pathprefix as the way to route requests to distinct proxies, so your "rewriter" is just "hiding" that. 

What I mean by "hiding" - an inbound request might include a "X-DESIRED-TARGET" header, and the WAF or "front door" could examine that, and then rewrite the inbound request accordingly, with a unique host+pathprefix, so that Edge can do its thing. 

If you use the "front door" proxy,  it needs access to "the map".  The rules that say "this request goes to proxy1, this other request goes to proxy2, etc."   It would be up to you to define that map, and what the discriminator is. You could use, as a discriminator, a specially defined header, or the leftmost segment in the path, or a queryparam, or a form parameter, OR something else in the request. (For now we are assuming all inbound requests use the same hostname).

THEN, in the front-door proxy you can use the "chained proxy" feature as described in Anil's video, but you will need to use a Path:

   <LocalTargetConnection>
        <Path>{this-is-a-message-template}</Path>
    </LocalTargetConnection>

...and the value of variable that holds the path will be determined by the application of your url mapping logic.  Maybe in JavaScript. 

Does this help?

 

Thanks @dchiesa1 

Let us talk about "build what we are calling a "front door" proxy that does the rewriting."
I assume this can be implemented in apigee proxy, right?
Can you provide us an example? Thanks.

Referring to https://www.youtube.com/watch?v=gSv48sGJMls, considering your upper suggestion,
I tried below, but still fail.

Design:
One vhost: vs-johntest-frontdoor-project1
Three host alias:
- svc01-project1.dev.oc.hp.com
- svc02-project1.dev.oc.hp.com
- svc03-project1.dev.oc.hp.com


Front Proxy: johntest-frontdoor-project1
vhost: vs-johntest-frontdoor-project1
basepath: "/"

Three behind proxy:
First proxy: johntest-svc01-project1
- vhost: vs-johntest-frontdoor-project1
- basepath: "/svc01-project1"
- targetServer: https://svc01-project1.internal-api.test.com

Second proxy: johntest-svc01-project1
- vhost: vs-johntest-frontdoor-project1
- basepath: "/svc02-project1"
- targetServer: https://svc02-project1.internal-api.test.com

Third proxy: johntest-svc03-project1
- vhost: vs-johntest-frontdoor-project1
- basepath: "/svc03-project1"
- targetServer: https://svc03-project1.internal-api.test.com

Note that vhost are same.

Test Result:
Three behind proxies are all created / deployed / test successfully.

But when I deploy front proxy, it raise error.
Error Deploying Revision 1 to dev
Path / conflicts with existing deployment path for revision 1 of the APIProxy johntest-svc01-project1 in organization hpcorp-columbia, environment dev.

Ok, path cannot overlap for all proxies with same virtualhost.
What's your suggestion?

I am thinking whether basepath support NOT, like
basePath not start with "NOT /svc/*"
Is it possible?

Thanks!

What revision, or revisions, of the proxy  johntest-svc01-project1 are deployed? 

Is it possible that you deployed it previously with a basepath of / ?

If you

  1. create a proxy with a basepath of /basepath1
  2. then delpoy it
  3. then modify it so that it has a basepath of /basepath2
  4. then deploy it

...the first deployed revision does not get undeployed automatically. 

Normally the "basepath conflict" has to be an exact match.  So when you see a message like

Path / conflicts with existing deployment path for revision 1 of the APIProxy johntest-svc01-project1 in organization hpcorp-columbia, environment dev.

That means revision 1 of APIProxy johntest-svc01-project1 has a basepath of / 

Can you check?

Thanks @dchiesa1 

If I deploy the proxy with basepath lastly, it deployed successful. The proxy chain works well.

In frontdoor proxy, need define like below

<RouteRule name="svc01-project1">
<TargetEndpoint>johntest-svc01-project1</TargetEndpoint>
<Condition>(request.header.Host = "svc01-project1.dev.oc.hp.com")</Condition>
</RouteRule>

<RouteRule name="svc02-project1">
<TargetEndpoint>johntest-svc02-project1</TargetEndpoint>
<Condition>(request.header.Host = "svc02-project1.dev.oc.hp.com")</Condition>
</RouteRule>

Target endpoint in proxy like:
```

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<TargetEndpoint name="johntest-svc02-project1">
<Description/>
<FaultRules/>
<PreFlow name="PreFlow">
<Request/>
<Response/>
</PreFlow>
<PostFlow name="PostFlow">
<Request/>
<Response/>
</PostFlow>
<Flows/>
<LocalTargetConnection>
<APIProxy>johntest-svc02-project1</APIProxy>
<ProxyEndpoint>default</ProxyEndpoint>
<Path>/svc02-project1</Path>
</LocalTargetConnection>
</TargetEndpoint>

```

All proxy has same virtualhost.

 

 

Thanks for confirming 

Hi @dchiesa1  - love how you protect your strong opinions on things. 

But you have to look over the edge and be more creative what apigee could be used for? Just think about using the features of apigee as a service for other customers within the company.

So it's naturally that they want to have their special domains or even in this case a certain domain where they get their own space. You might now suggest they should get their own apigee org, but that adds other complexity as well costs.

I agree on your view in regard of having a single API like api.example.com or so. But our case is a bit more complex since we have a lot of teams, lot of apis - we are talking here about > 5000 APIs with different concerns etc.

That's a good counterpoint.  I was not considering a LARGE company and the need for federated publishing of APIs by distinct teams.

How many different inbounds will there be?  If it's ~1000, you can't use Apigee to manage all those hostnames. I think the max number of vhosts in Edge is something like 100.  

If you could group the 5000 APIs into no more than 100 sets (no more than 100 teams), then ... I suppose each API-publishing team could use its own hostname.  Same Apigee org, 100 vhosts, and there ya go. 

But if you have the need for more than 100 unique hostnames, or whatever the limit is, then I think you'll need a different approach, like the url-rewriting idea that I am exploring here with John.