Search code examples
jsonpathwiremockwiremock-standalone

Wiremock dynamic response based on request - jsonPath is not working


I'm using Wiremock standalone and below are sample of request/response. jsonPath is not working and it's returing the whole code. What am I doing wrong?

Sample Request

{
    "source": "Web",
    "orders":[ 
        {
            "id": "Order1",
            "status": "In Progress"
        },
        {
            "id": "Order2",            
            "status": "In Progress"
        }
    ]    
}

Expected Response

{
    "user": "User1",
    "orders": [
        {
            "id": "Order1",
            "status": "In Progress", 
            "shipping": "Pending"
        },
        {
            "id": "Order2",            
            "status": "In Progress",
            "shipping": "Pending"
        }
    ]
}

My response.json

{
    "user": "User1",
    "orders": [
          {{#each (jsonPath request.body '$.batches') as |batches|}}
          {
             "id": "{{{batches.id}}}",
             "status": "In Progress", 
             "shipping": "Pending"
          }{{^last}},{{/last}}
          {{//each}}
    ]
}

Actual Response

{
    "user": "User1",
    "orders": [
          {{#each (jsonPath request.body '$.batches') as |batches|}}
          {
             "id": "{{{batches.id}}}",
             "status": "In Progress", 
             "shipping": "Pending"
          }{{^last}},{{/last}}
          {{//each}}
    ]
}

Solution

  • Normally, when nothing is parsed it means response-templating isn't enabled for this response. To enable response-templating you can add it to the stub mapping by adding the transformers field:

      "name" : "orders",
      "request" : {
        "url" : "/orders",
        "method" : "GET"
      },
      "response": {
        "status": 200,
        "bodyFileName": "response.json",
        "transformers": [
          "response-template"
        ],
        "headers": {
          "Content-Type": "application/json"
        }
      }
    }
    

    With the above stub mapping and this response.json file:

    {
      "user": "User1", 
      "orders": [ 
        {{#each (jsonPath request.body '$.orders') as |order|}} 
          {
            "id": "{{order.id}}", 
            "status": "In Progress", 
            "shipping": "Pending"
          } {{#not @last}},{{/not}}  
        {{/each}} 
      ]
    }
    

    I was able to produce the output you are looking for. This request:

    {
      "source": "Web",
      "orders": [
        {
          "id": "Order1",
          "status": "In Progress"
        },
        {
          "id": "Order2",
          "status": "In Progress"
        },
        {
          "id": "Order3",
          "status": "In Progress"
        }
      ]
    }
    

    Produces this output from wiremock:

    {
      "user": "User1",
      "orders": [
        {
          "id": "Order1",
          "status": "In Progress",
          "shipping": "Pending"
        },
        {
          "id": "Order2",
          "status": "In Progress",
          "shipping": "Pending"
        },
        {
          "id": "Order3",
          "status": "In Progress",
          "shipping": "Pending"
        }
      ]
    }
    

    The jsonPath matches on the array in the request and the each loops through those elements. The not checks to see if it is the last element in the loop and if not, add the , to make the response valid json.

    There is a great explanation of the conditional logic and iteration here - https://docs.wiremock.io/response-templating/conditional-logic-and-iteration/

    This was all done using the latest version of wiremock - currently 3.2.0