I know that clients and servers most commonly communicate through HTTP forms. I know enough about the GET methods, but the little I do know about POST methods is that they're used to submit data to the server. However, when the server receives a POST method and processes the data, it sends a status code like 200 etc., but how does the server send more data? I know there's a body but what does it look like? Does it have parameters and values just like a POST method?
The format of the body is specified in the Content-Type header.
A commonly used Content-Type for form data submission is application/x-www-form-urlencoded. The body for such a request should look something like this:
key1=value1&key2=value+with+spaces
Where key1 and key2 are input names and value1 and value+with+spaces are the corresponding values. Note that key names and values are url encoded
Another common type is application/json, which means the request body should be interpreted as JSON data, for example:
{
"key": "value",
"another_key": "value"
}
So it's just data, and the Content-Type header tells the server how to interpret it.
Edit: A good way to see what's going on is create a form with method="post", and analyze the request with your browser developer tools when the form is submitted.
Related
I need to reuse value which is generated for my previous request.
For example, at first request, I make a POST to the URL /api/products/{UUID} and get HTTP response with code 201 (Created) with an empty body.
And at second request I want to get that product by request GET /api/products/{UUID}, where UUID should be from the first request.
So, the question is how to store that UUID between requests and reuse it?
You can use the Request Sent Dynamic values https://paw.cloud/extensions?extension_type=dynamic_value&q=request+send these will get the value used last time you sent a requst for a given request.
In your case you will want to combine the URLSentValue with the RegExMatch (https://paw.cloud/extensions/RegExMatch) to first get the url as it was last sent for a request and then extract the UUID from the url.
e.g
REQUEST A)
REQUEST B)
The problem is in your first requests answer. Just dont return "[...] an empty body."
If you are talking about a REST design, you will return the UUID in the first request and the client will use it in his second call: GET /api/products/{UUID}
The basic idea behind REST is, that the server doesn't store any informations about previous requests and is "stateless".
I would also adjust your first query. In general the server should generate the UUID and return it (maybe you have reasons to break that, then please excuse me). Your server has (at least sometimes) a better random generator and you can avoid conflicts. So you would usually design it like this:
CLIENT: POST /api/products/ -> Server returns: 201 {product_id: UUID(1234...)}
Client: GET /api/products/{UUID} -> Server returns: 200 {product_detail1: ..., product_detail2: ...}
If your client "loses" the informations and you want him to be later able to get his products, you would usually implement an API endpoint like this:
Client: GET /api/products/ -> Server returns: 200 [{id:UUID(1234...), title:...}, {id:UUID(5678...),, title:...}]
Given something like this, presuming the {UUID} is your replacement "variable":
It is probably so simple it escaped you. All you need to do is create a text file, say UUID.txt:
(with sample data say "12345678U910" as text in the file)
Then all you need to do is replace the {UUID} in the URL with a dynamic token for a file. Delete the {UUID} portion, then right click in the URL line where it was and select
Add Dynamic Value -> File -> File Content :
You will get a drag-n-drop reception widget:
Either press the "Choose File..." or drop the file into the receiver widget:
Don't worry that the dynamic variable token (blue thing in URL) doesn't change yet... Then click elsewhere to let the drop receiver go away and you will have exactly what you want, a variable you can use across URLs or anywhere else for that matter (header fields, form fields, body, etc):
Paw is a great tool that goes asymptotic to awesome when you explore the dynamic value capability. The most powerful yet I have found is the regular expression parsing that can parse raw reply HTML and capture anything you want for the next request... For example, if you UUID came from some user input and was ingested into the server, then returned in a html reply, you could capture that from the reply HTML and re-inject it to the URL, or any field or even add it to the cookies using the Dynamic Value capabilities of Paw.
#chickahoona's answer touches on the more normal way of doing it, with the first request posting to an endpoint without a UUID and the server returning it. With that in place then you can use the RegExpMatch extension to extract the value from the servers's response and use it in subsequent requests.
Alternately, if you must generate the UUID on the client side, then again the RegExpMatch extension can help, simply choose the create request's url for the source and provide a regexp that will strip the UUID off the end of it, such as /([^/]+)$.
A third option I'll throw out to you, put the UUID in an environment variable and just have all of your requests reference it from there.
The documentation for Response Parsed Body Dynamic Value doesn't make much sense to me. I r-clicked on the JSON response element as described, in this case, userid
{"authorization":"T98J_J8QcH5lC83TOKZxaWB","userid":"T98J_J8QcH5lC83TOKZxaWB","lastLogin":"2014-12-15 15:17"}
but did not receive the menu option to Copy as Dynamic Value as stated. I got the standard text editor context menu. So, either I'm misreading the doc, or it's incorrect. Here's what I want to do: Take the dynamic value for the userid and pass it as part of the URL (not a parameter) to subsequent calls. Is this possible with Paw?
Here's how you can do it manually.
Right click on the field where you want to reuse the value. In the contextual menu, pick Response > Response Parsed Body
Pick the request you want to extract the response from. Enter the JSON key path. Make it explicitly JSON format (Automatic uses the Content-Type, which may not match in some cases).
The Copy as Dynamic Value may not work if your response is not interpreted as JSON, maybe the server is not setting a Content-Type: application/json header?
Why are POST params put in the request body, instead of in the URL like GET?
I understand that GET requests are meant to read data, while POST requests are meant to alter data (i.e. if a POST request is sent more than once, dicey things can happen). But why the difference in URL vs body? Putting the text in the body doesn't seem significantly more secure or private.
It's not about security or privacy, but about data.
You can send anything you want in the body, while the URI (specifically the query string) is quite restrictive in content and length.
The HTTP request has two parts: The header and the body
The header contains all information which describes the request and the requested object (path, request parameters, options, etc) and the requested operation (GET, POST, PUT, DELETE, etc).
The body contains all data which are sent by the client to process. This data could be some kind of binary data (an image for example), or some kind of form data (POST data).
This is the HTTP request specification: http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html
Here are the definitions of the HTTP request methods:
http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html
I'm writting a RESTful api, and at I'm thinking about the process of a user creating a key. I have the following possibilities:
GET request to /new/<keyname> - although it's very easy I think I won't use this, because I heard GET is for retrieving and/or listing information;
POST request to /<keyname> - This seemed to me easy and simple enough, but does not pass any data in the request body. Can I do it this way ? Is this weird ?
POST request to /keys passing in the request body "keyname=SomeKey" - Is this the correct way ?
I looked at this API from joyent and in all their PUT and POST requests they pass some data in the request body. Is this expected ? Is it really wrong not to require a request body in a PUT and POST request ?
I asked this question on the Http-WG. This was the most precise answer I got http://lists.w3.org/Archives/Public/ietf-http-wg/2010JulSep/0276.html
In summary, POST does not require a body. I would expect the same justification can be applied to PUT.
RFC2616 is the base RFC for HTTP 1.1
In the most general form, an HTTP message is this (note the optional body):
generic-message = start-line
*(message-header CRLF)
CRLF
[ message-body ]
start-line = Request-Line | Status-Line
Reading further gives this:
9.5 POST
The POST method is used to request that the origin server accept the
entity enclosed in the request as a new subordinate of the resource
identified by the Request-URI in the Request-Line. ...
and
9.6 PUT
The PUT method requests that the enclosed entity be stored under the
supplied Request-URI. ...
The fundamental difference between the POST and PUT requests is
reflected in the different meaning of the Request-URI. The URI in a
POST request identifies the resource that will handle the enclosed
entity. That resource might be a data-accepting process, a gateway to
some other protocol, or a separate entity that accepts annotations.
In contrast, the URI in a PUT request identifies the entity enclosed
with the request -- the user agent knows what URI is intended and the
server MUST NOT attempt to apply the request to some other resource.
Both POST and PUT include the phrase entity enclosed in the request.
Based on my reading, I believe that a body is desired (a non-normative description, I know) for both POST and PUT.
In the context of REST, POST is create and PUT is update. I can imagine creating an empty object (perhaps a placeholder for future information), but I don't imagine much use of an empty update.
It is not required. You can send a POST/PUT request without a body and instead use query string parameters. But be careful if your parameters contain characters that are not HTTP valid you will have to encode them.
For example if you need to POST 'hello world' to and end point you would have to make it look like this: http://api.com?param=hello%20world
Probably the best way is your third option: POST to /keys with keyname=SomeKey.
Here's why: You may wish to add another function to your API, for example create_new_user. It would then be difficult to tell the difference between a user trying to POST a key called create_new_user and a user trying to use the create_new_user function.
You are correct in saying that you should not be using GET to do this operation as the GET operation "SHOULD NOT have the significance of taking an action
other than retrieval." (RFC 2616).
To answer your question in one line. Yes it is expected to have Body/Content in body, but it is not required(Mandatory).
According to okHttp3 (an HTTP library for android): the following methods need a body: POST, PUT, PATCH, PROPPATCH (WebDAV) and REPORT (source). It even crashes if you try to do a request with the given methods without a body.
I am working on an app where we have to pass specific web api parameters to a web app using HTTP POST.
eg:
apimethod name
parameter1 value
parameter2 value
So do I use a string or URLEncodedPostData to send that data?
It would be good if u help me with a code eg.
I am using something like this but it doesnt post the data to the server.
Though the response code is ok/200 and I also get get a parsed html response when i read the httpresponse input stream. But the code doesnt post anything. So unable to get the expected response.
_postData.append("method", "session.getToken");
_postData.append( "developerKey", "value");
_postData.append( "clientID", "value");
_httpConnection = (HttpConnection) Connector.open(URL, Connector.READ_WRITE);
String encodedData = _postData.toString();
_httpConnection.setRequestMethod(HttpConnection.POST);
_httpConnection.setRequestProperty("User-Agent", "BlackBerry/3.2.1");
_httpConnection.setRequestProperty("Content-Language", "en-US");
_httpConnection.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
_httpConnection.setRequestProperty("Content-Length",(new Integer(encodedData.length())).toString());
os = _httpConnection.openOutputStream();
os.write(requeststring.getBytes());`
The code you posted above looks correct - although you'll want to do a few more things (maybe you did this already but didn't include it in your code):
Close the outputstream once you've written all the bytes to it
Call getResponseCode() on the connection so that it actually sends the request
POSTed parameters are usually sent in the response BODY, which means URL-encoding them is inappropriate. Quote from the HTTP/1.1 protocol:
Note: The "multipart/form-data" type has been specifically defined
for carrying form data suitable for processing via the POST
request method, as described in RFC 1867 [15].
The post method allows you to use pretty arbitrary message bodies — so it is whatever format the server wants.