Wiremock Stand alone - How to manipulate response with request data - java

I was trying to implement mocking of POST REST call using Wiremock Standalone server. I am faced with a challenge like this, suppose the post body contains an "name" field and its value, the same value should be returned in the response of that POST call. My json file looks like this:
{
"priority": 1,
"request": {
"method": "POST",
"urlPath": "/primeSlots",
"bodyPatterns" : [ {
"matchesJsonPath" : "{ \"things\": [ { \"name\": \"794363\" }]
}"
} ]
},
"response": {
"status": 200,
"body": "{{$.things.name.value}}",
"transformers": ["response-template"]
}
}
so, I need to get the value , that is 794363,but using above approach not able to get it in the post response body.
I tried this too:
{
"request": {
"method": "POST",
"urlPath": "/transform",
"bodyPatterns": [
{
"matchesJsonPath" : "$.things[?(#.name =~ /[0-9]+/i)]"
}
]
},
"response": {
"status": 200,
"body": "{\"responseName\": \"
{{request.body.things.name.value}}\"}",
"headers": {
"Content-Type": "application/json"
},
"transformers": ["body-transformer"]
}
}
So my question is, even if i use a regEx, which matches with any number that comes in the request, how to give back the same number in the response using Wiremock standalone json file?
Thanks.

Today I was in the same situation like you and found a solution which I would like to share with you:
Create own class that extends ResponseDefinitionTransformer
Add Handlebar functionality in your own transformer class ( see https://github.com/jknack/handlebars.java how to do it )
(Optional) Append your own/other helpers e.g.
Arrays.stream(StringHelpers.values()).forEach(helper -> this.handlebars.registerHelper(helper.name(), helper));
Export your transformer customization as a separate JAR file
Create a start batch script to start up your WireMock standalone with your own transformer extension e.g. java -cp "-cp ".\lib\wiremock-standalone-2.5.1.jar;.\lib\customTransformer.jar" com.github.tomakehurst.wiremock.standalone.WireMockServerRunner --extensions "your.name.CustomTransformer" (for linux use : instead of ; as classpath separator)
In case you have multiple transformers, just define all those using , (comma) as separator in the --extensions arg.

Unfortunately WireMock's response templating transformer doesn't currently break out the request body into a Map as would be necessary for what you're trying to do. The request body is just a single string.
The simplest way for you to enable this would probably be to write a Handlebars helper that implements JSONPath or some other mechanism for querying a JSON document, then registering this with the templating transformer when you initialise WireMock.
At some point I'll write handlebars helpers to do this kind of thing for XML and JSON, but that won't be for a while.

Related

Multiple matches for request body in wiremock

Recently learned request matching in wiremock (http://wiremock.org/docs/request-matching/). Curious about what happens when a request's body matches more than one mappings (defined for same url path with different conditions and returns different json response)?
Technically, WireMock won't ever match twice -- once it finds a singular match, it will return that match. Based on my own testing with using separate mapping files, this usually is the most recently added mapping (I don't know how this works with creating the stubs programmatically, but my guess is that the most recently added stub would be matched and returned).
To avoid this sort of ambiguity, there are a few strategies you can employ, but my personal favorite is to use the priority field along with specific and general mapping.
{
"priority": 1,
"request": {
"url": "/test",
"queryParameters": {
"search_term": {
"equalTo": "WireMock"
}
}
},
"response": {
"status": 201
}
}
{
"priority": 10,
"request": {
"url": "/test",
"queryParameters": {
"search_term": {
"matches": "*"
}
}
},
"response": {
"status": 204
}
}
More information about priority can be found here.
I'd also challenge that you shouldn't have two specific mappings that would both be matched -- the matcher should differ enough to separate the two. If you do need two identical matches, in order to simulate data changing or some other workflow, you can use scenarios to achieve this.

Extract and Crete new JSON string

I have some spring MVC based APIs which produces JSON/ XML which represents API output.
{
"data" :
{
"users": [
{
"id": "001",
"name: "abc1",
"type": {
"id": "P",
"name": "Permanent"
}
},
{
"id": "002",
"name: "xyz",
"type": {
"id": "C",
"name": "Contractor"
}
}
]
}
}
I'm passing a parameter with request as
url?fields=users.id, users.type.id
users.type.id is a sub-node in users node.
users node is an array.
Now, what I want to do is to filter those only properties and create the response based upon fields passed in the request.
So the response to above filter condition should be same structure and will only contain wanted fields with values.
I'm trying to build a flat map with keys with a dot notation so I won't lose the track to filter, then I'll rebuild the JSON again. I feel this approach is just unreasonable because Jackson has the .path and .with API's to check existing path. But the real challenge is to extract and create a new JSON which matches the response JSON.
I'm looking for some ideas to achieve this. I don't want to try any third party libs btw. I know some libs are there. I want to prefer Jackson way to do this.
Feel free to add or comment if you have a further ideas.

Is it possible for me to get the current trending topics from Youtube?

Currently, I'm working on getting the latest trend on Youtube. Is there a way to get the JSON Object so that I can use it in my java code.
From V3 you can use the following (from API Reference)
HTTP request
GET https://www.googleapis.com/youtube/v3/videos
API Reference for Videos List
For what you intend the chart parameter of the query string is what you need, and it accepts mostPopular
The response is JSON as the following taken from their API example.
{
"kind": "youtube#videoListResponse",
"etag": etag,
"nextPageToken": string,
"prevPageToken": string,
"pageInfo": {
"totalResults": integer,
"resultsPerPage": integer
},
"items": [
video Resource
]
}

How to create a service using Google cloud endpoint which take a json value in input parameter

I wanted to create a service which can accept JSON as an input to my endpoint. eg.
[{ "name": "Ram","event": "processed" },
{"name": "Raj", "event": "click" }] .
Tried some of the possible ways, cloud endpoints are not supporting arrays or any array related types to use. I tried it to convert the json to string but it's not working for me.
Thanks in advance.
You seem to have an invalid JSON. Try validating it here. As you can see, you will encounter a parsing error.
Change all occurrences of “ with "
[
{
"name": "Ram",
"event": "processed"
},
{
"name": "Raj",
"event": "click"
}
]
and now you have a valid JSON.
More details on JSON can be found here.

Is it possible to use $all and $regex at the same time?

I've got an interesting problem that is somewhat related to this question. I have multiple values for a field that I want to check. For example, say I want to look for a document with the field name matching "bob" and "barker". Initially, I thought to do this:
db.TVHosts.find({ "name": { "$all" :
[ { "$regex": ".*bob.*" }, { "$regex" : ".*barker.*" } ] } })
The way to do it via the command line is to do this:
db.TVHosts.find({ "name": { "$all" : [ /.*bob.*/, /.*barker.*/ ] } })
But that didn't appear to work from Java. Is there some key piece of documentation that I've missed?
EDIT: I'm using MongoDB via the MongoDB Java Driver.
As seen here, to send a Regex to MongoDB in Java you need to use Pattern.compile from java.util.regex.Pattern.

Categories

Resources