Route Rule Conditions for Sub Resources

jurgenroos
Participant I

Hi

We have the following resources available for consumption and want to develop custom route rules & conditions, however I am having problems hitting the relevant resource.

The Base URI of the proxy is api.com/v1/

api.com/v1/customers/{id}/ - Host A

api.com/v1/customers/{id}/subscriptions/{id2} - Host B

I have the current rules in place but they do not work for nested resources:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ProxyEndpoint name="default">
    <Description/>
    <FaultRules/>
    <PreFlow name="PreFlow">
        <Request/>
        <Response/>
    </PreFlow>
    <PostFlow name="PostFlow">
        <Request/>
        <Response/>
    </PostFlow>
    <Flows/>
    <HTTPProxyConnection>
        <BasePath>/v1</BasePath>
        <Properties/>
        <VirtualHost>secure</VirtualHost>
    </HTTPProxyConnection>
        <RouteRule name="SubscriptionRoute">
        <Condition>request.path ~ "*/subscriptions/"</Condition>
        <TargetEndpoint>default</TargetEndpoint>
    </RouteRule>
    <RouteRule name="CustomerRoute">
        
        <Condition>request.path ~ "*/customers/"</Condition>
        <TargetEndpoint>Target2</TargetEndpoint>
    </RouteRule>


    
</ProxyEndpoint>

Can anyone advise me how I should write my rules to allow access to sub resources and to short circuit directly to the customers/{id} endpoint if no resource is appended to this?

Solved Solved
0 5 1,744
1 ACCEPTED SOLUTION

Hi,

If you want to route on

customers/{id}/ - Host A

/customers/{id}/subscriptions/{id2} - Host B

Then you can use matches:

~ /customers/*

~ /customers/*/subscriptions/*

However, as customers/* would also match customers/*/subscriptions/* then you'll need to put the more specific match first. Route rules are evaluated top to bottom and only the first hit is actioned.

If you then want a generic catch all for everything else then use a default route rule after your matches. See here for an example bringing that together:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ProxyEndpoint name="default">
    <Description/>
    <FaultRules/>
    <PreFlow name="PreFlow">
        <Request/>
        <Response/>
    </PreFlow>
    <PostFlow name="PostFlow">
        <Request/>
        <Response/>
    </PostFlow>
    <Flows/>
    <HTTPProxyConnection>
        <BasePath>/routetest</BasePath>
        <Properties/>
        <VirtualHost>default</VirtualHost>
        <VirtualHost>secure</VirtualHost>
    </HTTPProxyConnection>
    <RouteRule name="CustomerRoute">
        <Condition>proxy.pathsuffix ~ "/customers/*/subscriptions/*"</Condition>
        <URL>http://httpbin.org/get/c2</URL>
        <TargetEndpoint>default</TargetEndpoint>
    </RouteRule>
    <RouteRule name="SubscriptionRoute">
        <Condition>proxy.pathsuffix ~ "/customers/*"</Condition>
        <URL>http://httpbin.org/get/c1</URL>
        <TargetEndpoint>default</TargetEndpoint>
    </RouteRule>
    <RouteRule name="default">
        <URL>http://httpbin.org/get</URL>
        <TargetEndpoint>default</TargetEndpoint>
    </RouteRule>
</ProxyEndpoint>

View solution in original post

5 REPLIES 5

Hi,

If you want to route on

customers/{id}/ - Host A

/customers/{id}/subscriptions/{id2} - Host B

Then you can use matches:

~ /customers/*

~ /customers/*/subscriptions/*

However, as customers/* would also match customers/*/subscriptions/* then you'll need to put the more specific match first. Route rules are evaluated top to bottom and only the first hit is actioned.

If you then want a generic catch all for everything else then use a default route rule after your matches. See here for an example bringing that together:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ProxyEndpoint name="default">
    <Description/>
    <FaultRules/>
    <PreFlow name="PreFlow">
        <Request/>
        <Response/>
    </PreFlow>
    <PostFlow name="PostFlow">
        <Request/>
        <Response/>
    </PostFlow>
    <Flows/>
    <HTTPProxyConnection>
        <BasePath>/routetest</BasePath>
        <Properties/>
        <VirtualHost>default</VirtualHost>
        <VirtualHost>secure</VirtualHost>
    </HTTPProxyConnection>
    <RouteRule name="CustomerRoute">
        <Condition>proxy.pathsuffix ~ "/customers/*/subscriptions/*"</Condition>
        <URL>http://httpbin.org/get/c2</URL>
        <TargetEndpoint>default</TargetEndpoint>
    </RouteRule>
    <RouteRule name="SubscriptionRoute">
        <Condition>proxy.pathsuffix ~ "/customers/*"</Condition>
        <URL>http://httpbin.org/get/c1</URL>
        <TargetEndpoint>default</TargetEndpoint>
    </RouteRule>
    <RouteRule name="default">
        <URL>http://httpbin.org/get</URL>
        <TargetEndpoint>default</TargetEndpoint>
    </RouteRule>
</ProxyEndpoint>

Thank you, this worked perfectly

<URL>http://httpbin.org/get/c1</URL>
what is the meaning of this ?(inside route rule)

You'll need to ask a new question and provide more information and more context when you ask.

The URL element refers to the destination endpoint where traffic is routed to. In this case, if the first route rule matches, it will forward the traffic to

http://httpbin.org/get/c1