How to append path to outgoing requests

I am new to Apigee and I’m confused how I can make this to work

I’ve a backend API with 4 operations

 

POST /users/register
PUT /users/{id}
GET /users/{id}
DELETE /users/{id}


If I understood it right I create one proxy API with 4 flows in proxyendpoints and targetendpoints

The target endpoint path is different from proxy endpoint so I suppress from being copied using

 

context.setVariable("target.copy.pathsuffix", false)

Now since each operation has a different path I don’t have path defined

<HTTPTargetConnection>
    <LoadBalancer>
        <Server name="abc"/>
    </LoadBalancer>
</HTTPTargetConnection>

Question: How can I add path to the outgoing request for each operation. I’ve tried using assign message with set path but doesn’t work.

If using route rules for each operation how can I add the id to outgoing request.

  1. <HTTPTargetConnection>
        <LoadBalancer>
            <Server name="abc"/>
        </LoadBalancer>
        <Path>/somepath/{id}</Path>
    </HTTPTargetConnection>
0 2 458
2 REPLIES 2

HI,  don't create separate target flows for each operation in this scenario.  best approach would be as below. 

1. just create a javascript policy to fix the targetpath in  request flow under target postflow.  sample javascript. 

var pathsuffix = context.getVariable("proxy.pathsuffix");
context.setVariable("target.copy.pathsuffix", "false");
if( ( pathsuffix.startsWith("/users") ){
pathsuffix = pathsuffix.replace('users', 'newpath')
}
context.setVariable("mytarget.path", pathsuffix);

2. add mytarget.path to HTTPTargetConnection as below.

<Flows/>
<HTTPTargetConnection>
<SSLInfo>
<Enabled>true</Enabled>
</SSLInfo>
<Properties>
<Property name="success.codes">1xx,2xx,3xx,4xx,5xx</Property>
</Properties>
<LoadBalancer>
<Server name="TS-Server1"/>
</LoadBalancer>
<Path>{mytarget.path}</Path>
</HTTPTargetConnection>

 

 

If I understood it right I create one proxy API with 4 flows in proxyendpoints and targetendpoints

Well, yes maybe. Apigee acts as a reverse proxy, which means, by default when you send a request into Apigee, it sends a different request, but a request shaped almost exactly the same, to the target you've configured. Which means, even if your API has PUT /foo/{n} and GET /foo/{n}, you do not need to configure conditional flows within the Apigee proxy.  An Apigee proxyendpoint configured like this: 

 

  <Flows>
    <Flow name="t1">
      <Request>
      </Request>
      <Response>
      </Response>
      <Condition>proxy.pathsuffix MatchesPath "/t1" and request.verb = "GET"</Condition>
    </Flow>

    <Flow name="t2">
      <Request>
      </Request>
      <Response>
      </Response>
      <Condition>proxy.pathsuffix MatchesPath "/t2" and request.verb = "POST"</Condition>
    </Flow>

  </Flows>

 

...will behave exactly the same as an Apigee proxy configure with this for the conditional flows: 

 

<Flows/>

 

If you are a programmer, the first example is as if you did this: 

 

if (request is "GET /t1") {
}
if (request is "POST /t2") {
}

 

 

Send a PUT /foo/{n} into an Apigee proxy with no Conditional flows and it will happily send a proxied PUT request to your target. You may want to configure conditional flows in the proxy endpoint in an Apigee API proxy if you want special, distinct handling for each type of request. For example if you want to verify an Oauth token when the request is PUT, but don't verify anything when the request is GET.... You'd need conditional flows of the type you described, in order to accomplish that.

Another case where you'd want conditional flows is if you want Apigee to validate that the inbound requests are good, before sending to the upstream. If your upstream system accepts only PUT, POST, GET, on specific paths, then you can configure Apigee to accept only those, and send back an error message for any request that does not comply with your interface. This might look like this: 

 

  <Flows>
    <Flow name="t1">
      <Request>
      </Request>
      <Response>
      </Response>
      <Condition>proxy.pathsuffix MatchesPath "/t1" and request.verb = "GET"</Condition>
    </Flow>

    <Flow name="t2">
      <Request>
      </Request>
      <Response>
      </Response>
      <Condition>proxy.pathsuffix MatchesPath "/t2" and request.verb = "POST"</Condition>
    </Flow>

    <Flow name="unknown request">
      <Request>
        <Step>
          <Name>RF-Unknown-Request</Name>
        </Step>
      </Request>
      <Response>
      </Response>
    </Flow>
  </Flows>

 

...where that "RF-Unknown-Request" is a RaiseFault policy that sends back an error message of your choice.

Alternatively, if you use no conditional flows, then you will allow Apigee to proxy all requests (even unsupported ones) to the upstream system, and you'll let the upstream system generate the error message. Which option is preferable, is sort of up to you.

Last thing about conditional flows: it's less common to ever need conditional flows in both the proxy endpoint AND in the target endpoint for each kind of request (PUT /foo/{n}, GET /foo/{n}). If you are doing the conditional flows thing, for one of the reasons I described above, you probably want that in the proxyendpoint, and probably not in the targetendpoint. You can use conditional flows in the targetendpoint if there is a need to perform some specific action on a subset of requests being sent to a specific target. Other than that, you can mostly avoid setting in conditional flows in your target. It's an area of flexibility in Apigee that is sort of advanced, you probably don't need it for simple cases.


The target endpoint path is different from proxy endpoint so I suppress from being copied using

context.setVariable("target.copy.pathsuffix", false);

That sounds good.


How can I add path to the outgoing request for each operation. I’ve tried using assign message with set path but doesn’t work.

You can use AssignMessage to set the path. The problem is, if you have target.copy.pathsuffix as false, then.... the path you're setting doesn't get propagated to the request that is sent to the target.  So, you'll want to manipulate the variable "target.url" directly.  Something like this in a JavaScript policy: 

 

var pathSegment = 'whatever you like here';
context.setVariable('target.url', '/my_dynamic_path/' + pathSegment ) ;

 


how can I add the id to outgoing request.

If you're manipulating the path directly, and there is no direct correspondence to the path on the request that arrives at "the front door" and the path going out "the back door", then... Javascript might help you. You'd need to parse and extract the path elements, and then assemble the thing you want.