Hi WireMock Team, In order to perform performance ...
# wiremock-cloud
v
Hi WireMock Team, In order to perform performance testing for our API's, We are trying to mock our external dependency service APIs. Trying to use response templates and struggling to find correct syntax for our use case: Use Case: For suppose, In query parameter when we send num_results key (num_results=10), then in our response the array object should multiply by 10 dynamically(statically we maintain single array object). I checked the loop syntax, but it doesn't provide increment counter and condition
Copy code
{{#each (jsonPath request.body '$.things') as |thing|}}
  {{@index}}: {{thing}}
{{/each}}
Just wondering if we have anything that I missed. Thanks
Copy code
Bascally in typescript we use : results.flatMap((e) =>
    Array(num_results).fill(e)
  )
l
Hi, just so I understand correctly, you pass in the
num_results
query param and you want the same number of items in the response json array as passed in in the
num_results
query param? Could you provide an example of the request and response that you would be expecting so i can see if we can achieve the same results from templating?
v
Copy code
{
  "mappings": [
    {
      "request": {
        "method": "GET",
        "urlPathTemplate": "/search/{query}"
      },
      "response": {
        "status": 200,
        "headers": {
          "Content-Type": "application/json"
        },
        "bodyFileName": "./DCX/Search/getCIOSearch.json",
        "transformers": [
          "response-template"
        ],
        "fixedDelayMilliseconds": 5
      }
    }
  ]
}
Above is the mapping: Request Path example: /search/dress?num_results=10
Copy code
{
  "response": {
    "results": [
      {
        "matched_terms": [
          "clothes"
        ],
        "labels": {},
        "data": {
          "id": "1600808951",
          "url": "/our-house-single-clothes-rail/1600808951.prd",
          "brand": "Our House",
          "group_ids": [
            "cat340196"
          ],
          "productReviews": {
            "averageStars": 2,
            "reviewsCount": 9
          },
          "prices": {
            "now": {
              "endDate": "2050-02-04T23:59:59.000+01:00",
              "vatCode": "S",
              "salesInd": "0",
              "basePrice": 17.99,
              "startDate": "2024-07-26T00:00:00.000+01:00",
              "outletCode": "E605",
              "suffixCode": "1Z",
              "currencyCode": "GBP",
              "productLevel": {},
              "currencySymbol": "£"
            },
            "next": {
              "endDate": "2023-08-15T23:59:59.000+01:00",
              "vatCode": "S",
              "salesInd": "0",
              "basePrice": 8,
              "origPrice": 14,
              "savePrice": 6,
              "startDate": "2023-08-15T00:00:00.000+01:00",
              "outletCode": "M561",
              "suffixCode": "1U",
              "currencyCode": "GBP",
              "productLevel": {
                "nowTo": 11,
                "wasTo": 16,
                "nowFrom": 6,
                "wasFrom": 9,
                "saveUpToPrice": 6,
                "displaySavePriceInd": "true"
              },
              "currencySymbol": "£"
            }
          },
          "swatch": {
            "id": "V9RF9_SQ0_0000000099_N_A_SW"
          },
          "options": {
            "COLOUR": "ONE COLOUR"
          },
          "image_url": "<https://media.very.co.uk/i/very/V9RF9_SQ1_0000000099_N_A_SLf>",
          "facets": [
            {
              "name": "price",
              "values": [
                17.99
              ]
            }
          ],
          "variation_id": "V9RF9",
          "catalogueNumber": "V9RF9"
        },
        "value": "Single Clothes Rail",
        "is_slotted": false,
        "variations": [
          {
            "data": {
              "prices": {
                "now": {
                  "endDate": "2025-02-04T23:59:59.000+01:00",
                  "vatCode": "S",
                  "salesInd": "0",
                  "basePrice": 17.99,
                  "startDate": "2024-07-26T00:00:00.000+01:00",
                  "outletCode": "E605",
                  "suffixCode": "1Z",
                  "currencyCode": "GBP",
                  "productLevel": {},
                  "currencySymbol": "£"
                },
                "next": null
              },
              "swatch": {
                "id": "V9RF9_SQ0_0000000099_N_A_SW"
              },
              "options": {
                "COLOUR": "ONE COLOUR"
              },
              "image_url": "<https://media.very.co.uk/i/very/V9RF9_SQ1_0000000099_N_A_SLf>",
              "facets": [
                {
                  "name": "price",
                  "values": [
                    17.99
                  ]
                }
              ],
              "variation_id": "V9RF9",
              "catalogueNumber": "V9RF9"
            },
            "value": "Single Clothes Rail"
          }
        ]
      }
    ]
  },
  "result_id": "46aef5be-1de4-4773-8b57-1248e7c7d78e",
  "request": {
    "num_results_per_page": 10,
    "sort_by": "relevance"
  }
}
In above response, results array object should be length of 10 as we sent the num_results value 10
Let me know if you have any doubts. Thanks, Lee
l
My initial thought is to use an
each
along with a
range
but we need to figure out how to get the upper bound of the range from the query param. In my examples below I will use a simple json payload for each of the items in the array otherwise it will get a little long due to the size of your response payload. Hopefully this will give enough information so you will be able to apply it to your use case.
The first step is to handle the query parameter. We can do this using a
val
helper:
Copy code
{{val request.query.num_results or='0' assign='numResults'}}
This is nice because it handles the default for us if the query param doesn't exist. This then assigns the value to the
numResults
variable.
We then need to use this value for the upper bound of the range. The tricky part is that the
range
helper requires integers and the query parameter will have generated a string. We can force it into an integer by using the
math
helper and again using the
val
helper to assign it to a variable. The main difference between
val
and
assign
is that
val
will maintain the type of the data being assigned whereas
assign
will always assign a string:
Copy code
{{val (math numResults '-' 0 ) or='0' assign='upperBound'}}
As you can see, we simply take
0
away from the
numResults
variable which forces the result to an int.
From that point we have everything we need to combine this with the
each
and the
range
Copy code
{{val request.query.num_results or='0' assign='numResults'}}
{{val (math numResults '-' 0 ) or='0' assign='upperBound'}}
{
    "response": {
      "results": [
        {{#each (range 1 upperBound) as |index|}}
            {
                "foo": "bar_{{index}}",
                "bar": "baz"
            }{{#unless @last}},{{/unless}}
        {{/each}}
      ]
    },
    "result_id": "46aef5be-1de4-4773-8b57-1248e7c7d78e",
    "request": {
      "num_results_per_page": {{numResults}},
      "sort_by": "relevance"
    }
  }
If I send a request like
/search/dress?num_results=2
I get the following :
Copy code
{
  "response": {
    "results": [
      {
        "foo": "bar_1",
        "bar": "baz"
      },
      {
        "foo": "bar_2",
        "bar": "baz"
      }
    ]
  },
  "result_id": "46aef5be-1de4-4773-8b57-1248e7c7d78e",
  "request": {
    "num_results_per_page": 2,
    "sort_by": "relevance"
  }
}
If i send
/search/dress?num_results=4
I get:
Copy code
{
  "response": {
    "results": [
      {
        "foo": "bar_1",
        "bar": "baz"
      },
      {
        "foo": "bar_2",
        "bar": "baz"
      },
      {
        "foo": "bar_3",
        "bar": "baz"
      },
      {
        "foo": "bar_4",
        "bar": "baz"
      }
    ]
  },
  "result_id": "46aef5be-1de4-4773-8b57-1248e7c7d78e",
  "request": {
    "num_results_per_page": 4,
    "sort_by": "relevance"
  }
}
Note we have used the
{{numResults}}
to make sure the
num_results_per_page
field is correct
If I send a request without the parameter -
/search/dress
I get:
Copy code
{
  "response": {
    "results": []
  },
  "result_id": "46aef5be-1de4-4773-8b57-1248e7c7d78e",
  "request": {
    "num_results_per_page": 0,
    "sort_by": "relevance"
  }
}
Is that the kind of thing you are looking for?
v
Thank you so much, that is exactly what I am looking for
I will check this code out
👍 1
And one another thing when we use response templates in JSON file how can we ignore the JSON Semantics errors pop out from the vs code file, For example:
l
That is a tricky one. If your editor thinks they are json then you will see the errors. You could convert them to a different file format like
.txt
and you wouldn't see the errors
v
That's what I am thinking, write in text file and use Jsonformat with pretty, I think that will return JSON response in API