Post parameter in path or in body - rest

I am creating Rest API but I am confused in URL structure. I have to send just one parameter to server in my Post request. should I send it through path variable or in request body? what are the best practices?
Example Current URL:
api/v1/users/{id}/name/{name}
name is the variable I want to send to server for to change state
Thanks

URL usually identifies resource you want to update.
So the data should go inside in request body
To update user name you may send this to server:
POST api/v1/users/{id} HTTP/1.1
Content-Type: application/x-www-form-urlencoded
name=string

Related

RESTful API POST call request without a body

I want to create a new call in my API that links two already created resources together. Therefore, I don't need to pass any json entities in the post body I just need the resources IDs which I am passing in the URL. Is that a wrong practice? so basically my request now is only a simple path {cid}/projects/{projectID}/subcontractors/{subcontractorID}
and in the post call method I extract the resources IDs from the path and I link them. The response is only either pass or fail {"success":true}. Is that a wrong practice? Is there a better way of doing this?
How you will design your API is really up to you. From a technical point of view, a POST request with an empty payload is completely fine.
However, assuming that you intend to add a contractor to a project, I think it could be better expressed with a payload:
POST /projects/1/contractors HTTP/1.1
Host: api.example.org
Content-Type: application/json
{ "contractorId": 100 }
This approach is specially useful if you need to manage more information for that contractor in that project. If above request succeeds, the response would contain the 201 status code along with a Location header that identifies the newly created resource.
Since you are linking the already existing resources - projects and contractors. I wouldn't prefer the POST method.
Instead I would use the PATCH method (as I am only editing the partial content of the existing resources)
Either the payload or the request URL methods are acceptable.
Request URL:
PATCH /projects/3/contractors/23 HTTP/1.1
HOST example.com/api
Payload
PATCH /projects/3/contractors HTTP/1.1
HOST example.com/api
Content-Type: application/json
{ "contractor_id": 23 }
A successful response is indicated by 200 status code which may contain the payload, or
204 response

RESTful WebServices: PUT, POST and DELETE - where to put the parameters

I would have a question concerning the properties which will be transfered from client to server.
HTTP GET is clear: Parameters are transmitted in URL and not in body!
HTTP PUT: where to transmit parameters - in URL or Body?
HTTP POST: where to transmit parameters - in URL or Body?
HTTP DELETE: where to transmit parameters - in URL or Body?
Thanks a ot for answering the question!
The id of the entity in PUT (update) and DELETE request should be in the url. The entity to update in PUT requests should be in the body. The entity to create in POST requests should also be in the body.
Optional parameters should be sent in query string. Other contextual information on the entity (Composite id) should be in the url.

Including created resource in HTTP POST response?

RFC7231 says a server should respond to a resource-creating POST request with status 201 and a Location header to the new resource. In some situations it could be convenient for the server to include a representation of the created resource in its response, but in other cases this would be a waste of bandwidth.
Might this be a good place for content negotiation within the post request? If so, what request headers should be sent to indicate that the client would like the resource returned in addition to the Location header?
I would suggest using the "Prefer" header:
Request:
PUT /xxx
Prefer: return=representation
Response:
201 Created
{ ... created resource representation ... }
See https://www.rfc-editor.org/rfc/rfc7240

HTTP PUT Request limit

I am designing a RESTful API when I noticed something strange.
When I make a POST request for creating a new record, the form data is sent in request payload.
But when I make a PUT request to update a record, it appends form data in the URL, very similar to GET request.
Now a URL has certain length limit. So what would happen if PUT request has larger data than this limit.
Will the PUT request fail?
Is it unsafe to use PUT instead of POST to update a record having large form data?
EDIT:
I am using NodeJS server. I am using restangular(angular framework) to build my PUT request.
Use customPUT to send the form data in payload.
baseObj.customPUT(newObj).then(function(xyz){})
Have a look at these threads
Can HTTP PUT request have application/x-www-form-urlencoded as the Content-Type?
PHP multipart form data PUT request?
application/x-www-form-urlencoded or multipart/form-data?
Sounds like you can basically set a Content-type: multipart/form-data header and be golden. Basically comes down to configuration of the request with restangular and support thereof on the NodeJS server.

How send application/x-www-form-urlencoded params to a RestServer with JMeter?

I developed a rest server, and I put it to run in localhost, and I'm trying to perform tests with JMeter, sending requests posts and gets (depends of called method).
I already send to Rest server and got result with JMeter in simple post requests, get requests, sending files with post, and sending a Json with post.
But I don't know how to send a Form-UrlEncoded object to server. My Rest server consumes application/x-www-form-urlencoded, and I need to send 3 String parameters.
There's some way to set the MimeType for every parameter and perform the test ?
I'm using Jmeter 2.7
[Update]
I solved this by disabling the option:
use multipart/form-data for post
And enabling:
redirect automatically
Instead of:
follow redirect
The parameters I put normally in the table "Send parameters with the Request" with each respective names.
For sending form parameters as application/x-www-form-urlencoded, add a header parameter Content-Type with value application/x-www-form-urlencoded.
The following steps is aplicable for Jmeter 2.3.4
Add a HTTP Header Manager under your http Request.
Add new parameter to HTTP Header Manager with name Content-Type and value application/x-www-form-urlencoded.
Uncheck "Use multipart/form-data for HTTP POST" of HTTP request.
Uncheck "Encode?" of each request parameter(not necessary).
kept "Content Encode:" text box of HTTP request as empty.
This won't work for PUT request.
For put request add parameters as path parameter and set Content-Type header then Jmeter will do by itself.
Here's the solution for HTTP POST with x-www-form-urlencoded testing with jmeter. You just folllow like these.
Go to Thread Group -> Add listener -> Views Result in table, View result Tree. To see the process of responding.
Have you tried to save your test using BadBoy or JMeter Proxy to see what your application actually sends?
To see what happens under the hood you can also use FireBug if you're using FireFox or Ctrl+Shift+i if you're on Chrome.
IllegalCharsetNameException will go immediately only after you will add the required content-type in HTTP Header Manager for HTTP request .
Hope this helps.
followed exact steps mentioned i still see an exception thrown
Response code: Non HTTP response code: java.nio.charset.IllegalCharsetNameException
Response message: Non HTTP response message: application/x-www-form-urlencoded
java.nio.charset.IllegalCharsetNameException: application/x-www-form-urlencoded
at java.nio.charset.Charset.checkName(Charset.java:315)
at java.nio.charset.Charset.lookup2(Charset.java:484)
at java.nio.charset.Charset.lookup(Charset.java:464)
at java.nio.charset.Charset.forName(Charset.java:528)
at org.apache.http.entity.ContentType.create(ContentType.java:210)
at org.apache.http.entity.StringEntity.<init>(StringEntity.java:116)
at org.apache.jmeter.protocol.http.sampler.HTTPHC4Impl.sendPostData(HTTPHC4Impl.java:1340)
at org.apache.jmeter.protocol.http.sampler.HTTPHC4Impl.handleMethod(HTTPHC4Impl.java:592)
at org.apache.jmeter.protocol.http.sampler.HTTPHC4Impl.sample(HTTPHC4Impl.java:409)
at org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy.sample(HTTPSamplerProxy.java:74)
at org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase.sample(HTTPSamplerBase.java:1166)
at org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase.sample(HTTPSamplerBase.java:1155)
at org.apache.jmeter.threads.JMeterThread.executeSamplePackage(JMeterThread.java:475)
at org.apache.jmeter.threads.JMeterThread.processSampler(JMeterThread.java:418)
at org.apache.jmeter.threads.JMeterThread.run(JMeterThread.java:249)
at java.lang.Thread.run(Thread.java:745)