Nestjs accepting also application/x-www-form-urlencoded - json

We have a service which is calling our nestjs microservice with header Content-Type: application/x-www-form-urlencoded which seems not to be parsed as expected.
If we start also from a clean nestjs project and put this pice of code in the AppController
#Post()
async store(#Body() request: any) {
console.log('request', request);
}
If we send data to the service with curl in this way:
curl -d '{"abc": 123 }' -H 'Content-Type: application/x-www-form-urlencoded' -X POST http://localhost:3000
At the end our console.log shows as that we don't have a valid json, the whole content of the body is puted in the first parameter of the request json, which is resulting in this
request { '{"abc": 123 }': '' }
As you can see the content is not parsed right to the json, the documentation is not showing a lot of the parser, but googling this should work out of the bax
Can someone help?

Either post
URL encoded data and claim it is URL encoded data or
JSON encoded data and claim it is JSON encoded data
You're posting JSON and claiming it is URL encoded, which doesn't make sense.

Related

How to use a GET curl in postman?

I have this curl example:
curl -i -X GET -H "Content-Type:application/json" https://dev.ga.coach/intervention/:getworse/ -d '{"user_id": "012ab3", "section_id": "6"}'
When I run it through cygwin it's working properly! When I'm trying to import it in postman then it shows it as POST and I get the following response.
<h1>Not Found</h1>
<p>The requested URL /intervention/ was not found on this server.</p>
When I test https://dev.ga.coach/intervention/:getworse/ through web browser, this is what I see:
cURL allows you to include a payload on a GET request but the HTTP specification says:
A payload within a GET request message has no defined semantics;
sending a payload body on a GET request might cause some existing
implementations to reject the request.
When you try to make the same request with Postman, you are experiencing it "rejecting" the request. In this case, the rejection comes in the form of it converting to a POST request instead.
It would be appropriate to include a JSON payload on a POST request, but since it looks like you are trying to GET information you should move the data to the URL instead.
For example:
https://dev.ga.coach/intervention/012ab3/6/:getworse/
This will require you change your server-side code (which you, presumably, can do since you said I'm developing the rest-apis) to read the data from the new location.

REST API - Use the "Accept: application/json" HTTP Header

When I make a request, I get a response in XML, but what I need is JSON. In the doc it is stated in order to get a JSON in return: Use the Accept: application/json HTTP Header.
Where do I find the HTTP Header to put Accept: application/json inside?
My guess is it is not suppose to be inside the URL-request, which looks like:
http://localhost:8080/otp/routers/default/plan?fromPlace=52.5895,13.2836&toPlace=52.5461,13.3588&date=2017/04/04&time=12:00:00
You guessed right, HTTP Headers are not part of the URL.
And when you type a URL in the browser the request will be issued with standard headers. Anyway REST Apis are not meant to be consumed by typing the endpoint in the address bar of a browser.
The most common scenario is that your server consumes a third party REST Api.
To do so your server-side code forges a proper GET (/PUT/POST/DELETE) request pointing to a given endpoint (URL) setting (when needed, like your case) some headers and finally (maybe) sending some data (as typically occurrs in a POST request for example).
The code to forge the request, send it and finally get the response back depends on your server side language.
If you want to test a REST Api you may use curl tool from the command line.
curl makes a request and outputs the response to stdout (unless otherwise instructed).
In your case the test request would be issued like this:
$curl -H "Accept: application/json" 'http://localhost:8080/otp/routers/default/plan?fromPlace=52.5895,13.2836&toPlace=52.5461,13.3588&date=2017/04/04&time=12:00:00'
The H or --header directive sets a header and its value.
Here's a handy site to test out your headers. You can see your browser headers and also use cURL to reflect back whatever headers you send.
For example, you can validate the content negotiation like this.
This Accept header prefers plain text so returns in that format:-
$ curl -H "Accept: application/json;q=0.9,text/plain" http://gethttp.info/Accept
application/json;q=0.9,text/plain
Whereas this one prefers JSON and so returns in that format:-
$ curl -H "Accept: application/json,text/*;q=0.99" http://gethttp.info/Accept
{
"Accept": "application/json,text/*;q=0.99"
}
Basically I use Fiddler or Postman for testing API's.
In fiddler, in request header you need to specify instead of xml, html you need to change it to json.
Eg: Accept: application/json. That should do the job.
Well Curl could be a better option for json representation but in that case it would be difficult to understand the structure of json because its in command line.
if you want to get your json on browser you simply remove all the XML Annotations like -
#XmlRootElement(name="person")
#XmlAccessorType(XmlAccessType.NONE)
#XmlAttribute
#XmlElement
from your model class and than run the same url, you have used for xml representation.
Make sure that you have jacson-databind dependency in your pom.xml
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.4.1</version>
</dependency>

How to return a collection of JSON documents as a JSON array

I have a collection of JSON documents in MarklLogic which I want to return to an API call as a JSON Array.
fn.collection('my-users')
Returns a sequence of JSON docs, I need a valid JSON object, an array. I am doing this in serverside java script, pushing to a new empty array().
No real example documentation to my knowledge, only in XQuery some examples.Google keeps referring to this very high level documentation here
var myArray = [];
for (d of fn.collection('my-users')){
myArray.push(d);
}
myArray
Do I need to loop over each item in the sequence to push to an array or is there a more elegant/quicker solution?
hugo
If you need to return them as a JSON array, you're doing the right thing. There's no more elegant/quicker solution that I know of. But if you're looking for a more optimized / high performance way, try REST extensions which will turn a sequence of documents into a multi-part HTTP response.
Here's an example. Given example.sjs with the contents:
function get(context, params) {
return fn.collection('my-users')
}
exports.GET = get;
Installed like so:
curl --anyauth --user admin:admin -X PUT -i \
-H "Content-type: application/vnd.marklogic-javascript" \
--data-binary #./example.sjs \
http://localhost:8000/LATEST/config/resources/js-example
And the following docs inserted into the my-users collection (I assume you know how to insert these):
myuser.json
{"name":"Sue"}
myuser2.json
{"name":"Mary"}
myuser3.json
{"name":"Jane"}
myuser4.json
{"name":"Joe"}
You can call your rest extension like so:
curl --anyauth --user admin:admin \
http://localhost:8000/LATEST/resources/js-example
And you get the following multi-part http response:
--js-example-get-result
Content-Type: application/json
Content-Length: 14
{"name":"Sue"}
--js-example-get-result
Content-Type: application/json
Content-Length: 15
{"name":"Mary"}
--js-example-get-result
Content-Type: application/json
Content-Length: 15
{"name":"Jane"}
--js-example-get-result
Content-Type: application/json
Content-Length: 14
{"name":"Joe"}
--js-example-get-result--
Use your favorite client-side http library to accept that efficient response as an individual json document for each document.
I should add that there's no need for a REST extension if your requirements are this simple. You could simply use the REST search endpoint:
curl --anyauth --user admin:admin \
-H accept:multipart/mixed \
http://localhost:8000/LATEST/search?collection=my-users
and get a very similar multi-part http response. I only provided the REST extension example since your question was about server-side javascript and I figured you might have additional requirements that require that.
Iterables are from ES6 and are (from what I understand), one of the only things carried over for the initial release of SJS along with sub-sequences.
The reason for these is so that you get the same behaviour as you would get with sequences and sub-sequences in xQuery. (different notation in the two languages, but identical behaviour)
If there were a full implementation of ES6, then the answer for you would be Array.from(iteratable)
However, without that feature, then I think you are using the most efficient way. But be careful that you don't suck your entire database into memory with the pushing from iterator to array.
I am curious of your use-case for needing them in an array actually..
-David
You don't have to loop. The following should help you for your need:
myArray.push(fn.doc(fn.collection('my-users')))

HTTPRequest equivalent to cURL

I have this particular cURL statement that I am trying to figure out the equivalent for it in an HTTP Request.
curl -X POST --upload-file movie-data-2013.json doc-movies-123456789012.us-east-1.cloudsearch.amazonaws.com/2013-01-01/documents/batch --header "Content-Type:application/json"
So far the HTTP Request equivalent I am able to compile is below:
Set oHTTPRequest = Server.CreateObject( "MSXML2.XMLHTTP.3.0" )
oHTTPRequest.Open "POST" _
,"doc-movies-123456789012.us-east-1.cloudsearch.amazonaws.com/2013-01-01/documents/batch" _
False
oHTTPRequest.setRequestHeader "Content-type", "application/json"
oHTTPRequest.Send
For the most part I should be set, except there's one part it's missing, and I'm unsure how it's appended to the request.
There is a part in cURL that says: --upload-file movie-data-2013.json
Not sure how it applies in an HTTP Request. Does anyone how this applies?
I'd recommend trying .Net's built-in HttpWebRequest class over MSXML. There is an example of uploading text data on MSDN using the GetRequestStream method. You should be able to easily modify the sample to instead read the data from a file, for example using File.ReadAllBytes, and then write the returned data to the request stream.

POST: sending a post request in a url itself

I have been given a url .. www.abc.com/details and asked to send my name and phone number on this url using POST. They have told me to set the content-type as application/json and the body as valid JSON with the following keys:
name: name of the user
phone number: phone number of the user
Now i have no clue how to send this request! Will it be something like:
http://www.abc.com/details?method=post&name=john&phonenumber=445566
or do i have to use java to send the same?
Please help
Based on what you provided, it is pretty simple for what you need to do and you even have a number of ways to go about doing it. You'll need something that'll let you post a body with your request. Almost any programming language can do this as well as command line tools like cURL.
Once you have your tool decided, you'll need to create your JSON body and submit it to the server.
An example using cURL would be (all in one line, minus the \ at the end of the first line):
curl -v -H "Content-Type: application/json" -X POST \
-d '{"name":"your name","phonenumber":"111-111"}' http://www.example.com/details
The above command will create a request that should look like the following:
POST /details HTTP/1.1
Host: www.example.com
Content-Type: application/json
Content-Length: 44
{"name":"your name","phonenumber":"111-111"}
You can post data to a url with JavaScript & Jquery something like that:
$.post("www.abc.com/details", {
json_string: JSON.stringify({name:"John", phone number:"+410000000"})
});
It is not possible to send POST parameters in the URL in a straightforward manner. POST request in itself means sending information in the body.
I found a fairly simple way to do this. Use Postman by Google, which allows you to specify the content-type (a header field) as application/json and then provide name-value pairs as parameters.
You can find clear directions at [2020-09-04: broken link - see comment] http://docs.brightcove.com/en/video-cloud/player-management/guides/postman.html
Just use your URL in the place of theirs.
You can use postman.
Where select Post as method.
and In Request Body send JSON Object.
In windows this command does not work for me..I have tried the following command and it works..using this command I created session in couchdb sync gate way for the specific user...
curl -v -H "Content-Type: application/json" -X POST -d "{ \"name\": \"abc\",\"password\": \"abc123\" }" http://localhost:4984/todo/_session
If you are sending a request through url from browser(like consuming webservice) without using html pages by default it will be GET because GET has/needs no body. if you want to make url as POST you need html/jsp pages and you have to mention in form tag as "method=post" beacause post will have body and data will be transferred in that body for security reasons. So you need a medium (like html page) to make a POST request. You cannot make an URL as POST manually unless you specify it as POST through some medium. For example in URL (http://example.com/details?name=john&phonenumber=445566)you have attached data(name, phone number) so server will identify it as a GET data because server is receiving data is through URL but not inside a request body
In Java you can use GET which shows requested data on URL.But POST method cannot , because POST has body but GET donot have body.