How to send POST requests with array properties (Ionic 2 HTTP plugin)? - ionic-framework

In one of my Ionic 2 projects I need to send a POST request to a server with a JSON body that looks like this:
var body = { "prop" : 1,
"prop2" : "Test",
"prop3": [{ "id" : "1", "qty": 1, "details": "Test" }]
}
I am using the following code to call the server using the native HTTP plugin (1.2.0) in Android:
http.post(url, body, {}).then(function() { ... })
But my server is receiving the following:
{ "prop" : 1,
"prop2" : "Test",
"prop3": "[{ \"id\" : \"1\", \"qty\": 1, \"details\": \"Test\" }]"
}
As you can see, the array property "prop3" is being turned into a string, so my server is failing to parse it because it's expecting an array, not a string.
One of the things I could do is to change the server side code to parse this string back into an array (but that would be far from ideal). The other thing I could do is to parse the JSON object manually with JSON.stringify.
So, is this just a bug in the plugin or am I missing something here?
Native HTTP plugin

Try set http.setDataSerializer("json");
And send data as usual: http.post(url, body, {})
Then http plugin will send data with application/json content type and support deep structure of json, as stated in the documentation:
https://github.com/silkimen/cordova-plugin-advanced-http#setdataserializer

So, after taking a look at the plugin's source code (the Java one, I'm testing my application in Android) it seems that I won't be able to use the plugin as is (I would need to modify it). What I found was this:
In CordovaHttpPost.java, the body of the request is sent as Form data (simple key-values).
request.form(this.getParams()); //Map<?, ?>
That's why my array property is converted into a string (and any other complex object for that matter)
TL;DR this plugin is only useful to send simple JSON key-value objects (no nesting, no complex objects, no arrays, etc.).

Related

How do I avoid duplicate fields in Json request payload ? I'm using Apache Camel with REST

I wanted to parse json request by identifying duplicate fields in the request body. E.g. Assume I have below request.
`"employee": {
"name": "abc",
"name": "xyz",
"id": "6754",
"title": "supervisor",
}`
The employee request above has duplicate name field. ideally during json validation/parsing the second duplicate field takes precedence over first but I want to invalidate this kind of json request. How do I achieve this in Camel REST. Below is the approach that I tried but nothing worked. In myorg.apache.camel.builder.RouteBuilder, I tried configuring DataFormatProperty to use DeserializationFeature FAIL_ON_READING_DUP_TREE_KEY but its not failing. How do I fail the request for invalid json request which has duplicate fields.?
`#Override
public void configure() throws Exception {
restConfiguration().bindingMode(RestBindingMode.json).component("servlet")
.jsonDataFormat(JsonParser.Feature.STRICT_DUPLICATE_DETECTION.name())
.dataFormatProperty("prettyPrint", "true")
.dataFormatProperty("json.in.enableFeatures",
"FAIL_ON_NUMBERS_FOR_ENUMS,USE_BIG_DECIMAL_FOR_FLOATS,FAIL_ON_READING_DUP_TREE_KEY"
+ ",FAIL_ON_UNKNOWN_PROPERTIES,ADJUST_DATES_TO_CONTEXT_TIME_ZONE,"
+ JsonParser.Feature.STRICT_DUPLICATE_DETECTION.name())
.dataFormatProperty("json.in.disableFeatures", "FAIL_ON_EMPTY_BEANS").enableCORS(true)`
This may come from the fact that Camel is using XStream as default JSON library (see here).
Did you already try to force the use of Jackson library ?

How do I insert an ISODate into mongoDB via Postman?

How do I insert an ISODate into MongoDB via Postman? I have looked around but examples/queries on this subject tend to be just for ways of getting various string formats.
I have an in-house API set up on my localhost so I am querying the database (MongoDB) with Postman. Queries & entries are written in JSON so I would do this like so usually:
{ "adminModifiedId": 1, "dateCreated" : { "$date": "1557510188"}, .., .. }
or
{ "adminModifiedId": 1, "dateCreated" : new Date(), .., .. }
Of course dates within MongoDB are in this format: ISODate("2019-01-21T17:41:27.107Z") but I just can't find the right solution here. I know that Postman does allow to set global & environmental variables within the Pre-request Script section but it does seem strange that a platform so established would not have a way to format or convert into an ISODate type.
Edited in response to #Danny_Dainton
Postman body as JSON request
Pre-request Script
Erorr response
I'll leave this for a few days to see if anyone can suggest a pre-established answer (that doesn't require a pre-request script). Otherwise I will mark mine correct as the only answer that has worked for me so far.
You could use either of these methods in a Pre-request Script.
Using the moment lib, like this:
var moment = require('moment')
pm.globals.set("ISO_Date", moment())
More info about that here: https://stackoverflow.com/a/47823708/6028443
Or
Just use basic JS code like this to create the same timestamp:
pm.globals.set("ISO_Date", (new Date()).toISOString())
Once the variable is created, add {{ISO_Date}} reference to your request body.
For whatever reason other solutions didn't work for me but may for others. This one resolved my issue though so may be of use.
Pre-request Script
let t = Date.now()
pm.environment.set('t', t);
Body (sample)
{ "adminModifiedId": 1, "dateCreated" : { "$date": {{t}}}, .., .. }

AWS Api Gateway Documentation - cant create schema

Today i got into swagger and swagger-ui to create the documentation of our API.
We are using AWS API Gateway with a Lambda function, since AWS is comming with an in-built option for documentation we are going with it.
Sadly, I am pretty limited with this option or I am doing it wrong.
As an example
responses:
'200':
description: 200 response
schema:
$ref: '#/definitions/Empty'
I canĀ“t create an alternative schema, nor im able to edit the existing /Empty schema.
Is there a solution for my problem?
For example
... to not use an schema and just write the whole response in there?
... to show me how to create an alternative schema?
EDIT
For me it seems like an AWS problem, not my swagger file in generall. If someone reads over this i added more informations.
It doesnt matter if i use "create Documetation Part" --> Type = Response (Body) or i go to Ressources --> Method which i want to set the Response (Body) --> Method Response and set the Respone Body to an Modell.
My Modell looks like this
{
{
"$schema": "http://json-schema.org/draft-04/schema#",
"description" : "Example Promotion",
"title" : "Promotion",
"type" : "object",
"properties" : {
"Status" : { "type" : "string"}
}
}
}
It gives me no error, but if i go to "Publish Documentation" it seems to no put the Respone (Body) i set into the swagger.json on the Method Response part, nor on the Defenitions at the end of the file and set the schema path right.
I found it easier to not use $ref when I was starting out. After you have the knack how to write requests or response definitions, you can easily transition to referencing schemas using $ref.
What comes after schema statement? That depends on what you expect to be returned -- text, an array, a JSON object, or an array of JSON objects, etc. Typically it's the later two. So here is an example of each.
schema:
type: object
description: This is a JSON object
properties:
fullName:
type: string
age:
type: number
which defines: { fullName: "Jane Smith", age: 30 }
schema:
type: array
description: This is an array of JSON object
items:
type: object
properties:
carMake:
type: string
carModel:
type: string
which defines: [{ carMake: "Ford", carModel: "Mustang" } ... ]
Clone github's swagger-ui onto your computer and run it as a local server. Or you have free use of the SwaggerHub if you don't mind the API definition to be public (or, after a trial period, pay for your APIs to be private).
The specification has changed over the years, so its important to know whether you are dealing with swagger v2 or openapi v3. www.swagger.io has a good multi-page tutorial. And you can find several public API examples at the SwaggerHub website. I do not work for Smartbear, the originators of both the original swagger spec and swaggerhub tooling, but I've found them to be very helpful in the past. Some of their staff monitor this website and answer questions.
Good luck!

API call in Response and another response types

How can I call API url (Fulfillment or Webhook as named by API.AI) from Watson conversation API Response.
I don't need to enter the full list of expected responses from the Response section.
I need to call an API with the understood JSON object to handle the response from the backend (fetch DB for example) and return the expected JSON to the user (requester).
Any advice?!
Not sure I understand your question, you cannot program within the Conversation service tooling to call out to other services etc, as part of a response or message.
These are the types of actions that the middleware or service layer part of your application should handle. Not to be recommended but you could program the client element of your application to process additional api calls.
You will find both on this forum, and in the IBM docs examples of the use of whats called "action" json elements that can be added to your conversation response payload. Thus along with the response output text ( or in place ) you add an "action" json element to the output and context json object that includes instructions to your middleware or client part of your application. i.e.
"output" : { "Text" : "Hi there" },
"action" " { "api_url" : "http://bluemixservice.ibm.com", "Task" : "insert", "data" : "User asked for an alarm at 5pm" },
"context" : { "conversation_id" : "asdada" }
Hope this helps.

RESTful from Google Apps Script

I invoke a RESTful webserice via a method GET url with paramters from google apps script successfully using the following:
UrlFetchApp.fetch(url);
But when I switch the method to use POST, the result returned tells that no parameter was sent:
UrlFetchApp.fetch(url, options);
I also tried to use Google Chrome's (Advanced) Rest Client, and the payload parameters are not sent there as well.
What am I missing?
Below is the Google Chrome's (Advanced) Rest Client interface.
You mention in your comments that you are converting the payload you send to JSON.
First, are you certain the remote service is expecting a JSON payload, rather than form encoded data?
If the service expects form encoded data, don't JSON.stringify your payload:
var data = {"x1": "1", "x2": "2"};
var options = {method : "post", payload : data};
If the service does expect a JSON payload, you need to set the content type:
var data = {"x1": "1", "x2": "2"};
data = JSON.stringify(data);
var options = {method : "post", payload : data, contentType:"application/json"};
Otherwise the default content type of 'application/x-www-form-urlencoded' is used.
See the description on "contentType" under "Advanced Parameters": https://developers.google.com/apps-script/reference/url-fetch/url-fetch-app