Cannot pass an array in request body using Api Gateway - json

I have an API with PUT method in AWS Api Gateway. I'm passing an object in Request Body with content type application/json
{
"uuid": "i_1",
"insiderName": "Sam Keys",
"profileImage": "https://do6gbw1x8hs3.cloudfront.net/spree/cover_images/53977/default/400.jpg",
"gender": "Female",
"fullDescription": "This is the full description",
"shortDescription": "This is the short description",
"tribes": ["Adventurer"]
}
I'm passing a key called tribes and a value as an array. But I'm getting this error:
{"message": "Could not parse request body into json: Unexpected character (\'A\' (code 65)): was expecting comma to separate Object entries\n at [Source: [B#5d62dfa1; line: 8, column: 17]"}
I believe the error is caused by the array in the request body

We had same problem ,I added a work around by changing the array of strings into pipe separated single string and converted back to array of string after the Json is parsed on the API .
IDictionary<string, string> dictionary = new Dictionary<string, string>();
foreach (KeyValuePair<string, IEnumerable<string>> reportObject in dictionary)
{
// do something with entry.Value or entry.Key
dictionary[entry.Key] = string.Join("|", reportObject.Value.Where(x => string.IsNullOrWhiteSpace(x)));
}

Related

How do I correctly deserialize json that consists of a list item that includes another object?

The client I am using returns json like this:
[
{
"source": "ANY"
}
]
That is, the element of the array that the object is in.
I'm trying to make a request like this:
restTemplate.postForObject<AbcdResponse>(
"/address",
listOf(value).let { JsonHttpEntity(it) }
)
data class AbcdResponse(
val obj: AbcdObject
)
data class DaDataAddress(
val source: String?
)
But I get the HttpMessageNotReadableException exception:
org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize instance of `com.app.client.abcd.domain.AbcdResponse` out of START_ARRAY token; nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `com.app.client.abcd.domain.AbcdResponse` out of START_ARRAY token
at [Source: (ByteArrayInputStream); line: 1, column: 1]
How can I deserialize the response correctly?
As you probably noticed, the response as a whole is a JSON array. You can tell by the square brackets [ ... ] surrounding the whole thing.
Because of this, you cannot deserialize it as an object (such as AbcdResponse). What you should do instead is use List<DaDataAddress> instead of AbcdResponse.
You don't really need AbcdResponse. What you need is to use a ParameterizedTypeReference as follows while calling the service:
restTemplate.exchange("/address",
HttpMethod.POST,
listOf(value).let { JsonHttpEntity(it) },
ParameterizedTypeReference<List<DaDataAddress>>() {})
The reason is that the service that you are calling is returning a JSON array of JSON objects.

How do I deserialize json with nested breakslashes?

I have a piece of json, but when I go to deserialize it, it won't map correctly to an object in C#.
Ex:
"location": {
"raw": "{\"address1\":\"1234 Fake Street\",\"address2\":null,\"city\":\"Madison\",\"state\":\"WI\",\"zip\":\"12345\",\"country\":\"US\"}"
},
I'm using restSharp to make the api call and Newtonsoft.Json
var test = JsonConvert.DeserializeObject(content);
I've tried the following and failed:
Parsing the json
Replacing the backslashes
Serializing, then deserializing again
JavascriptSerializer
Is there anyway to deserialize a string into an object with the backslashes there?

Accessing JSON response

I am storing the response of a REST Get request and trying to access as below,
final JSONObject receivedItem = new JSONObject(response.readEntity(String.class));
This is the sample response,
[
{
"timeStamp": 1511136000000,
"contextKeys": [
{
"tKey": "Test1",
"contextKey": "Location",
"contextValue": "San Jose",
"eCount": 3
},
{
"tKey": "Test1",
"contextKey": "Name",
"contextValue": "User1",
"eCount": 3
}
}
]
And i am getting the below error,
org.json.JSONException: A JSONObject text must begin with '{' at character 1
at org.json.JSONTokener.syntaxError(JSONTokener.java:496)
at org.json.JSONObject.<init>(JSONObject.java:180)
at org.json.JSONObject.<init>(JSONObject.java:403)
Any clues ?
Thanks
As Rajkumar pointed out, in your example there is a missing close bracket - but this may just be a simple typing error.
The actual error message is saying A JSONObject text must begin with '{' which is because JSON objects are exactly that, objects. You need to use a JSONArray to parse your example JSON as follows:
final JSONArray receivedItem = new JSONArray(response.readEntity(String.class));
This may change some of your other code to handle this as an array vs an object.
If your problem is with storing and accessing json response try this response instead;
I am presuming that you are using javascript; Anyways, core idea is the same;
var jsonStorage;
$.getJSON('your url',(json) => {
jsonStorage = json;
});
console.log(jsonStorage) //your jsonresponse is now available here;

How to pass a JSON string to API Gateway as query Parameter

How can i pass a JSON object like {val: 1} to my Lambda function as a query parameter?
Following Standardized way to serialize JSON to query string? i URL-encoded my JSON object and requested the following: mysite.com/path?json=%7B%22val%22%3A%201%7D
As requestTemplates i tried the following two options
"json": "$input.params().querystring.json"
"json": "$util.parseJson($input.params().querystring.json)"
But i got this error message:
{"message": "Could not parse request body into json: Unexpected
character (\'v\' (code 118)): was expecting comma to separate OBJECT
entries\n at [Source: [B#37a2970e; line: 1, column: 47]"}
If i do not encode the query string so: mysite.com/path?json={"val":1} i get a 400 error
Your mapping template is producing no valid JSON, you have to wrap the key/value pair in curly braces
I guess you do not want to wrap the value in quotes, it will be a string and no object otherwise
You can use $util.urlDecode to decode URL encoded strings
Your mapping template should look like this:
{"json": $util.urlDecode($input.params().querystring.json)}
For mysite.com/path?json=%7B%22val%22%3A%201%7D this mapping template will result in the following JSON:
{
"json": {
"val": 1
}
}
If you want the querystring JSON to be passed on the root level to your Lambda function use this as a mapping template:
$util.urlDecode($input.params().querystring.json)

how to find the number of response object in json

I have a JSON response to validate. I am writing a test secario where I want to assert if the response contains the number of objects or not. JSON response:
{
"Result": {
"resultCode": "1000",
},
"ResultClient": {
"responseCode": null,
"statusCode": null
},
"creditCard": {
"number": null
}
}
I want to assert that the response has 3 objects. How to do that? The response obj dosn't have size() or count() so I am unable to understand the path to the solution.I am writting my tests in rest-assured .
TestResponse testResponse = given()
.contentType("application/json; charset=UTF-8")
.body(cTestRequest)
.when()
.post(uri)
.as(TestResponse.class);
now how to assert the json contains the 3 obj and the parameters inside the objs?
You can do something like this:
when().
get("/x").
then().
body("keySet().size()", is(3));
The reason is that the JSON object is treated as Groovy Map so you can invoke functions on it. keySet() returns all keys as a Set and size() returns the size of this Set.