How to encode special characters in Wiremock request body? - json

I'm using Wiremock server to mock responses and using JSON format to mock responses.
{
"request":
{
"url": "/token",
"method": "POST",
"bodyPatterns" : [{
"contains": "username=test_user#gmail.com&password=passwordtest_security_token"
}]
},
"response":
{
"status": 200,
"headers":
{
"Content-Type" : "application/json"
},
"jsonBody": {"message": "ok"}
}
This is not working as the '#' in the email is not encoded. I need to pass "test_user%40gmail" for the request to work.
Here the change is only at one place. But for other mocks, request bodies have many special characters**(#,%*\n\s)**. Is there any way to handle the encoding part in the Wiremock.
Also, is there way to encode the string in url?

In the above example there is an accolade missing which prevents is from loading in WireMock. The below example is complete:
{
"request": {
"url": "/token",
"method": "POST",
"bodyPatterns": [{
"contains": "username=test_user#gmail.com&password=passwordtest_security_token"
}
]
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/json"
},
"jsonBody": {
"message": "ok"
}
}
}
In your question you highlighted that you need to use %40 instead of #. I have been unable to replicate this scenario. As I'm unsure if you're posting through a form, or raw string.
In the case that you use a regular Form Data option this results in failure to match.
But sending it as a raw body the result is quite the opposite. The example behaves exactly as you would described it should. Below is a screenshot of my Postman result:

Related

Is there a way to have a wildcard in the bodyFileName for a wiremock stub mapping?

My issue is that I want to give my response file names a more meaningful name but to do this I need to be able to match on any text following the id. Here is my current mapping:
{
"priority": 10,
"request": {
"urlPattern": "/api/v1/customer\\?Id=(.*)&IdType=(.*)&AdditionalInformation=(.*)",
"method": "GET"
},
"response": {
"transformers": [
"dynamic-mapping-transformer"
],
"status": 200,
"headers": {
"Content-Type": "application/json",
"Correlation-ID": "{{request.headers.Correlation-ID}}"
},
"transformerParameters": {
"bodyFileName": "{{request.query.Id}}",
"fileDirectory": "getWorkplaceDetails",
"extension": "json",
"encodeName": false,
"caseInsensitive": true
}
}
}
And the naming convention for the response files should be something along the lines of "Id_foo_bar" but "foo" and "bar" are not available in the request so there is no way for me to know them before the response is posted. I would like to use a wild card in the bodyFileName value to match on anything after the Id and was wondering if anyone knew a way to do this?
EDIT 1
I forgot to mention that the mapping needs to accept multiple files with different names which is why I am looking to use a wild card instead of a static file name.

event.body in lambda function is not an object even though application/json header exists

I have an API Gateway / lambda function set up with a LAMBDA_PROXY integration.
I have a POST resource which is sending a JSON object in the body like the following:
{
"version": 123,
"attributes": [
{
"id": 1123,
"type": "integer",
"defaultValue": 88
}
]
}
The POST request is sent with a Content-Type: application/json header.
I expect the lambda function to receive event.body as an object so that I will be able to reference the object like this:
const version = event.body.version;
In fact, this does not work and I am forced to run a JSON.parse() on event.body.
At first I was thinking that the content-type header was not getting to the lambda but then I printed to the log event.headers and the header is in fact there:
{
"Accept": "*/*",
"content-type": "application/json",
"Host": "jfpvip409c.execute-api.eu-west-1.amazonaws.com",
"User-Agent": "curl/7.65.0",
"X-Amzn-Trace-Id": "Root=1-5fe9940a-3f3634ce4ccd26f5211c21d1",
"X-Forwarded-For": "192.118.35.111",
"X-Forwarded-Port": "443",
"X-Forwarded-Proto": "https"
}
Can somebody please help me understand why this is the case ?
Thanks in advance
nsteiner

multiple accept values in request for wiremock

I'm attempting to write a mock for my api.
To test it correctly I need a request whick allows application/json and / to be accepted.
Which sould work in HTML like this
application/json, */*
When I use this in my wiremock mapping json file, i recieve errors, or with minor changes just "not matching" response.
My Json is build like this
"request": {
"urlPathPattern": "/publish",
"method": "POST",
"headers": {
"Accept": {
"contains": "application/json, */*"
}
},
"bodyPatterns": []
}
I couldn't find any solution, neither on the wiremock docs nor with the help of google, but maybe my description of the problem was just not showing the results I would have needed.
Can anyone enlighten me?
with best regards
As I understand your problem, you need to accept both application/json and */* as Accept header values. I'm assuming that the case where you'd receive something matching */* would interpret those * as wildcards, so some/type would match. In this case, you just want to make sure that the Accept header has some value.
If that is the case, I'd recommend you use matches to do regex matching on the header.
"request": {
"urlPathPattern": "/publish",
"method": "POST",
"headers": {
"Accept": {
"matches": ".*\/.*"
}
},
"bodyPatterns": []
}
If you instead need to match exactly on either application/json or */*, you'd need to do something like...
"request": {
"urlPathPattern": "/publish",
"method": "POST",
"headers": {
"Accept": {
"matches": "(application\/json|\*\/\*)"
}
},
"bodyPatterns": []
}

Stringify JSON in Logic App

We are sending messages to a service bus using a logic app. These messages will later be consumed by another service, the service expects the message content to be a string - essentially a stringified JSON object, with escape characters.
We are not able to find a method to stringify a JSON object in Logic Apps. Even if we explicitly provide a escaped string the logic app itself detects that it's stringified JSON and unescapes it and then sends it as a JSON object. We don't want that, we simply want it to send the string as it is. We have already tried changing the content type to text/plain, it does not work. The logic app always sends the unescaped string as JSON.
This post on MSDN: https://social.msdn.microsoft.com/Forums/office/en-US/e5dee958-09a7-4784-b1bf-facdd6b8a568/post-json-from-logic-app-how-to-escape-data?forum=azurelogicapps is of no help because doing this will violate the request contract of the message consuming service
Do you need the stringified message to include opening and closing double quotes?
I've tried this and it worked for me.
I have my JSON object as an output of a compose
Then, I initialised a variable with the Base64 encoded value of the escaped stringified JSON (you need to add ALL the proper escaping required,
mine was just a PoC)
Then, you send the variable already in Base64 to Service Bus. (You need to remove the encoding on that action).
"actions": {
"Compose_JSON_Object": {
"inputs": {
"message": "I want this as a string"
},
"runAfter": {},
"type": "Compose"
},
"Initialise_Variable_with_Stringified_JSON_Base64_Encoded": {
"inputs": {
"variables": [
{
"name": "jsonAsStringBase64",
"type": "String",
"value": "#base64(concat('\"', replace(string(outputs('Compose_JSON_Object')), '\"', '\\\"'), '\"'))"
}
]
},
"runAfter": {
"Compose_JSON_Object": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Send_message": {
"inputs": {
"body": {
"ContentData": "#variables('jsonAsStringBase64')",
"ContentType": "text/plain"
},
"host": {
"connection": {
"name": "#parameters('$connections')['servicebus']['connectionId']"
}
},
"method": "post",
"path": "/#{encodeURIComponent(encodeURIComponent('temp'))}/messages",
"queries": {
"systemProperties": "None"
}
},
"runAfter": {
"Initialise_Variable_with_Stringified_JSON_Base64_Encoded": [
"Succeeded"
]
},
"type": "ApiConnection"
}
},
This way, I got the message stringified.
HTH

Describe http request/reply in json

I have a case where I have to serialize a N number of http requests, perform the requests in parallel, and describe the response in the same json. To do this in json is pretty easy obviously, I could do something like:
[
{
"request": {
"uri": "http://something",
"headers": [
{
"Content-Type": "application/json"
}
],
"body": ".. snip .. you get the idea",
"other-stuff": ""
},
"response": {
// something along the lines of the request structure to be filled in after the request completed
}
},
// second request/response here, and so on.
]
But while I could make this format up myself, I feel this problem is (very) likely solved before, and there should be some sort of json standard floating around that does this. Can't find it though. Have you encountered this somewhere?