URGENT PLEASE : Send request from response

Hello,

I have a scenerio where I need to get the billing acounts from a CRM based on the id of a client:

The proxy endpoint :

        Get {basePath}/cutomer/{id}/billingAccount 

The backend can only first return the billing account(s) id(s) with an SQL-like query in the query params :

The CRM endpoint :

        Get {basePath}/query?select+billingaccountid+from+billingaccount+where+clientid+=+'theid'

You guessed it, it's SQL but you replace the spaces with '+'.

That request will return a json with the billing acount(s) id(s). So i need to :

- Parse the json

- Get the id(s)

UNTIL THIS POINT I KNOW HOW AND WHAT TO DO

- Resend one or more requests to the CRM Api using the id(s).

        Get {basePath}/customer/{billingacountId}

- Recuperate the new response(s)

- Fashion the response to the client.

My question is :

       How to send one or multiple requests after the initial request, after getting the id(s) i need. 

If my explanation is not clear I can try to give you more details or to phrase it better.

Thank you, long live the community ❤️

@dchiesa1 I need your wisdom

0 2 171
2 REPLIES 2

You will not be able to loop through billing account ids and make requests to {basePath}/customer/{billingacountId} in the usual fashion using a target endpoint. We’ll have to look down other avenues to achieve this.

We could follow your flow generalistically using a JavaScript or JavaCallout policy, but that may not be best practice. By looping multiple http calls within your proxy you run the risk of accumulating very high latency for your API. This is easy to imagine in a scenario where your first API call returns 100 billing ids and forces your proxy to loop over each and make another 100 resulting API calls to the CRM. Even just 10 billing ids could have a large impact.

That is why my recommendations attempt to circumvent this practice. Hopefully one of them works for you. Otherwise, we'll need to explore other options that may be less performant.

Option #1

  1. Make the call to your first target to get billing ids via a ServiceCallout policy. Alternatively, you could use a JavaScript or JavaCallout policy
  2. Parse and process the response from your first API call. Retrieve billing IDs and put into a string array
  3. Make the call to your second target to get billing account information via the target endpoint using a constructed SQL query that utilizes a WHERE .. IN({billingidarray}). This allows you to get all of your data in only 1 query instead of multiple.
  4. Retrieve response, format as needed, return to client
  5. Note: This option only works if your second CRM endpoint accepts SQL like your first does

Option #2

  1. Find or create a new CRM API that allows you to provide the entire list of billing ids and pass them all at once. Perhaps something like {basePath}/customer/list/{billingidarray}. 
  2. Make the call to your first target to get billing ids via a ServiceCallout policy. Alternatively, you could use a JavaScript or JavaCallout
  3. Parse and process the response from your first API call. Retrieve billing IDs and put into array
  4. Make the call to your second target {basePath}/customer/list/{billingidarray} to get billing account information. This allows you to get all of your data in only 1 query instead of multiple.
  5. Retrieve response, format if needed, return to client

Option #3

  • Investigate Apigee’s new integrations offering. If you can get access to the CRM SQL database, or if your CRM is Salesforce, you may be able to utilize connectors (SQL, SF) easily retrieve the data you need with little configuration.

Apigee 's configuration language is oriented toward building a traditional "reverse proxy" type of behavior. It handles an inbound request, maybe validates it or checks it (APIkey or token, rate limit, etc), and then routes that request to a backend system. Then the Apigee flow can optionally manipulate that response, and then send it to the requesting client.  A configurable reverse proxy. 

What you are talking about is something just a little different.  You would like to use the original response from the target, as input to a not-strictly-limited series of calls outbound.  As you know the Apigee flow language lacks control structure for loops.  There's no way to code that in the <Flow> element. 

A general way to solve that problem is to delegate the control of all of that to an integration engine.  We might call this particular case a sort of special case of the "scatter/gather" pattern. Where "Scatter/Gather" talks of sending multiple outbound requests to different endpoints, and then aggregating the results, your particular case is sending multiple outbound requests to a single endpoint and aggregating the results.  Anyway my point is that there are tools dedicated to solving the general-purpose integration problem, including Scatter Gather and other patterns. Apigee integration is one of those tools, and it's quite powerful. We released it in September 2021, as a separate offering int he Apigee family. If you know Apigee API Management, this is a complementary tool that is dedicated to enterprise integration.  It includes a graphic designer that allows you to configure the flow for various processes, and of course could be used to solve the specific problem in your case.   

So I'd say if this particular problem is just one instance of a number of different integration challenges you might be facing, consider looking at a general purpose integration tool, like Apigee Integration. 

On the other hand if you just have a simple problem that you'd like to solve - call an endpoint multiple times based on the response from a target - then you can use the tools in Apigee API Management to do that. Specifically the JavaScript callout will be good for this purpose. The JS callout includes an httpClient capability, and of course JS allows you to create loops. 

The Apigee community has discussed this previously multiple times. Search here.  And here are some highlights:

Good luck!