REST Script for PUT Request on Multiple Records - json

I have a REST script that's currently working well for single-record PUT requests. I'm looking to update the script such that it can support multi-record updates.
Current Script:
function put(context) {
// doValidation([context.recordtype, context.id], ['recordtype', 'id'], 'PUT');
var rec = record.load({
type: context.recordtype,
id: context.id
});
var values = context.values;
for (var fldName in values) {
if (values.hasOwnProperty(fldName)) {
rec.setValue({
fieldId: fldName,
value: values[fldName]
});
}
}
rec.save({
ignoreMandatoryFields: true
});
rec = record.load({
type: context.recordtype,
id: context.id
});
return rec; // reloading includes the results of any triggered actions.
}
return {
post: postProcess,
put: put
};
Working Single Record JSON body payload for PUT request:
{
"recordtype": "customrecord_record",
"id": "201",
"values": {
"custrecord_managementpriority": "3"
}
Ideally looking for the PUT script to support this payload structure:
{
"recordtype": "customrecord_record",
"id": "201",
"values": {
"custrecord_managementpriority": "3"
}
},
{
"recordtype": "customrecord_record",
"id": "204",
"values": {
"custrecord_managementpriority": "4"
}
}
(Wrapped in [ ] or however necessary of course).

Solved. Will leave this post up in case anyone else runs into this issue. This piece upfront did the trick:
var contexts = context;
if(!Array.isArray(contexts))
contexts = [contexts];
var rec;
contexts.forEach((context) => {

Related

Postman test - automation test

How can I write a Postman test that checks if my response body contains nets": {"4": "1"}?
I have trouble to put this "parameter_list": { "2": ... part into pm.expect(). "parmeter_list" can contain many objects with name that is "number"
{
"request_id": 358624578,
"product_list": [
{
"symbol": "AX-174",
"value_ids": [
271,
1437038,
.
.
.
1757620
],
"id": 65869
}
],
"do_show": true,
"do_show_list": {
"do_show_products": true,
"do_show_parameters": true,
"do_show_parameter_values": true,
"do_show_flags": false
},
"parameter_list": {
"2": {
"value_type_id": 0,
"name_full_txt": "Producent",
"unit_text": null,
"product_count": 1,
"nets": {
"3": "1"
},
"pos": 0,
"id": 2
}
}
}
If you need to test only against "2" key in parameter_list, I would suggest the following solution:
const jsonBody = pm.response.json();
const parameterList = jsonBody.parameter_list["2"];
const nets = {
"nets": {
"4": "1"
}
};
pm.test("check parameter '2' contains nets", () => pm.expect(parameterList).to.deep.include(nets));
I believe, that you can easily modify both nets and parameterList to match your actual case.
EDIT:
If you need to iterate over all objects in parameter_list you can use for..in loop within your test:
const jsonBody = pm.response.json();
const nets = {
"nets": {
"3": "1"
}
};
pm.test("check all parameters contains nets", () => {
for(let parameter in jsonBody.parameter_list) {
pm.expect(jsonBody.parameter_list[parameter]).to.deep.include(nets);
}
});
Or for more readability use tests[]:
for(let parameter in jsonBody.parameter_list) {
tests[`Check 'nets' object is in ${parameter} parameter`] = pm.expect(jsonBody.parameter_list[parameter]).to.deep.include(nets);
}
To add to #n-verbitsky accepted answer, Postman provides test snippets in the 'test' tab of a request. More information on testing in Postman and how to write test scripts can be taken from their docs: learning center.
I think it would be beneficial to show the test code you already have written.

get json object attribute with 'dot' in name

*** Problem solved : json.stringify was the problem.. much easier to handle when its gone.
var DBName = result['Document']['SW.Blocks.GlobalDB']['AttributeList']['Name'];
I have a xml file which describes a datablock from a PLC and want to get specific values with JS.
I converted it with xml2js module, so i have a json object to work with.
{
"Document": {
"Engineering": {
"$": {
"version": "V15"
}
},
"SW.Blocks.GlobalDB": {
"$": {
"ID": "0"
},
"HeaderAuthor": "",
"HeaderFamily": "",
"HeaderName": "",
"HeaderVersion": "0.1",
"Interface": {
...
...
"Name": "datentypen",
"Number": "6",
"ParameterModified": {
"_": "2018-09-05T11:49:37.0862092Z",
"$": {
"ReadOnly": "true"
}
},
}
}
I want to print out the "Name" and the "Number", which are part of the "AttributeList".
So how to handle with the "SW.Blocks.GlobalDB"?
Getting error : "TypeError: Cannot read property 'SW' of undefined"
var fs = require('fs');
var xml2js = require('xml2js');
var xml = fs.readFileSync('datentypen.xml');
var parser = new xml2js.Parser({explicitArray: false});
parser.parseString(xml, function(err, result) {
if (err) {
console.error('xml2js.parse error: ',err);
} else {
var injson = JSON.stringify(result,null,3);
console.log(injson);
// var injson2 = JSON.parse(injson);
// var DBnummer = injson.Document.SW.Blocks.GlobalDB.AttributeList["Name","Number"];
// console.log(DBNummer);
};
});
I read a lot about this theme but didnt found a concrete answer..
When i write ["SW.Blocks.GlobalDB"], an error about [ comes around.
Can you try reading the JSON array using Key-Value pair? I had similar issues but with a different programming language.

How to remove Task json properties in Nancy.Response.AsJson

I've made one of my API endpoints and inner logic asynchronous and when previously I've used Response.AsJson(Foo.bar()) , it would return the json representation normally, but now I see this appended to it:
{
"result": [
{
"id": "59d680cc734d1d08b4e6c89c",
"properties": {
"name": "value"
}
}
],
"id": 3,
"exception": null,
"status": 5,
"isCanceled": false,
"isCompleted": true,
"isCompletedSuccessfully": true,
"creationOptions": 0,
"asyncState": null,
"isFaulted": false
}
But I want it to be like this:
"id": "59d680cc734d1d08b4e6c89c",
"properties": {
"name": "value"
}
As I understand, it's because I've wrapped my object in a Task , but I can't figure out, how with Nancy framework, which I use the Response.AsJson, to make it so the properties are excluded. I can obviously omit the Response.AsJson of the returned object, but then response is no longer Json if requesting through web-browser for example.
For further example
NancyModule for routing API:
public ItemCatalogModule(IItemCatalog itemCatalog) : base("/itemCatalog")
{
Get("/fetch/{id}", async parameters =>
{
var id = (string) parameters.id;
var response = await Response.AsJson(itemCatalog.GetItem(id));
return response;
});
}
How the interface looks like of ItemCatalog:
public interface IItemCatalog
{
Task<Item> GetItem(string id);
}
You shoud do this :
public ItemCatalogModule(IItemCatalog itemCatalog) : base("/itemCatalog")
{
Get("/fetch/{id}", async parameters =>
{
var id = (string) parameters.id;
return Response.AsJson(await itemCatalog.GetItem(id));
});
}

API Gateway + Lambda download CSV file

I want to do a csv download link with API Gateway + Lambda.
But there is a problem that lambda always return JSON.stringify. Is there a way to resolve this?
s-function.json
"responses": {
"default": {
"statusCode": "200",
"responseParameters": {
"method.response.header.Content-disposition": "'attachment; filename=testing.csv'"
},
"responseTemplates": {
"text/csv": ""
}
}
}
handler.js
var json2csv = require('json2csv');
module.exports.handler = function(event, context, cb) {
var fields = ['car', 'price', 'color'];
var myCars = [
{
"car": "Audi",
"price": 40000,
"color": "blue"
}, {
"car": "BMW",
"price": 35000,
"color": "black"
}, {
"car": "Porsche",
"price": 60000,
"color": "green"
}
];
var csv = json2csv({ data: myCars, fields: fields });
return cb(null, csv);
};
In the downloaded csv file.
"\"car\",\"price\",\"color\"\n\"Audi\",40000,\"blue\"\n\"BMW\",35000,\"black\"\n\"Porsche\",60000,\"green\""
Updated:
I still trying but thank you at least I have direction.
By the way, I can't find API Gateway doc about $input.body.replaceAll. replaceAll is Java function?
Finally, I resolve this by below code in Api Gateway template.
$input.body.replaceAll("\\""","").replaceAll("""","").replaceAll("\\n","
")
s-function escaped double quotes.
"responseTemplates": {
"text/csv": "$input.body.replaceAll(\"\\\\\"\"\",\"\").replaceAll(\"\"\"\",\"\").replaceAll(\"\\\\n\",\"\n\")"
}
return data:
car,price,color
Audi,40000,blue
BMW,35000,black
Porsche,60000,green
The template final replaceAll is weird. CSV don't recognize \n or \r\n, but I try copy new line in IDE and pass to code. It work and it's magical.
Serverless has changed a bit since you asked this question but if you're using the lambda_proxy method of integration, you can use a handler like:
module.exports.handler = (event, context, callback) => {
const csvRows = [
'1,"blah",123',
'2,"qwe",456'
]
const result = csvRows.reduce((prev, curr) => {
return prev + '\n' + curr
})
callback(null, {
headers: {
'Content-Type': 'text/csv',
'Content-disposition': 'attachment; filename=testing.csv'
},
body: result,
statusCode: 200
})
}
Note: I've used ES6 features so you'll want to use Node 6 or higher to directly copy-paste this example.
If you can't fix it on the Lambda function, you could probably do a replaceAll() in the API Gateway mapping template. I think this could work just to replace the escaped double quotes:
$input.body.replaceAll("\\""","")
Edit: So the swagger would be (if I got the escaping right):
"responses": {
"default": {
"statusCode": "200",
"responseParameters": {
"method.response.header.Content-disposition": "'attachment; filename=testing.csv'"
},
"responseTemplates": {
"text/csv": "$input.body.replaceAll(\"\\\"\"\",\"\")"
}
}
}

Restangular - custom search - search within an array

Lets assume I have an mongodb items collection looking like this (MongoLab):
{
"_id": {
"$oid": "531d8dd2e4b0373ae7e8f505"
},
"tags": [
"node",
"json"
],
"anotherField": "datahere"
}
{
"_id": {
"$oid": "531d8dd2e4b0373ae7e8f505"
},
"tags": [
"ajax",
"json"
],
"anotherField": "datahere"
}
I would like to get all items where a node is within the tags array.
I've tried the below, but no success - it is returning all items - no search performed?
Plunker demo : http://plnkr.co/edit/BYj09TOGyCTFKhhBXpIO?p=preview
// $route.current.params.id = "node" - should give me only 1 record with this tag
Restangular.all("items").customGET("", { "tags": $route.current.params.id });
Full example, return same record for both cases:
var all = db.all('items');
// GET ALL
all.getList().then(function(data) {
$scope.all = data;
console.log(data);
});
// SEARCH for record where "tags" has got "node"
all.customGET('', { "tags": "node"}).then(function(data) {
$scope.search = data;
console.log(data);
});
Any suggestion would be much appreciated.
According to Mongolab REST API Documentation you have to pass the query object with the q parameter. In your case it is q={"tags":"node"}.
Using Restangular it will be like this:
Restangular.all("items").customGET('', { q: {"tags": "node"}})