Apigee QueryParam for get

Hi Team,

/person/?name ={dynamic val} & number= {dynamic val} & place = {dynamic val}                   (or)
/person/?name ={dynamic val} & number= {dynamic val}

Need a condition to block requests with above params alone

/person/?name ={dynamic val} & number= {dynamic val} & houseNo = {dynamic val}

If we get request with any other combinations alone with name and number except place, it has to allow without blocking.

e.g,, the above url with name, number & houseNo combination it has to allow without blocking

Tried,

<Condition>((proxy.pathsuffix ~~ "/person/?") and
                        ((request.queryparam.name != null and request.queryparam.number != null )
               or     (request.queryparam.name != null and request.queryparam.number != null and                                              request.queryparam.place != null)) and
                       (request.verb = "GET"))

</Condition>

in the above condition it is blocking for the below url as well. It has to allow withOut blocking, can someOne pls assist.

/person/?name ={dynamic val} & number= {dynamic val} & houseNo = {dynamic val}


Thanks,
Vidya

0 2 87
2 REPLIES 2

I think you need a truth table.  Something to help express exactly what should be allowed and not allowed.  

First let us stipulate that only GET /person requests will be allowed. Any non-GET or any GET on something other that /person, will be rejected. So the eventual condition must consider that, but in the truth table we want to look only at query param presence.

 

name number houseNo place Allow?
not present either either either NO
present not present either either NO
present present not present either NO
present present present not present YES
present present present present ??
? ? ? ? ?

If I understand correctly you want to allow requests only if they include qparams {name, number, houseNo} . And I am not sure about rejecting or allowing requests with place. 

After you get the truth table, translating that into a Condition should be relatively easy. I think the building blocks are

  • verb GET
  • pathsuffix /person
  • qparams name, number, houseNo present
  • don't care about any other qparams

in which case your condition is

<Condition> request.verb = "GET" AND
      proxy.pathsuffix ~~ "/person/?" AND
      request.queryparam.name != null AND
      request.queryparam.number != null AND
      request.queryparam.houseNo != null</Condition>

Conditions like this are usually employed in "Conditional Flows" in Apigee.  For example, like this:

<ProxyEndpoint name='endpoint1'>
  ...
  <Flows>
    <Flow name='flow1'>
    <Condition> request.verb = "GET" AND
      proxy.pathsuffix ~~ "/person/?" AND
      request.queryparam.name != null AND
      request.queryparam.number != null AND
      request.queryparam.houseNo != null</Condition>
    <Request>
      ...policy steps for request...
    </Request>
    <Response>
        ...policy steps for response...
    </Response>
  </Flow>
   ...

Keep in mind you can add validation within the flow, to provide better feedback to the calling client app.  Often people use a "verb + path" check in the condition for the flow, and then subsequent validation of the headers or queryparams within the flow.  For example, like this: 

<ProxyEndpoint name='endpoint1'>
  ...
  <Flows>
    <Flow name='flow1'>
      <Condition> request.verb = "GET" AND proxy.pathsuffix ~~ "/person/?"</Condition>
      <Request>
        <Step>
          <!-- reject calls that do not have the required qparams -->
          <Condition>request.queryparam.name = null OR
      request.queryparam.number = null OR
      request.queryparam.houseNo = null</Condition>
          <Name>RF-Invalid-Request-Missing-Qparam</Name>
        </Step>
        ...more policy steps for request...
      </Request>
      <Response>
        ...policy steps for response...
      </Response>
    </Flow>
     ...

And in this case RF-Invalid-Request is a RaiseFault policy that sends back a message indicating that there is a missing qparam. 

This is the kind of structure I recommend.  Then augment that with a "catch all flow" that responds when the request is not GET /person.  Like so: 

<ProxyEndpoint name='endpoint1'>
  ...
  <Flows>
    <Flow name='flow1'>
      <Condition> request.verb = "GET" AND proxy.pathsuffix ~~ "/person/?"</Condition>
      <Request>
        <Step>
          <!-- reject calls that do not have the required qparams -->
          <Condition>request.queryparam.name = null OR
      request.queryparam.number = null OR
      request.queryparam.houseNo = null</Condition>
          <Name>RF-Invalid-Request-Missing-Qparam</Name>
        </Step>
      ...more policy steps for request...
      </Request>
      <Response>
        ...policy steps for response...
      </Response>
    </Flow>
    <Flow name='unsupported-request'>
      <!-- no condition here. it handles all requests not matched above -->
      <Request>
        <Step>
          <Name>RF-Bad-Request</Name> <!-- will send back 400 or 404 -->
        </Step>
      </Request>
    </Flow>
  </Flows>
   ...

Hi @dchiesa1 ,

Thank you for your response.

Let me put it in this way,

 

 NamenumberHouseNoAddressAllow ?
Api  1presentpresentnot presentnot presentYes
Api  2presentpresentpresentnot presentNo
Api 3presentpresentnot presentpresentNo

I need to apply some policy only if the url is, "/person/?name ={dynamic val} & number= {dynamic val}"

for the above url, I wrote the condition like

<Condition>proxy.pathsuffix ~~ "/person/?" and
                       request.queryparam.name != null and
                       request.queryparam.number != null
</Condition>"

But the problem is,  the above condition is allowing the url with query params
1. "/person/?name ={dynamic val} & number= {dynamic val} & houseNo= {dynamic val}"
2. "/person/?name ={dynamic val} & number= {dynamic val} & address= {dynamic val}"
as well, along with
"/person/?name ={dynamic val} & number= {dynamic val}"

So, Modified the condition to ,

<Condition>proxy.pathsuffix ~~ "/person/?" and
                      request.queryparam.name != null and
                     request.queryparam.number != null and
                    request.queryparam.houseNo == null and
                     request.queryparam.address == null
</Condition>".  This condition is accepting "/person/?name ={dynamic val} & number= {dynamic val}" alone

My question is instead of using request.queryparam.address== null & request.queryparam.houseNo == null in condition, do we have any condition to restrict the query params to name and number alone / I don't want to use request.queryparam.address & request.queryparam.houseNo in condition as my policy restricted to name and number.., any other way can we write the condition using name & number alone withOut using address & houseNo in the condition ?

Thanks,
Vidya