Search code examples
postmanpostman-collection-runnerpostman-pre-request-scriptpostman-testcase

Postman chaining APIs with looping


I have 3 APIs.

API#1 - GET {{endPoint}}/event/{{customerId}}/orders

API#2 - POST {{endPoint}}/pullOrders/{{orderId}}/claims

API#3 - DELETE {{endPoint}}/pullOrders/{{orderId}}/events

Response of API#1 is a json with the orderIDs.

{
    "List": [
        {
            "OrderId": "c6882585",
            "Type": "pull"
        },
        {
            "OrderId": "a2f818e7",
            "Type": "pull"
        },
        {
            "OrderId": "1f45e306",
            "Type": "pull"
        }
    ]
}

The input to API#2 is the orderId from the response of API#1. The response of API#2 is a json with partNumber for a particular customerId. The response could be empty/null with varying number of partNumber with other customerId.

[
    {
        "EventId": "46323beaf738",
        "PartNumber": "22b188f7",
    },
    {
        "EventId": "5024519db933",
        "PartNumber": "2c2d8757",
    }
]

These partNumber are input to API#3 in it’s body.

Body of API#3

{
    "partNumberList": [22b188f7, 2c2d8757]
}

The goal is to delete all order history for a customer by chaining API#1, API#2 and API#3.

In Tests of API#1 I get all the orderIds in test and save it in a variable.

const responseJson = pm.response.json();
var orderIdList = responseJson.List;
var orderIds = []
for(var index in orderIdList) {
    orderIds.push(orderIdList[index].OrderId);
}
pm.variables.set("orderIds", JSON.stringify(orderIds));
pm.variables.set("orderIdsIndex", 0);

In the Pre-request Script of API#2 I set the call to API#2 with the orderId from API#1.

var orderIds = JSON.parse(pm.variables.get('orderIds'));
var index = parseInt(pm.variables.get('orderIdsIndex'));
pm.variables.set('orderId', orderIds[index]);
if (index + 1 < orderIds.length){
    pm.variables.set('orderIdsIndex', index + 1);
    postman.setNextRequest('API#2');
}else{
    postman.setNextRequest(null);
}

Till this point things work as expected, i.e. API#2 is called in a loop 3 times for 3 orderIds.

In Tests of API#2 I have tried the following. The run stops when partNumbers array below is non empty. It calls API#3 and then stops. How do I make it continue to the next iteration?

const responseJson = pm.response.json();
var partNumbers = [];
for (var key in responseJson){
    partNumbers.push(responseJson[key].PartNumber);
}
pm.variables.set('partNumbers', JSON.stringify(partNumbers));
if (receiptHandles.length != 0) {
    postman.setNextRequest('API#3');
}else{
    postman.setNextRequest('API#2');
}

And in body of API#3 I have

{
    "partNumberList": {{partNumbers}}
}

Solution

  • why can't you store everything before hand ?

    in API 1 test use:

    //storing all orderids to a list 
    pm.variable.set("orderIDList",pm.response.json().List.map(elem=>elem.OrderId))
    

    in pre-request of API2

    //Getting orderID from the list in the left to right order
    let orderIDList = pm.variable.get("orderIDList")
    pm.variables.set("orderId", orderIDList.shift())
    pm.variables.set("orderIDList", orderIDList)
    // Doing sendRequest till all orderIDs are executed
    orderIDList.length ? postman.setNextRequest(pm.info.requestName):null
    

    In test script of API2

    //storing PartNumber for each orderID as a List of object coontaining 
    //orderID:[partnumber1,partnumber2]
    let obj = {}
    obj[pm.variables.get("orderId")] =  pm.response.json().map(elem=>elem.PartNumber)
    let partNumberList = pm.variables.get("partNumberList") 
    partNumberList ? partNumberList.push(obj) : partNumberList=[obj]
    pm.variables.set("partNumberList",partNumberList) 
    

    and in Pre request of API3

    //sending each orderid with the full PartNumberList
    let partNumberList = pm.variable.get("partNumberList")
    let partNumberMap = partNumberList.shift()
    pm.variables.set("orderId", Object.keys(partNumberMap).shift())
    pm.variables.set("partNumbers", partNumberMap[orderId])
    pm.variables.set("partNumberList", partNumberList)  
    
    partNumberList.length ? postman.setNextRequest(pm.info.requestName):null