RESTful API POST call request without a body - rest

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

Related

Location vs Content-Location on post requests

I am confused about the header Location and Content-Location.
Content-Location
Regarding Content-Location I found this statement in the spec. (Emphasis mine)
For a state-changing request like PUT (Section 4.3.4) or POST (Section 4.3.3), it implies that the server's response contains the new representation of that resource, thereby distinguishing it from representations that might only report about the action (e.g., "It worked!"). This allows authoring applications to update their local copies without the need for a subsequent GET request.
However, in the mdn docs is an example that shows the opposite behaviour. (Emphasis mine)
The site returns a generic success message confirming the post was published. The server specifies where the new post is with Content-Location:
HTTP/1.1 201 Created
Content-Type: text/plain; charset=utf-8
Content-Location: /my-first-blog-post
✅ Success!
These two statements seem to contradict each other.
Now, I am unsure if I should use Content-Location for the case of not including the real entity in the response.
Location
The spec has a sentence about the Location header.
For 201 (Created) responses, the Location value refers to the primary resource created by the request.
And mdn is saying the same.
In cases of resource creation, it indicates the URL to the newly created resource.
I am confused which one to pick for a post response that does not include the entity.
I am guessing the Location header would be most appropriate for a generic post request where the entity can be viewed later. For example, posting a user and viewing it.
What about a POST response with a 202 code? For example, when posting a task to a queue where later only the status of the task can be viewed. So it isn't a real entity like a user. I.e. an email was dispatched to X clients based on the posted task, now I want to communicate where the status (PENDING, FAILURE or SUCCESS) can be viewed.
You are correct, and MDN is wrong about the first example. This example:
HTTP/1.1 201 Created
Content-Type: text/plain; charset=utf-8
Content-Location: /my-first-blog-post
✅ Success!
Suggests that the contents of /my-first-blog-post is ✅ Success!, due to the Content-Location header.
Given that you don't want to return the new resource's body, you should keep Location and omit Content-Location.
And if you have time: report the issue to the MDN maintainers.
What about a POST response with a 202 code? For example, when posting a task to a queue where later only the status of the task can be viewed. So it isn't a real entity like a user. I.e. an email was dispatched to X clients based on the posted task, now I want to communicate where the status (PENDING, FAILURE or SUCCESS) can be viewed.
I would suggest a Link header.

Should I use POST or PUT for login request, and why?

I know the difference between them generally but for the login form, I'm not sure why the POST method is recommended.
Broadly: because PUT has more specific semantics in HTTP, and those semantics don't match the typical login form case very well.
POST serves many useful purposes in HTTP, including the general purpose of “this action isn’t worth standardizing.” -- Fielding 2009
POST /foo HTTP/1.1
Content-Type: text/plain
username=foo&password=this_is_a_secret
That request can mean almost anything; it might or might not be idmpotent, it might or might not be "effectively read only". It's very non-committal. From RFC 7321:
The POST method requests that the target resource process the representation enclosed in the request according to the resource's own specific semantics.
In contrast, PUT means something much more specific
A successful PUT of a given representation would suggest that a subsequent GET on that same target resource will result in an equivalent representation being sent in a 200 (OK) response.
Thus
PUT /foo HTTP/1.1
Content-Type: text/plain
username=foo&password=this_is_a_secret
Suggests that when someone later does
GET /foo HTTP/1.1
You expect a response like
HTTP/1.1 200 OK
Content-Type: text/plain
username=foo&password=this_is_a_secret
In other words, the semantics of PUT are very close to those of "save" or "upsert". "Make your copy of this resource look like the payload of this request."
Remember, general purpose HTTP components don't necessarily know that these message are about "login"; they only see messages with semantics of the transfer of documents over a network domain. That's means that when they see your "login" PUT request, they are going to assume that the semantics are exactly the same as a PUT to any other resource on the web, and act accordingly.

Post parameter in path or in body

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

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

What are the best/common RESTful url verbs and actions?

I'm trying to find some info on the best and most common RESTful url actions.
for example, what url do you use for displaying the details of an item, for editing the item, updating, etc.
/question/show/<whatever>
/question/edit/<whatever>
/question/update/<whatever> (this is the post back url)
/question/list (lists the questions)
hmm. thanks to anyone helping out :)
Use URLs to specify your objects, not your actions:
Note what you first mentioned is not RESTful:
/questions/show/<whatever>
Instead, you should use your URLs to specify your objects:
/questions/<question>
Then you perform one of the below operations on that resource.
GET:
Used to obtain a resource, query a list of resources, and also to query read-only information on a resource.
To obtain a question resource:
GET /questions/<question> HTTP/1.1
Host: whateverblahblah.com
To list all question resources:
GET /questions HTTP/1.1
Host: whateverblahblah.com
POST:
Used to create a resource.
Note that the following is an error:
POST /questions/<new_question> HTTP/1.1
Host: whateverblahblah.com
If the URL is not yet created, you should not be using POST to create it while specifying the name. This should result in a resource not found error because does not exist yet. You should PUT the resource on the server first. You could argue that by creating a new question, you are also updating the /questions resource as it would now return one more question in its list of questions.
You should do something like this to create a resource using POST:
POST /questions HTTP/1.1
Host: whateverblahblah.com
Note that in this case the resource name is not specified, the new objects URL path would be returned to you.
DELETE:
Used to delete the resource.
DELETE /questions/<question> HTTP/1.1
Host: whateverblahblah.com
PUT:
Used to create a resource, or overwrite it, while you specify the resources URL.
For a new resource:
PUT /questions/<new_question> HTTP/1.1
Host: whateverblahblah.com
To overwrite an existing resource:
PUT /questions/<existing_question> HTTP/1.1
Host: whateverblahblah.com
...Yes, they are the same. PUT is often described as the 'edit' method, as by replacing the entire resource with a slightly altered version, you have edited what clients will GET when they next do.
Using REST in HTML forms:
The HTML5 spec defines GET and POST for the form element.
The method content attribute is an enumerated attribute with the following keywords and states:
The keyword GET, mapping to the state GET, indicating the HTTP GET method.
The keyword POST, mapping to the state POST, indicating the HTTP POST method.
Technically, the HTTP specification does not limit you to only those methods. You are technically free to add any methods you want, in practice though, this is not a good idea. The idea is that everyone knows that you use GET to read the data, so it will confuse matters if you decide to instead use READ. That said...
PATCH:
This is a method that was defined in a formal RFC. It is designed to used for when you wish to send just a partial modification to a resource, it would be used much like PUT:
PATCH /questions/<new_question> HTTP/1.1
Host: whateverblahblah.com
The difference is PUT has to send the entire resource, no matter how big it is compared to what's actually changed, whilst PATCH you can send just the changes.
Assuming /questions/10 is a valid question then the method is used to interact with it.
POST to add to it
PUT to create or replace it
GET to view/query it
and DELETE to well.. delete it.
The url doesn't change.
I'm going to go out on a limb and guess that you what you mean is what are standard controllers for MVC when you say "RESTful" urls, since your examples could be considered non-"RESTful" (see this article).
Since Rails really popularized the URL style you seem to be interested in, I offer below the default controller actions produced by the ScaffoldingGenerator in Ruby on Rails. These should be familiar to anyone using a Rails application.
The scaffolded actions and views are:
index, list, show, new, create, edit,
update, destroy
Typically you would construct this as:
http://application.com/controller/<action>/<id>
Here is a mapping of your current URLs using the REST principle:
/question/show/<whatever>
If you identify the question as a resource, then it should have a unique URL. Using GET to display it (retrieve it) is the common practice. It becomes:
GET /question/<whatever>
/question/edit/<whatever>
Now you want your user to have another view of the same resource that allows him to edit the resource (maybe with form controls).
Two options here, your application is an application (not a website), then you may be better using JavaScript to transform the resource into an editable resource ono the client side.
If this is a website, then you can use the same URL with additional information to specify another view, the common practice seems to be:
GET /question/<whatever>;edit
/question/update/<whatever> (this is the post back url)
This is to change the question, so PUT is the correct method to use:
PUT /question/<whatever>
/question/list (lists the questions)
The list of question is actually the parent resource of a question, so it naturally is:
GET /question
Now you may need some more:
POST /question (create a new question and returns its URL)
DELETE /question/<whatever> (deletes a question if this is relevant)
Tada :)
Your four examples could be:
GET /questions/123
POST (or PUT) /questions/123 q=What+is+the+meaning+of+life
POST (or PUT) /questions/123 q=What+is+the+meaning+of+life
GET /questions
To add a question:
POST /questions q=What+is+the+meaning+of+life
The server would respond:
200 OK (or 201 Created)
Location: /questions/456