Hello, Team. I have the following situation: RX49...
# help
m
Hello, Team. I have the following situation: RX498167A-bbe773830edd2ffcde6424313ee43373d25cad87 HJ159160B-a7ea729648857f271fa12f59daaf89dc81529c3f. I need to create 1000 data mocks like this: if I supply the first part, which is nino, it will be translated into a unique number; if I pass the unique number, it will return Nino, so I need to create 2000 mapping files in total. Instead, I was looking for a solution where I could have a json file that wiremock could check and respond to ?
l
What is the API structure like that you are building. Is there two endpoints here - one for the short bit of data and one for the long ?
m
Hi Lee, Thanks for responding. is ok to have quick huddle ?
l
Hi, sorry, it will have to be in this thread. Can you give an example of the API - does your API just return the raw data as an application/text response
m
Copy code
{
  "request": {
    "method": "GET",
    "urlPathPattern": "^/users/\\d+$",
    "headers": {
      "Accept": {
        "matches": "^application/json;?.*"
      }
    }
  },
  "response": {
    "status": 200,
    "headers": {
      "Content-Type": "application/json"
    },
    "transformers": [
      "response-template"
    ],
    "transformerParameters": {
      "usernameMapping": {
        "1": "foo",
        "2": "bar",
        "3": "baz"
      }
    },
    "jsonBody": {
      "id": "{{#assign 'userId'}}{{request.pathSegments.[1]}}{{/assign}}{{userId}}",
      "username": "{{lookup parameters.usernameMapping userId}}"
    }
  }
}
Basically I am trying to separate the data from the transformerParameters in to a file like data.json and response into json response file.
is it possible to use a transformerParameters input into a different json file ?
l
Not that I am aware of.
m
so your saying wiremock wont let you to use the data file as input to the transformerParameters ?
l
I haven't tried that before myself. I would need to look at the code to see what the transformer parameters allow you to pass. Give me a moment and I will take a look
m
Thanks
Sorry to bother you again with lot of question, is it possible , if I pass foo in the url will it response with 1 for the same example ?
l
Not sure. Let me take a look and see if I can come up with an example
👍 1
I have an example of the
nino
->
username
example above but it doesn't use the transformer parameters
Simple stub example:
Copy code
{
  "request": {
    "method": "GET",
    "urlPathTemplate": "/users/{nino}"
  },
  "response": {
    "status": 200,
    "headers": {
      "Content-Type": "application/json"
    },
    "bodyFileName": "nino.txt",
    "transformers": [
      "response-template"
    ]
  }
}
With this response body file - nino.txt:
Copy code
{{#assign 'data'}}
[
    {
      "nino": "1",
      "id": "foo"
    },
    {
      "nino": "2",
      "id": "bar"
    },
    {
      "nino": "3",
      "id": "baz"
    }
]
{{/assign}}
{{#assign 'expr'}}$[?(@.nino=={{request.path.nino}})].id{{/assign}}
{
  "id": "{{request.path.nino}}",
  "username": "{{jsonPath (jsonPath data expr) '$[0]'}}"
}
Returns
Copy code
{
  "id": "2",
  "username": "bar"
}
Not sure how easy it would be to make the same stub return
1
if you passed
foo
. Does that need to be the same stub or can that be a separate stub on a different path (url)
m
First thanks for helping me on this, in our requirement its need to be a same stub, but once if possible we can try.
l
How does the API you are mocking know whether to return the nino or the username?
m
ya agree we need to create a separate mock but the data file can we same ?
Because I have 1000 data then it will be like maintain the same data in two files
l
I don't know a way off the top of my head to extract the data out into a separate file that is shared across stubs in the open source version. We do have a solution for this in WireMock Cloud that was built for this exact purpose - Data Sources You basically upload your data as a csv format and then you can reference that data from multiple stubs and query it in an SQL type format.
m
The problem is we cant use the cloud due to the project privacy.
l
Ah, that is a shame
m
ya , I did read about this but ya due to gov policy
l
You could create a WireMock extension that adds the data you are using to the template data model and then you could use it directly in all your stubs - https://wiremock.org/docs/extensibility/adding-template-model-data/
m
hmm, this is interesting Thanks Lee your help is much appreciated.
l
If all of that doesn't work for you I would speak to one of our team about our on prem version of WireMock Cloud. That way you get all the cool WireMock Cloud features and all the privacy concerns sorted 🙂
m
That would be really helpful, I guess I found a way now {{#assign 'data'}} [ { "nino": "1", "id": "foo" }, { "nino": "2", "id": "bar" }, { "nino": "3", "id": "baz" } ] Can we write something like this path contain nino then{ {{/assign}} {{#assign 'expr'}}$[?(@.nino=={{request.path.nino}})].id{{/assign}} { "id": "{{request.path.nino}}", "username": "{{jsonPath (jsonPath data expr) '$[0]'}}" }} path contain id then{{#assign 'expr'}}$[?(@.nino=={{request.path.id}})].nino{{/assign}} { "id": "{{request.path.id}}", "username": "{{jsonPath (jsonPath data expr) '$[0]'}}" }}
I am not sure on the syntax can you pls help me to correct ?
l
I thought of something like that but those are two different path variables (
nino
and
id
). Your path structure would have multiple levels if you were to do this (
/user/{nino}/{id}
). If you only want one level it is difficult to know whether you have passed an id or a nino
Let me try something else
m
actually my path is something like
/user/convert-nino-to-id/123
/user/convert-id-to-nino/foo
l
Oh, that might make it a little easier then
🫡 1
Try this as your mapping file:
Copy code
{
  "request": {
    "method": "GET",
    "urlPathTemplate": "/user/{action}/{data}"
  },
  "response": {
    "status": 200,
    "headers": {
      "Content-Type": "application/json"
    },
    "bodyFileName": "nino.txt",
    "transformers": [
      "response-template"
    ]
  }
}
And this as your body file:
Copy code
{{#assign 'data'}}
[
    {
      "nino": "1",
      "id": "foo"
    },
    {
      "nino": "2",
      "id": "bar"
    },
    {
      "nino": "3",
      "id": "baz"
    }
]
{{/assign}}
{{#eq request.path.action 'convert-nino-to-id'}}
{{#assign 'idExpr'}}$[?(@.nino=='{{request.path.data}}')].id{{/assign}}
{
  "id": "{{request.path.data}}",
  "username": "{{jsonPath (jsonPath data idExpr) '$[0]'}}"
}
{{else}}
{{#assign 'ninoExpr'}}$[?(@.id=='{{request.path.data}}')].nino{{/assign}}
{
  "id": "{{jsonPath (jsonPath data ninoExpr) '$[0]'}}",
  "username": "{{request.path.data}}
}
{{/eq}}
Then you can make requests using your real url paths:
Copy code
GET <http://localhost:8080/user/convert-nino-to-id/3>
GET <http://localhost:8080/user/convert-id-to-nino/foo>
It is generally better to create multiple stubs for things like this rather than complicated logic in the response template but with your use case and not wanting to manage the same data across multiple stubs this should work
m
Ok thanks again Lee , let me try once and get back to you . 🙏🏽