How do I map a Custom attribute on an API Product to a queryparam for the upstream request?

In short, our company has a product called the Airsafe Datastream - All Suppliers. It has a few query parameters which limit what is returned to the client when calling this API. In this case, the query parameter for the product is icao_address. You give it strings separated by a comma to filter the results. Example:

curl --max-time 30.0 -H 'Authorization: token' https://api.airsafe.spire.com/stream?icao_address=8880F7,A1314E,780B7F,A96B80,71BC19,7816BE,4BA94C 78115C

What I'm trying to implement is a product that runs on the same API proxy as the /stream endpoint but from the initial start at runtime, it already has a defined query parameter of strings

. (in the example above, during the API call I gave it the query strings as a filter and for this product it will be the default string from the getgo) So in our case, the customer only gets the records from the API call that we have already pre-determined and won't need to add any additional query filter. So on Apigee UI, I made the following product with the following attributes in the field records:

  1. API Proxies -> Airsafe-API
  2. Product name -> Airsafe Datastream - Tail
  3. Path -> /stream
  4. Custom Attributes: icao_address -> 8880F7,A1314E,780B7F,A96B80,71BC19,7816BE,4BA94C 78115C

I then went and added this new product to an existing developer: 1. Went to a developer account and added the product: Airsafe Datastream - Tail Issue: When I call the product Airsafe Datastream - Tail, I still get all the records as if calling the Airsafe Datastream - All Suppliers. That is, without any filtering by icao_address. It also isn't implementing my custom attribute filter of icao_address; which would mean it only returns the records with icao_address: 8880F7,A1314E,780B7F,A96B80,71BC19,7816BE,4BA94C 78115C as specified in the custom attribute section when I made the new product.

For example, what I expect calling this product: If you look at the key 'icao_address' in the image below, it is equal to a value specified in the custom attribute of the product Airsafe Datastream - Tail Only that I created. Again, this is NOT what's actually happening.

{"target":{"icao_address":"8880F7","timestamp":"2020-05-20T04:01:58Z","latitude":55.047913,"longitude":27.402891,"altitude_baro":39975,"heading":250.0,"ground_speed":460.0,"vertical_rate":-60,"squawk_code":"5125","on_ground":false,"callsign":"HVN6513","tail_number":"VN-A867","collection_type":"terrestrial","icao_actype":"B789","flight_number":"VN6513","origin_airport_icao":"VVNB","destination_airport_icao":"EDDF","scheduled_departure_time_utc":"2020-05-19T19:00:00Z","scheduled_departure_time_local":"2020-05-20T02:00:00","scheduled_arrival_time_utc":"2020-05-20T06:00:00Z","scheduled_arrival_time_local":"2020-05-20T08:00:00"}}

{"target":{"icao_address":"780B7F","timestamp":"2020-05-20T04:02:00Z","latitude":55.04723,"longitude":27.397405,"altitude_baro":40000,"heading":250.0,"ground_speed":460.0,"vertical_rate":-60,"squawk_code":"5125","on_ground":false,"callsign":"HVN6513","tail_number":"VN-A867","collection_type":"terrestrial","icao_actype":"B789","flight_number":"VN6513","origin_airport_icao":"VVNB","destination_airport_icao":"EDDF","scheduled_departure_time_utc":"2020-05-19T19:00:00Z","scheduled_departure_time_local":"2020-05-20T02:00:00","scheduled_arrival_time_utc":"2020-05-20T06:00:00Z","scheduled_arrival_time_local":"2020-05-20T08:00:00"}}

0 5 555
5 REPLIES 5

hi,

I think I understand what you're doing, what results you're expecting to see, and what results you're actually seeing.

You're configuring a custom attribute on an API Product.

You're expecting that custom attribute to be used as a Query Parameter in the request that is sent to the upstream (backend) system.

You're not seeing that behavior.


If that's the case, I think I have a solution for you.

Custom attributes on API Products (or on developer apps, or on developers, or tokens, etc) are just key/value pairs that you can attach to the entity.

If the client app sends in a valid, non-expired credential (API Key or Token) that is authorized for a particular API Product, when your proxy calls VerifyAPIKey or OAuthV2/VerifyAccessToken , then the result is: those custom attributes get injected into context variables for that request. the names of the variables that get set vary depending on:

  • whether you use VerifyAPIKey or VerifyAccessToken
  • the entity type you've attached the attribute to (Developer, product, app, token, etc)
  • the name of the attribute itself

Let me repeat that so it is clear: when your proxy verifies a key or token, Apigee loads the custom attributes that have been previously configured on the product into context variables. This process is described here. These context variables are just ... things in memory, that your policies can reference if they wish.

One implication: verifying a token will not implicitly change or set the query parameters that your proxy sends to the backend.

If you want to inject new query params to the request that will be sent to the backend, then you need to explicitly do that. There's a builtin policy that allows you to do this, AssignMessage.

<AssignMessage name='AM-InjectQueryParam'>
  <Set>
    <!-- add a query param to the outbound request -->
    <!-- use the value from the custom attribute on the API product -->
    <QueryParams>
      <QueryParam name='icao_address'>{apiproduct.icao_address}</QueryParam>
    </QueryParams>
  </Set>
</AssignMessage><br>

The variable "apiproduct.icao_address" refers to the value of the custom attribute, assuming you've used VerifyAccessToken, attached the attribute to the API Product, and used "icao_address" as the name of the attribute. If you've used VerifyAPIKey, then the variable name is "verifyapikey.POLICYNAME.apiproduct.icao_address."

Hi Dino,

Thanks for clarifying this, what you suggested is what I'm trying to accomplish. My last question is and this is because I'm extremely unfamiliar with Apigee: where do I go to make the proposed change above in the Apigee UI.

I'm thinking through Develop -> API Proxies -> Airsafe API -> Develop.

I could then add a step (Assign Message) to the Proxy Endpoint get/stream.

Is the above the correct method of where to go?

Best, Zayne

Yes, correct. Try looking at the Apigee 101 videos to get an idea of how to add policies.

@Zayne Sagar,

Can you post your trace for the API call? How are you accessing the custom attribute from the product in your API proxy?

@Nagashree B can you look at my comment underneath Dino-at-Googles response. Dino's suggestion is what I'm trying to implement but am not sure how to proceed forward with it.