GET & POST passing parameters - rest

I've read many question on stackoverflow about passing parameters with GET and POST methods, but none of them satisfied my curiosity.
I use GETs to retrieve data passing parameters as path/query params and use POSTs to save data passing parameters as request body with Content-Type: application/json and sometimes request body + path/query params (depending on other APIs I've created for simmetry purpose only).
My question is when to use Content-Type: application/x-www-form-urlencoded. Say I want to call a POST without a request body of Content-Type: application/json but with params, do I have to use the application/x-www-form-urlencoded Content-Type or I can use path/query params as best practice?
What's the difference between sending data as path/query params and key-value params with Content-Type: application/x-www-form-urlencoded? Does the data size have to do with it?

What's the difference between sending data as path/query params and key-value params with Content-Type: application/x-www-form-urlencoded?
Consider this example
PUT /example?a=b&c=d
Content-Type: application/x-www-form-urlencoded
d=e&f=g
What's happening here? This is a request that the server replace its current representation of the resource identified by
/example?a=b&c=d
With the payload. In other words, after successful processing, we would expect
GET /example?a=b&c=d
to produce a response like
200 OK
Content-Type: application/x-www-form-urlencoded
d=e&f=g
POST /example?a=b&c=d
Content-Type: application/x-www-form-urlencoded
d=e&f=g
For POST, it's the same idea, except that instead of "replace the current representation", POST stands in for "process the payload according to the specific semantics of /example?a=b&c=d".
GETs to retrieve data passing parameters as path/query params
It might help to reframe your thinking here. We use GET to retrieve the current representation of a resource. We aren't passing parameters, we're passing a document (resource) identifier.
The fact that the origin server's implementation is going to parse that identifier is an implementation detail.
A URI Template is a compact sequence of characters for describing a
range of Uniform Resource Identifiers through variable expansion.
-- RFC 6570
I want to call a POST without a request body of Content-Type: application/json but with params, do I have to use the application/x-www-form-urlencoded Content-Type or I can use path/query params as best practice?
POST /example?a=b&c=d
Content-Type: application/json
{"d":"e","f":"g"}
Is a perfectly normal HTTP request.
Content-Type describes the payload only - it has nothing at all to do with the target URI, and how information might be encoded within it.

Related

Akka-HTTP: how to know if Content-type header was explicitly set in received response

Is the a way in akka-http to know if 'Content-type' header was explicitly set in HttpResponse that we received?
From sniffed Http dump I see, that there was no 'Content-Type' header, but
httpResponse.header[`Content-Type`].get.contentType.mediaType.toString()
and
httpResponse.entity.getContentType().mediaType.toString
stil return application/octet-stream.
This is default Content type not only for Akka-HTTP, but perhaps for other frameworks like Play too. Akka-http and other HTTP based technologies need to know how to parse content internally, based on this header. application/octet-stream means that it considers request body as just byte-stream.
Rule of thumb: if it is possible - try to specify Content-type.

what is valid data for http post request for request content type application/json

I have one rest api.
which accept application/json request for an http post method .
all post parameters are optional.
The question is what is considered valid request in that case.
No value
{}
The second option represent json with no value.
Which is best practice for api?

What should be Content-Type if response is encrypted json?

What should be Content-Type header, for a REST web service response which contains encrypted JSON in body?
Here encrypted JSON does not mean JOSE or JWE. It is symmetric encryption done by interceptor, using any algorithm. Is it okay if I keep application/json ?
According to RFC1847 you should use multipart/encrypted. You then have to provide information about the encrypted and unencrypted data formats in the two required body parts.
Example from the RFC:
Content-Type: multipart/encrypted; protocol="TYPE/STYPE";
boundary="Encrypted Boundary"
--Encrypted Boundary
Content-Type: TYPE/STYPE
CONTROL INFORMATION for protocol "TYPE/STYPE" would be here
--Encrypted Boundary
Content-Type: application/octet-stream
Content-Type: application/json

Postman Chrome: What is the difference between form-data, x-www-form-urlencoded and raw

I am using the Postman Chrome extension for testing a web service.
There are three options available for data input.
I guess the raw is for sending JSON.
What is the difference between the other two, form-data and x-www-form-urlencoded?
These are different Form content types defined by W3C.
If you want to send simple text/ ASCII data, then x-www-form-urlencoded will work. This is the default.
But if you have to send non-ASCII text or large binary data, the form-data is for that.
You can use Raw if you want to send plain text or JSON or any other kind of string. Like the name suggests, Postman sends your raw string data as it is without modifications. The type of data that you are sending can be set by using the content-type header from the drop down.
Binary can be used when you want to attach non-textual data to the request, e.g. a video/audio file, images, or any other binary data file.
Refer to this link for further reading:
Forms in HTML documents
This explains better:
Postman docs
Request body
While constructing requests, you would be dealing with the request body editor a lot. Postman lets you send almost any kind of HTTP request (If you can't send something, let us know!). The body editor is divided into 4 areas and has different controls depending on the body type.
form-data
multipart/form-data is the default encoding a web form uses to transfer data. This simulates filling a form on a website, and submitting it. The form-data editor lets you set key/value pairs (using the key-value editor) for your data. You can attach files to a key as well. Do note that due to restrictions of the HTML5 spec, files are not stored in history or collections. You would have to select the file again at the time of sending a request.
urlencoded
This encoding is the same as the one used in URL parameters. You just need to enter key/value pairs and Postman will encode the keys and values properly. Note that you can not upload files through this encoding mode. There might be some confusion between form-data and urlencoded so make sure to check with your API first.
raw
A raw request can contain anything. Postman doesn't touch the string entered in the raw editor except replacing environment variables. Whatever you put in the text area gets sent with the request. The raw editor lets you set the formatting type along with the correct header that you should send with the raw body. You can set the Content-Type header manually as well. Normally, you would be sending XML or JSON data here.
binary
binary data allows you to send things which you can not enter in Postman. For example, image, audio or video files. You can send text files as well. As mentioned earlier in the form-data section, you would have to reattach a file if you are loading a request through the history or the collection.
UPDATE
As pointed out by VKK, the WHATWG spec say urlencoded is the default encoding type for forms.
The invalid value default for these attributes is the application/x-www-form-urlencoded state. The missing value default for the enctype attribute is also the application/x-www-form-urlencoded state.
Here are some supplemental examples to see the raw text that Postman passes in the request. You can see this by opening the Postman console:
form-data
Header
content-type: multipart/form-data; boundary=--------------------------590299136414163472038474
Body
key1=value1key2=value2
x-www-form-urlencoded
Header
Content-Type: application/x-www-form-urlencoded
Body
key1=value1&key2=value2
Raw text/plain
Header
Content-Type: text/plain
Body
This is some text.
Raw json
Header
Content-Type: application/json
Body
{"key1":"value1","key2":"value2"}
multipart/form-data
Note. Please consult RFC2388 for additional information about file uploads, including backwards compatibility issues, the relationship between "multipart/form-data" and other content types, performance issues, etc.
Please consult the appendix for information about security issues for forms.
The content type "application/x-www-form-urlencoded" is inefficient for sending large quantities of binary data or text containing non-ASCII characters. The content type "multipart/form-data" should be used for submitting forms that contain files, non-ASCII data, and binary data.
The content type "multipart/form-data" follows the rules of all multipart MIME data streams as outlined in RFC2045. The definition of "multipart/form-data" is available at the [IANA] registry.
A "multipart/form-data" message contains a series of parts, each representing a successful control. The parts are sent to the processing agent in the same order the corresponding controls appear in the document stream. Part boundaries should not occur in any of the data; how this is done lies outside the scope of this specification.
As with all multipart MIME types, each part has an optional "Content-Type" header that defaults to "text/plain". User agents should supply the "Content-Type" header, accompanied by a "charset" parameter.
application/x-www-form-urlencoded
This is the default content type. Forms submitted with this content type must be encoded as follows:
Control names and values are escaped. Space characters are replaced by +', and then reserved characters are escaped as described in [RFC1738], section 2.2: Non-alphanumeric characters are replaced by %HH', a percent sign and two hexadecimal digits representing the ASCII code of the character. Line breaks are represented as "CR LF" pairs (i.e., %0D%0A'). The control names/values are listed in the order they appear in the document. The name is separated from the value by =' and name/value pairs are separated from each other by `&'.
application/x-www-form-urlencoded the body of the HTTP message sent to the server is essentially one giant query string -- name/value pairs are separated by the ampersand (&), and names are separated from values by the equals symbol (=). An example of this would be:
MyVariableOne=ValueOne&MyVariableTwo=ValueTwo
The content type "application/x-www-form-urlencoded" is inefficient for sending large quantities of binary data or text containing non-ASCII characters. The content type "multipart/form-data" should be used for submitting forms that contain files, non-ASCII data, and binary data.
let's take everything easy, it's all about how a http request is made:
1- x-www-form-urlencoded
http request:
GET /getParam1 HTTP/1.1
User-Agent: PostmanRuntime/7.28.4
Accept: */*
Postman-Token: a14f1286-52ae-4871-919d-887b0e273052
Host: localhost:12345
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 55
postParam1Key=postParam1Val&postParam2Key=postParam2Val
2- raw
http request:
GET /getParam1 HTTP/1.1
Content-Type: text/plain
User-Agent: PostmanRuntime/7.28.4
Accept: */*
Postman-Token: e3f7514b-3f87-4354-bcb1-cee67c306fef
Host: localhost:12345
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Content-Length: 73
{
postParam1Key: postParam1Val,
postParam2Key: postParam2Val
}
3- form-data
http request:
GET /getParam1 HTTP/1.1
User-Agent: PostmanRuntime/7.28.4
Accept: */*
Postman-Token: 8e2ce54b-d697-4179-b599-99e20271df90
Host: localhost:12345
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Content-Type: multipart/form-data; boundary=--------------------------140760168634293019785817
Content-Length: 181
----------------------------140760168634293019785817
Content-Disposition: form-data; name="postParam1Key"
postParam1Val
----------------------------140760168634293019785817--

HTTP Headers to use to specify CSV delimiter and options

I would like my REST service to accept CSV files in addition to JSON and XML.
I would accept an HTTP PUT request such as:
PUT /myservice/user
Content-Type: text/csv; charset=utf-8
"tomas";"1980-01-01"
"george";"1981-02-02"
I would like to be able to accept different delimiters and other format options for my CSV file. Preferably without using the querystring, which doesn't seem to be the proper tool for that. I understand I could just invent my own headers such as:
PUT /myservice/user
Content-Type: text/csv; charset=utf-8
CSV-Delimiter: ,
CSV-Options: merge-duplicates, no-header-row
Or maybe I could invent my own parameters to Content-Type if that is allowed (after all it is a part of the content-type just like the charset used):
PUT /myservice/user
Content-Type: text/csv; charset=utf-8; delimiter=,; options=no-header-row
What would be the proper way to handle this? Are there any HTTP-headers conventionally used for this?
For "no-header-row" a parameter already exists: [header="present"|"absent"].
As for adding new parameters to the content-type header:
New parameters SHOULD NOT be defined as a way to introduce new
functionality in types registered in the standards tree, although new
parameters MAY be added to convey additional information that does
not otherwise change existing functionality. An example of this
would be a "revision" parameter to indicate a revision level of an
external specification such as JPEG. Similar behavior is encouraged
for media types registered in the vendor or personal trees but is not
required.