How to retrieve from KVM using a variable

Hello, 

I will explain the scenario in detail first, 

I have various domains under my current organisation and every domain has list of backend APIs. We were already using a different API gateway(Kong) earlier using which our current customers are invoking all of these APIs. Now we want to migrate these to Apigee. The Proxy endpoint is different than the target endpoint and the differences are various levels.

First difference is, it is a multi-tenant system. And the customer tenant information(customer domain) is passed in header. To handle this in Apigee I have used the ExtractVariable policy and modified target URL in JavaScript policy. 

Sometimes, the proxy endpoint URL and target URL differs in request URI structure, this is where I want to use KeyValuMaps

Earlier I was using only Javascript policy with many if & else to detect and modify the target URL, as followed, 

 

 

 

 

var request_uri = context.getVariable('request.uri');
if(request_uri == "/payroll/v2/employees/handentry" && !targetModified)
{
    targetUrl = targetUrl + "/payroll/items/employee";
    targetModified = true;
}

if(request_uri == "/payroll/v2/employees/"+empId && !targetModified)
{
    targetUrl = targetUrl + "/payroll/items/employee/"+empId; 
    targetModified = true;
}

 

 

 

 

Then I came across KeyValueMaps in Apigee. 

Now if I want to implement same in KeyValueMap Operations policy, how I can do this is the question? 

I already created a policy and made all necessary initial entries, but then as the key is going to be a variable here, how can we retrieve the value using variable from KeyValueMap in policy?

Also, based on what I described, are we using correct ways to migrate to Apigee?

1 3 129
3 REPLIES 3

1. Your example javascript looks incomplete as it refers to some variable? - empId

2. What is the base path of your API proxy in Apigee? is it /payroll/v2/employees? in which case, you want to ignore /handentry if it's your proxy.pathsuffix and otherwise append the proxy.pathsuffix?

https://docs.apigee.com/api-platform/reference/variables-reference#proxy

3. An alternative to javascript could also be Apigee route rules 

Thanks for the response, here is full Javascript code 

var targetUrl = "https://"+ context.getVariable("host") + context.getVariable("target.basepath");

var request_uri = context.getVariable('request.uri');
print("request_uri is: "+ request_uri);
var empId = context.getVariable("employeeId");
var date = context.getVariable("date");
var statusVar = context.getVariable("status");
print("empId is: "+ empId);

print("proxy.pathsuffix is: "+ context.getVariable('proxy.pathsuffix'));
print("request.querystring:---"+ context.getVariable("request.querystring"));

print(" Target URL is 1 :"+ targetUrl);

print("Keyvalumap value is: "+ context.getVariable('myvar'));

var targetModified = false;

if(request_uri == "/payroll/v2/employees/handentry" && !targetModified)
{
    targetUrl = targetUrl + "/admin/v1/payroll/items/employee";
    targetModified = true;
}

if(request_uri == "/payroll/v2/employees/"+empId && !targetModified)
{
    targetUrl = targetUrl + "/admin/v1/payroll/items/employee/"+empId;
    targetModified = true;
}

if(request_uri == "/payroll/v2/salary/repository" && !targetModified)
{
    targetUrl = targetUrl + "/admin/v1/salary/repository";
    targetModified = true;
}

if(request_uri == "/payroll/v2/employees/salary/statement/"+date && !targetModified)
{
    targetUrl = targetUrl + "/admin/v1/salary/statement/"+date;
    targetModified = true;
}

if(request_uri == "/payroll/v2/employees/salary/statement/"+date+"/"+empId && !targetModified)
{
    targetUrl = targetUrl + "/admin/v1/salary/statement/"+date+"/"+empId;
    targetModified = true;
}

if(request_uri == "/payroll/v2/employees/resettlement/"+date && !targetModified)
{
    targetUrl = targetUrl + "/v1/resettlement/"+date;
    targetModified = true;
}

if(request_uri == "/payroll/v2/salary/revision/employees/"+empId && !targetModified)
{
    targetUrl = targetUrl + "/v1/admin/revision/"+empId;
    targetModified = true;
}

if(request_uri == "/payroll/v2/salary/revision/employees/"+empId+"/"+statusVar && !targetModified)
{
    targetUrl = targetUrl + "/v1/admin/revision/"+empId+"/"+statusVar;
    targetModified = true;
}

if(request_uri == "/payroll/v2/salary/revision/difference/employees/"+empId && !targetModified)
{
    targetUrl = targetUrl + "/v1/admin/revision/difference/"+empId;
    targetModified = true;
}

context.setVariable("configMapHandEntry", "handentry");

print(" Final Target URL is :"+ targetUrl);
context.setVariable("target.url", targetUrl);

For question 2, the base path as of now for this Api proxy is /payroll/v2. 

For point no 3, I believe we cannot use routes as we are forming the Target URL based on header parameter `x-greythr-domain`, 

In addition to above, following is my ExtractVariable policy configuration

<ExtractVariables continueOnError="false" enabled="true" name="EV-EID-EXTRACT">
    <DisplayName>EV-EID-EXTRACT</DisplayName>
    <Properties/>
    <Header name="x-greythr-domain">
        <Pattern ignoreCase="true">{host}</Pattern>
    </Header>
    <URIPath>
        <Pattern ignoreCase="true">/employees/{employeeId}</Pattern>
        <Pattern ignoreCase="true">/employees/salary/statement/{date}</Pattern>
        <Pattern ignoreCase="true">/employees/salary/statement/{date}/{employeeId}</Pattern>
        <Pattern ignoreCase="true">/employees/resettlement/{date}</Pattern>
        <Pattern ignoreCase="true">/salary/revision/employees/{employeeId}</Pattern>
        <Pattern ignoreCase="true">/salary/revision/employees/{employeeId}/{status}</Pattern>
        <Pattern ignoreCase="true">/salary/revision/difference/employees/{employeeId}</Pattern>
    </URIPath>
    <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
    <Source clearPayload="false">request</Source>
</ExtractVariables>

 

I think it would be simpler to have a json object that maps each request uri to a target path.. then you can eliminate all the if statements

eg something like

var targetMappings = {}
targetMappings["/payroll/v2/employees/handentry"] = "/admin/v1/payroll/items/employee"
targetMappings["/payroll/v2/employees/"+empId] = "/admin/v1/payroll/items/employee/"+empId
...

if (targetMappings[requestUri]) {
  targetUrl = targetUrl + targetMappings[requestUri] 
}

you could also store that in a kvm, but you would need extra steps to populate your date and id variables, etc