I'm trying to make an api so I'm using the Swagger UI thing and I'm trying to make a document return something like this
{
"link":"https://example.com/images/image" + Math.floor(Math.random() * (4-1)+1) + ".png"
}
How would I do this, because if I do this I get this error
{
"description": "Malformed JSON object found during read: com.fasterxml.jackson.core.JsonParseException: Unexpected character ('+' (code 43)): was expecting comma to separate Object entries\n at [Source: (String)"{\n"link":"https://example.com/images/image" + Math.floor(Math.random() * (4-1)+1) + ".png"\n}"; line: 2, column: 44]",
"code": 400
}
(I'm new to the site so the post isn't that good)
Thanks
Related
I am trying to read output from my lambda function into a variable in my step function. The lambdas default output is
return {
'statusCode': 200,
'body': json.dumps('Hello from Lambda!')
}
What I would like to return is a json object like this
{
"version": version,
"bucket": bucket
}
where the version and bucket name gets passed from the lambda. in my step function, I am trying to capture this and insert it into an s3 url like this:
"S3Uri.$": "States.Format('s3://{}/path/to/script/{}/script.py',$.bucket, $.version)"
However, I am struggling with having the correct output from the lambda and how to grab the value in step functions. I've tried
return {
'statusCode': 200,
'body': json.dumps({
"version": version,
"bucket": bucket
}) }
And various ways of constructing the json object as a string to the body, eg
"{\"version\": \"" + version + "\",\"bucket\": \"" + bucket + "\"}"
But I can't find the right combo, and the job keeps failing. Here is an example error message
The JsonPath argument for the field '$.bucket' could not be found in
the input '{"statusCode": 200, "body": "{\"version\":
\"v0-1\", \"bucket\":
\"sagemaker-us-west-2-removed\"}"}'"
How should I construct the lambda output, and the corresponding step function variable to have the values pass through? Again, I want the lambda to tell step functions what bucket and version was used, and then have step functions insert these values into an s3 url string.
EDIT: here is the full error message for one of the attempts
{
"error": "States.Runtime",
"cause": "An error occurred while executing the state 'Postproc' (entered at the event id #38). The function 'States.Format('s3://{}/AAPM/AAPM_2207/prod/{}/meta/scripts/preproc/aapm-postproc.py',$.bucket, $.version)' had the following error: The JsonPath argument for the field '$.bucket' could not be found in the input '{\"statusCode\": 200, \"body\": \"{\\\"version\\\": \\\"v0-1\\\", \\\"bucket\\\": \\\"sagemaker-us-west-2-removed\\\"}\"}'"
}
As in this answer the trick was just to get rid of json dumps.
return {
'statusCode': 200,
'body': {
"version": version,
"bucket": bucket
}
}
and I could access them fine with $.bucket, $.version
I am new to JMeter. I am using 'CSV Data Set Config' with "While Controller". The sample data of CSV file is as follows
Example-
Id,BobId,TarFulDate,SSRId,EDPNumber,SiteCode,CrBy,CrDate,ModBy,ModDate,Status,Version,ToolVer,ShipDate,TMDate,MaintComments,ParentId,TOName
990:548254,18ATR0002,2018-04-02T10:00:00+05:30,548254,MEATLM-18ATR0002-001,NEATOM,LVerlli,2018-03-01T16:12:37.7230000+05:30,PFibacher,2018-05-15T12:19:33+05:30,Submitted,12,0,1,2018-04-02T10:00:00+05:30,,547011,18ATR0002-0600-0-2
Inside the "While Controller", I have an "If Controller". From Inside the "If Controller" I am sending the "Http Request" using one of the properties "${Id}" of the csv dataset. So far, so good. The HTTP Request correctly takes one row at a time of csv data set and gets the Json response back. Since I have to validate multiple properties of the Json response, I am using "JSR 223 Assertion".
The "JSR 223 Assertion" process the very first of row of CSV Dataset correctly. However, for any subsequent row, it just takes the value of the first row of csv file. So, the assertion of only first row is successful. It fails for rest of the rows.
The code is as follows -
import groovy.json.JsonSlurper;
def failureMessage = "";
def jsonResponse = null;
rawId = "${Id}"; //I tried this also. Didn't work.
JsonSlurper JSON = new JsonSlurper ();
try {
jsonResponse = JSON.parseText(prev.getResponseDataAsString());
} catch (Exception e) {
failureMessage += "Invalid JSON.\n"
}
if(!"200".equals(prev.getResponseCode())){
failureMessage += "Expected <response code> [200] but we got [" + prev.getResponseCode() + "]\n\n" ;
}
if ((jsonResponse.createdBy !="${CreatedBy}")) {
failureMessage += "Expected:[" + jsonResponse.createdBy + " Found:" + "${CreatedBy}" + "]\n\n";
}
if ((jsonResponse.id !=rawId)) {
failureMessage += "Expected:[" + jsonResponse.id + " Found:" + rawId + "]\n\n";
}
The expectation is the "JSR 223 Assertion" should access the current data row of the CSV Data Set. As "Http Request" picks the current row correctly inside the same "If Controller" the "JSR223 Assertion" should also do the same.
An answer coming very late; you may already have got your answer. I am still posting my answer so that anyone else, like me, looking for a solution for this requirement, may find it helpful.
When I faced this need, I used the args setting on the JSR223 Assertion script settings.
Since your CSV has many columns, I have used a smaller CSV to demonstrate the solution, one with only 2 columns.
Id,Name
1,New Delhi
2,Calcutta
3,Chennai
Now, access them by index in your Groovy script like this:
println( "Id: " + args[ 0 ] )
println( "Name: " + args[ 1 ] )
Don't use ${} syntax inside JSR223 script, it will cache values, use vars.get instead:
vars.get("Id");
I'm trying to make API request with using Apps Script. API is GraphQL based.
I'm using JSON.stringify function. But API returns an error.
Request:
payload={"query":"{mutation {change_column_value (board_id: 177955, item_id: 287466289, column_id:\"phone\", value: \"{phone : 15065332974, countryShortName: \"US\" }\") {name column_values{ id value}}}"}}
I'm getting error;
{"errors":[{"message":"Parse error on \" }\" (STRING) at [1, 148]","locations":[{"line":1,"column":148}]}]}
Apps Script Code:
var us = "US"
var column_values = '{ \
mutation {change_column_value (board_id: 177955, item_id: '+ 287466289 +', column_id:"phone", value: "{phone : 15065332974, countryShortName: \"' + us +'\" }") {name column_values{ id value}} \
}';
settings = {
"method": "POST",
"headers": {"Content-Type" : "application/json","Authorization" : "eyJhbGciOiJIXXXXXXXXXX"},
"payload" : JSON.stringify({query:column_values})
}
response= UrlFetchApp.fetch(url, settings);
Brackets in a GraphQL operation indicate a selection set -- one or more fields that are being requested. The operation itself (whether a query or a mutation) is not a field, so you don't wrap the whole operation in brackets.
Correct:
mutation {
doSomething
}
Incorrect:
{
mutation {
doSomething
}
}
The only time you will see brackets that look like they are on the "outside" is when using query shorthand.
Provided that value is a String, then your use of backslashes to escape the double quotes inside that string should be fine.
You might also consider using variables, which would clean up your code considerably and make it less error prone.
You do not need to escape special characters inside a JSON request.
The syntax implies using key-value pairs assigned to each other with a colon, whereby strings are located inside quotes (not escaped with a backslash!), while numbers and variable names are not.
The brackets should be used in function of your desired API request as documented.
I'm trying to send a json payload in quartz scheduler. I have the header set to Content-type:application/json, but for some reason my json string is throwing an error: Uncaught error, unexpected token in json.
The original json that I'm sending to a graphql service looks like this:
{
GetAllAuthors{
id
name
}
}
But to make it work in quartz, I need to mimic a rest API call, which is why I tried using the following:
{ "query":{{""{\nGetAllAuthors {\nid\nname\n}\n\n}""}} }
The above is also giving me the "Uncaught error, unexpected token in json" error. Is there something that I'm missing or overlooking?
PS: I tried using an online json formatter and when I try to validate the above json, I get the following error:
Error: Parse error on line 2:
{ "query": { { "" {\ nGetA
--------------^
Expecting 'STRING', '}', got '{'
That's not valid Json. This is how it might look if it were:
{
"GetAllAuthors": [
"id",
"name"
]
}
but I suspect you're trying for something like this:
{
"GetAllAuthors": {
"id": 123,
"name": "James Brown"
}
}
Play here until you get it right: https://jsonlint.com/
Edit: I've not worked with GraphQL, but this page shows how a (non JSON) GraphQL query might be transferred over Http by POSTing JSON or GETting using querystrings: https://graphql.org/learn/serving-over-http/
I figured this out by testing through Mozilla's network tab - the correct format is:
{"query":"{\n GetAllAuthors{\n id\n name\n}\n}\n","variables":null, "operationName":null}
I have been trying for a few days to get a parameter sent from the API Gateway in AWS to a Lambda function and I am having no success.
I decided to start from the beginning so I followed their walkthrough (http://docs.aws.amazon.com/apigateway/latest/developerguide/getting-started.html#getting-started-new-lambda)
I have checked this walkthrough twice and I have followed the steps to the letter.
Problem
When I test the API from Postman or in Swift I am getting the error:
{"message": "Could not parse request body into json: Unexpected character (\'-\' (code 45)) in numeric value: expected digit (0-9) to follow minus sign, for valid numeric value\n at [Source: [B#c036d15; line: 1, column: 3]"}
In postman, When I view the result as JSON I just get
Bad String
Lambda Function
The function is the basic example from the Walkthrough:
console.log('Loading event');
exports.handler = function(event, context) {
var name = (event.name === undefined ? 'No-Name' : event.name);
console.log('"Hello":"' + name + '"');
context.done(null, {"Hello":name}); // SUCCESS with message
};
When Tested from the Lambda Console and with the Test data I get the result:
{
"Hello": "TestUser123"
}
When Tested from the API Gateway Test, The result is also:
{
"Hello": "TestUser123"
}
Can anyone see why both test consoles are allowing this work but when tested with POSTMAN or used within a Swift Script it does not work ?
Edit 1
In postman, I have set the content-type to application/json
The script returns the default:
{
"Hello": "user"
}
However, When I add in the parameters name and TestUser123 in POSTMAN, this is when it returns the error.
Update 1
Ok, so I changed the mapping template to one that I found on another answer:
{ "name": "$input.params('name')" }
Now the result is:
{
"Hello": ""
}
Any Ideas why it is not getting the name?
I just got stuck with this today.
your mapping template is:
{ "name": "$input.params('name')" }
AWS uses AWS Velocity templates, which; even though looks like JSON, is different.
if you use
{ "name": $input.params('name') } // notice no quotes
for the mapping template right at the integration request step, then it should work as expected.
Read the error message very carefully, it actually tells you the problem. For example, I got
Could not parse request body into json: Unexpected character (\'\"\' (code 34)): was expecting comma to separate Object entries
So the problem is that I'm missing a comma. I check my Lambda's Integration Request - Body Mapping Template:
{
"age" : $input.json('$.persondata.age'),
"income" : $input.json('$.persondata.income')
"height" : $input.json('$.persondata.height')
}
Can you spot the problem? I am missing a comma after the income line.
Here is another example.
Could not parse request body into json: Unexpected character (\'}\' (code 125)): expected a value
When I look at the Integration Request - Body Mapping Template:
#set($inputRoot = $input.path('$'))
{
"age" : $inputRoot.age,
"height" : $inputRoot.height,
"income" : $inputRootincome
}
Can you spot the problem? I am missing a dot in $inputRootincome.
Error Message :
Could not parse request body into json: Could not parse payload into json: Unrecognized token \' \': was expecting (\'true\', \'false\' or \'null\')
Cause of the error : When string values inside the json are not assigned using double quotations in the aws mapping template the error occurs.
Solution : (Please Note : This example is for application/json type request template)
Actually the solution for the problem is, if you are using a value of type string in json then its value should be assigned inside a ("" - double quotation marks) in the mapping template.
The below shown example has the following attributes :
customerId - string (Please note : this value comes from a query parameter)
customerName - string
customerAge - integer
isPermanentEmployee - boolean
customerAddress - string (Please note this is an optional parameter)
And the mapping template should be defined like the example shown below
Refer the example below :
#set($inputRoot = $input.path('$'))
{
"CustomerId": "$input.params('customerId')",
"CustomerName": "$inputRoot.customerName",
"CustomerAge": $inputRoot.customerAge,
"IsPermanentEmployee": $inputRoot.isPermanentEmployee
"CustomerAddress ": #if($inputRoot.customerAddress == "") "" #elseif($inputRoot.customerAddress != "") "$inputRoot.customerAddress" #end
}
If you note the above mapping template, I would have given string values inside double quotation marks("") which will solve the error
Also this example contains how to handle optional parameters in aws mapping templates using #if#else statements.
It is likely that you had copy-pasted multiple lines in your "Integration Request" in the API gateway.
When copying a line and pasting it below, you might have copied the hidden character '\n' at the end of that line. This is probably causing issues at the lambda function.
Example: Copying the line containing age and pasting it twice and modifying them to have height and income respectively.
#set($inputRoot = $input.path('$'))
{
"age" : $inputRoot.age,
"height": $inputRoot.height,
"income": $inputRoot.income
}
Instead of copy-pasting, just type the line out for height and income.