Should "/users" and "/users/" point to the same (RESTful) resource? - http

They do in this and probably any other website, but I'm not sure I understand why.
A popular analogy compares RESTful resources to files in the file system and filename users wouldn't point to the same object as filename users/ static web pages and in a static website users would point to users.html and users/ - to a different file - users/index.html.

Short answer: they may only identify the same resource if one redirects to the other.
URI's identify resources, but they do so differently depending on the response status code to a GET request in HTTP. If one returns a 3xx to the other, then the two URI's identify the same resource. If the two resources each return a 2xx code, then the URI's identify different resources. They may return the same response in reply to a GET request, but they are not therefore the same resource. The two resources may even map to the same handler to produce their reply, but they are not therefore the same resource. To quote Roy Fielding:
The resource is not the storage object. The resource is not a
mechanism that the server uses to handle the storage object. The
resource is a conceptual mapping -- the server receives the identifier
(which identifies the mapping) and applies it to its current mapping
implementation (usually a combination of collection-specific deep tree
traversal and/or hash tables) to find the currently responsible
handler implementation and the handler implementation then selects the
appropriate action+response based on the request content.
So, should /users and /users/ return the same response? No. If one does not redirect to the other, then they should return different responses. However, this is not itself a constraint of REST. It is a constraint, however, which makes networked systems more scalable: information that is duplicated in multiple resources can get out of sync (especially in the presence of caches, which are a constraint of REST) and lead to race conditions. See Pat Helland's Apostate's Opinion for a complete discussion.
Finally, clients may break when attempting to resolve references relative to the given URI. The URI spec makes it clear that resolving the relative reference Jerry/age against /users/ results in /users/Jerry/age, while resolving it against /users (no trailing slash) results in /Jerry/age. It's amazing how much client code has been written to detect and correct the latter to behave like the former (and not always successfully).
For any collection (which /users/ often is), I find it best to always emit /users/ in URI's, redirect /users to /users/ every time, and serve the final response from the /users/ resource: this keeps entities from getting out of sync and makes relative resolution a snap on any client.

filename users wouldn't point to the same object as filename users/.
That is not true. In most filesystems, you cannot have a file named users and a directory named users in the same parent directory.
cd users and cd users/ have the same result.

There are some nuances on this, while "users" represent one resource while "users/" should represent a set of resources, or operations on all resources "users"... But there does not seem to exist a "standard" for this issue.
There is another discussion on this, take a look here: https://softwareengineering.stackexchange.com/questions/186959/trailing-slash-in-restful-api

Technically they are not the same. But a request for /users will probably cause a redirect to /users/ which makes them semantically equal.
In terms of JAX-RS #Path, they can both be used for the same path.

Related

How to implement discovery of the [corresponding] _file path_ for a [stored] resource, using HTTP?

We have an HTTP application which needs to communicate to the user the path of the resource the user has requested or modified, as people otherwise struggle to later locate the corresponding file when accessing the backing storage through other means (e.g. remote shell to a host where said storage is mounted with known path prefix).
For example, the user agent would send a HTTP request with the following first line:
PUT /project/human-genome/files/meetings/owners-101190/report.txt
...meaning someone requested creation and storage of the resource at the corresponding URL.
Now, you can say one should be trivially able to infer the file path from the URL, and normally I'd be inclined to design URLs with such assumption in mind, but in our case we don't generally have such relationship that the client can automatically infer the path like that, and this relationship (the "mapping", if you will) can change, so what we have is this additional level of indirection, you can say, that makes assumptions like this inapplicable.
In practice, it means the above URL can't be assumed to correspond to a file named report.txt stored in some folder with path like /project/human-genome/files/meetings/owners-....
Instead, we want to have the client be able to negotiate obtaining the path value related to the resource.
I have thought of the following solutions:
Return the path with a response header for at least HEAD requests; the header is probably custom, something like Resource-Path; If utilizing a custom header, there needs to be specification that tells for what responses related to the resource, the header is returned? Is it only returned for HEAD requests? Doesn't that fly in the face of HTTP basically describing HEAD request as GET-without-response-body, meaning that the corresponding GET response also shall include the response header? That is an overhead and a waste if the client didn't need the metadata. And if metadata is returned, how much of it, and what kind of representation of it? This option intuitively seems to be inferior to the second alternative:
Allocate a dedicated URL for metadata about the resource including the "stored path", e.g. /metadata/project/human-genome/files/meetings/owners-101190/report.txt, with optional suffix like :path or /path and/or utilizing URL query variables -- to specify what metadata to return; whether it's some /metadata/ URL pathname prefix, or some /metadata or :metadata suffix, this seems more "idiomatic", but I am not entirely convinced of the wisdom in representing also metadata as server resource -- what would the semantics for requests like PUT .../metadata, be?
On top of the choices above, I am half-suspecting this is a solved problem and there is some RFC I should read that solves this very problem -- surely metadata about resources that doesn't fall into categories for which HTTP uses response headers (which normally pertain to the response, not the resource), is something a lot of applications and application servers routinely have to manage?
Is there a truly idiomatic approach here that can be the correct answer to this problem?

REST: Proper way to handle partially-restricted resources

I’m redesigning the REST API for a small SaaS I built. Currently there’s a route /entries that doesn’t require any authentication. However, if the client authenticates with sufficient privileges, the server will send additional information (ex: the account associated with each entry).
The main problem I see with this is that a client attempting to request protected data with insufficient privileges will still receive a 200 response, but without the expected data, instead of a 401 Unauthorized.
The alternatives I came up with are:
Split the endpoint into two endpoints, ex /entries and /admin/entries. The problem with this approach is that there are now two different endpoints for essentially the same resource. However, it has the advantage of being easy to document with OpenAPI. (Additionally, it allows for the addition of a /entries/:id/account endpoint.)
Accept a query parameter ?admin=true. This option is harder to document. On the other hand, it avoids having multiple URIs for a single entry.
Is there a standard way to structure something like this?
Related question: Different RESTful representations of the same resource
The alternatives I came up with are
Note that, as far as HTTP/REST are concerned, your two alternatives are the same: in both cases you are introducing a new resource.
The fact that in one case you use path segments to distinguish the two identifiers and in the other case you are using the query part doesn't change the fact that you have two resources.
Having two resources with the same information is fine - imagine two web pages built from the same information.
It's a trade off - the HTTP application isn't going to know that these resources have common information, and so won't know that invalidating one cached resource should also invalidate the other. So just like with web pages, you can get into situations where the representations that you have in your cache aren't consistent with each other.
Sometimes, the right answer is to use links between different resources - have "the" information in one place, and everywhere else has links that allow you to find that one place. Again, trade-offs.
HTTP isn't an infinitely flexible application protocol. It's really good at transferring documents over a network, especially at "web scale".
There have been attempts at using Link headers to trigger invalidation of other cached resources, but as far as I have been able to tell, none of them has made it past the proposal stage.

Why would you use PUT instead of PATCH?

From what I understand, PUT requests send the whole object while PATCH requests just send the diff, which is used to update the object in the database.
Why would you do a PUT over a PATCH? PATCH seems much lighter. I don't see any upsides to PUT (I'm sure they exist, I just don't know what they are).
A better way of looking at is that PUT replaces a resource, whilst PATCH is for providing an instruction to change a resource.
Replacing a resource is always a safe and idempotent operation as it has no dependency on the existing state of the resource. Meanwhile a request to change a resource may be dependent on the state of that resource and can therefore have other effects.
The HTTP PATCH verb is defined in RFC 5789, which states:
The difference between the PUT and PATCH requests is reflected in the
way the server processes the enclosed entity to modify the resource
identified by the Request-URI. In a PUT request, the enclosed entity
is considered to be a modified version of the resource stored on the
origin server, and the client is requesting that the stored version
be replaced. With PATCH, however, the enclosed entity contains a set
of instructions describing how a resource currently residing on the
origin server should be modified to produce a new version. The PATCH
method affects the resource identified by the Request-URI, and it
also MAY have side effects on other resources; i.e., new resources
may be created, or existing ones modified, by the application of a
PATCH.
It goes on to say:
PATCH is neither safe nor idempotent
You might want to create the resource, or there might not be an applicable PATCH format available (think binary files).
with using POST as only option to create resources
only having JSON resources (RFC 7396)
making your PATCH endpoint implementation idempotent
Is there still a need to provide a PUT endpoint in an API?
Maybe I don't want to take the diff and deduce where I should save it so that everything makes sense. Maybe I just want to work with full resources instead of messing around with little parts of them. >> you can use PATCH for full update as well, no?
A considerable part of the HTTP standard is outdated, so it is not surprising that PATCH can completely replace PUT.
In RESTful API, people often mistakenly regard PUT as "update the entire resource", but in fact the semantics of PUT is "replace the resource". Unfortunately, there is a sad design in the HTTP: PUT is defined to create new resources when they don't exist, so PUT is sometimes used as an idempotent alternative to POST.
PATCH is an imitation of PUT to a certain extent, so it also incorporates part of the responsibilities of POST. However, if you only want to have an action of "modify the existing resource", you only need to use PATCH (PATCH is not idempotent, another sad design of HTTP).
Those who study REST and HTTP standard methods in depth will eventually find that a simple RPC interface can better implement all the actions you need.

What is the usefulness of PUT and DELETE HTTP request methods?

I've never used PUT or DELETE HTTP Request methods. My tendency is to use GET when the state of the system (my application or website) may not be affected (like a product listing) and to use POST when it is affected (like placing an order). Aren't those two always sufficient, or am I missing something?
DELETE is for deleting the request resource:
The DELETE method requests that the origin server delete the resource identified by the Request-URI. This method MAY be overridden by human intervention (or other means) on the origin server. The client cannot be guaranteed that the operation has been carried out, even if the status code returned from the origin server indicates that the action has been completed successfully …
PUT is for putting or updating a resource on the server:
The PUT method requests that the enclosed entity be stored under the supplied Request-URI. If the Request-URI refers to an already existing resource, the enclosed entity SHOULD be considered as a modified version of the one residing on the origin server. If the Request-URI does not point to an existing resource, and that URI is capable of being defined as a new resource by the requesting user agent, the origin server can create the resource with that URI …
For the full specification visit:
http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html
Since current browsers unfortunately do not support any other verbs than POST and GET in HTML forms, you usually cannot utilize HTTP to it's full extent with them (you can still hijack their submission via JavaScript though). The absence of support for these methods in HTML forms led to URIs containing verbs, like for instance
POST http://example.com/order/1/delete
or even worse
POST http://example.com/deleteOrder/id/1
effectively tunneling CRUD semantics over HTTP. But verbs were never meant to be part of the URI. Instead HTTP already provides the mechanism and semantics to CRUD a Resource (e.g. an order) through the HTTP methods. HTTP is a protocol and not just some data tunneling service.
So to delete a Resource on the webserver, you'd call
DELETE http://example.com/order/1
and to update it you'd call
PUT http://example.com/order/1
and provide the updated Resource Representation in the PUT body for the webserver to apply then.
So, if you are building some sort of client for a REST API, you will likely make it send PUT and DELETE requests. This could be a client built inside a browser, e.g. sending requests via JavaScript or it could be some tool running on a server, etc.
For some more details visit:
http://martinfowler.com/articles/richardsonMaturityModel.html
Are the PUT, DELETE, HEAD, etc methods available in most web browsers?
Why are there no PUT and DELETE methods in HTML forms
Should PUT and DELETE be used in forms?
http://amundsen.com/examples/put-delete-forms/
http://www.quora.com/HTTP/Why-are-PUT-and-DELETE-no-longer-supported-in-HTML5-forms
Using HTTP Request verb such as GET, POST, DELETE, PUT etc... enables you to build RESTful web applications. Read about it here: http://en.wikipedia.org/wiki/Representational_state_transfer
The easiest way to see benefits from this is to look at this example.
Every MVC framework has a Router/Dispatcher that maps URL-s to actionControllers.
So URL like this: /blog/article/1 would invoke blogController::articleAction($id);
Now this Router is only aware of the URL or /blog/article/1/
But if that Router would be aware of whole HTTP Request object instead of just URL, he could have access HTTP Request verb (GET, POST, PUT, DELETE...), and many other useful stuff about current HTTP Request.
That would enable you to configure application so it can accept the same URL and map it to different actionControllers depending on the HTTP Request verb.
For example:
if you want to retrive article 1 you can do this:
GET /blog/article/1 HTTP/1.1
but if you want to delete article 1 you will do this:
DELETE /blog/article/1 HTTP/1.1
Notice that both HTTP Requests have the same URI, /blog/article/1, the only difference is the HTTP Request verb. And based on that verb your router can call different actionController. This enables you to build neat URL-s.
Read this two articles, they might help you:
Symfony 2 - HTTP Fundamentals
Symfony 2 - Routing
These articles are about Symfony 2 framework, but they can help you to figure out how does HTTP Requests and Responses work.
Hope this helps!
Although I take the risk of not being popular I say they are not useful nowadays.
I think they were well intended and useful in the past when for example DELETE told the server to delete the resource found at supplied URL and PUT (with its sibling PATCH) told the server to do update in an idempotent manner.
Things evolved and URLs became virtual (see url rewriting for example) making resources lose their initial meaning of real folder/subforder/file and so, CRUD action verbs covered by HTTP protocol methods (GET, POST, PUT/PATCH, DELETE) lost track.
Let's take an example:
/api/entity/list/{id} vs GET /api/entity/{id}
/api/entity/add/{id} vs POST /api/entity
/api/entity/edit/{id} vs PUT /api/entity/{id}
/api/entity/delete/{id} vs DELETE /api/entity/{id}
On the left side is not written the HTTP method, essentially it doesn't matter (POST and GET are enough) and on the right side appropriate HTTP methods are used.
Right side looks elegant, clean and professional. Imagine now you have to maintain a code that's been using the elegant API and you have to search where deletion call is done. You'll search for "api/entity" and among results you'll have to see which one is doing DELETE. Or even worse, you have a junior programmer which by mistake switched PUT with DELETE and as URL is the same shit happened.
In my opinion putting the action verb in the URL has advantages over using the appropriate HTTP method for that action even if it's not so elegant. If you want to see where delete call is made you just have to search for "api/entity/delete" and you'll find it straight away.
Building an API without the whole HTTP array of methods makes it easier to be consumed and maintained afterwards
Safe Methods : Get Resource/No modification in resource
Idempotent : No change in resource status if requested many times
Unsafe Methods : Create or Update Resource/Modification in resource
Non-Idempotent : Change in resource status if requested many times
According to your requirement :
1) For safe and idempotent operation (Fetch Resource) use --------- GET METHOD
2) For unsafe and non-idempotent operation (Insert Resource) use--------- POST METHOD
3) For unsafe and idempotent operation (Update Resource) use--------- PUT METHOD
3) For unsafe and idempotent operation (Delete Resource) use--------- DELETE METHOD
See the accepted answer from #Gordon, the key point being simply this:
PUT and DELETE are specific verbs with a meaning, that instruct the server to do something specific and how the instruction should be handled.
OK standards and semantics are great but what real use is DELETE to me if all I want to do is somehow run code to delete something from a database?
So what if we say, "OK but it's easier for me to just do a delete by issuing a GET to my URI that has a path /api/entity/delete/{id} (as suggested in the answer by #Bogdan). OK so let's look at the definition of GET:
The GET method means retrieve whatever information (in the form of an
entity) is identified by the Request-URI
Source - W3C standards - https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html
If you use GET for a DELETE you are clearly misusing the method according to its standard definition.
Alright so let's further say 'OK but that doesn't really matter because it's just more practical for a developer to read a URI somewhere that uses a GET method and reads /api/entity/delete/{id} instead of having a DELETE method that deletes resources having the same signature as a GET method that retrieves, so that the developer understands that's meant for deletion. Let's consider a well structured DELETE method signature (example is for .NET Core 5):
// DELETE: api/TodoItems/5
[HttpDelete("{id}")]
public async Task<IActionResult> DeleteTodoItem(long id)
{
This will not respond to a get request, (so for example, accidental deletion instead of retrieval when making a call to the API is more protected - the developer has to explicitly perform a DELETE request to the API). And we have a very clear, well structured and named API operation that's clear and highly discoverable by a developer or even automated tooling (e.g. a developer can now search specifically for any occurrence of DELETE in code, or for the method name which clearly indicates the DELETE). And what's more, this pattern conforms to a generally accepted standard for a 'RESTFUL' API that should render the API more broadly recognisable and interpretable to developers (and potentially any automated tooling).
OK, that's nice, but what's the real difference in making it a DELETE? Why even use DELETE instead of GET? My operation is deleting something from the database, why should my web server care? OK, let's think about the definition of DELETE:
9.7 DELETE - The DELETE method requests that the origin server delete the resource identified by the Request-URI. This method MAY be
overridden by human intervention (or other means) on the origin
server.
So now, if we're specifying a delete, we have the potential for specific behaviour on the server that potentially allows for reversing a delete action by manual or automatic intervention. In a particular use case, that could be significant.
OK well DELETE works for me then, but why use PUT? For example it's more convenient if I just make an 'upsert' method that uses POST, and update the resource if it exists or create it if it doesn't
I personally typically do this when I"m implementing an API that effects operations against a database, although again there is specific meaning to PUT i.e. that it specifically indicates updating of a resource, while POST indicates creation, so using POST for both creating and updating is counter-standard. My own view is that a REST API is a case when I typically view the practicality of upsert functionality as being more important that strict use of the correct verb for adds versus insert, but I could be missing something here.
Use of PUT outside of a REST api could be more significant for practical purposes, for example if we're performing an update operation where the server can potentially clear any cacheing by understanding that the resource has been updated (which is more significant if our resource is a whole document, for example). There may be some practical advantages I haven't considered when PUT is utilised inside a restful API for an update operation.
The standard definition for POST states that a POST success response SHOULD be 201 (created), and not just the generic '200 OK', so that we're able to correctly interpret that resource creation is explicitly successful. That response isn't appropriate for an update operation but there's no 'MUST' specified in the standard for the response code. It's certainly common for developers to use POST for an upsert and return 200 (OK) on success, whether it's a creation or an update.
The standard for PUT is more strict, and specifies that any unexpected creation of a resource when attempting an update MUST be indicated via a 201 response code. This can occur if no existing resource exists at the specified URI. The standard explains that if we use PUT we get clearer feedback on whether the result of our attempted update operation is what we expected.
From the W3C standard:
[if a put] does not point to an existing resource, and that URI is
capable of being defined as a new resource by the requesting user
agent, the origin server can create the resource with that URI. If a
new resource is created, the origin server MUST inform the user agent
via the 201 (Created) response. If an existing resource is modified,
either the 200 (OK) or 204 (No Content) response codes SHOULD be sent
to indicate successful completion of the request.
PUT
The PUT method is used whenever you need to change the resource. The resource, which is already a part of resource collection. One thing to note here is that PUT method modifies the entire resource whereas PATCH method is used to modify the necessary part of the resource or data.
DELETE
As the name says, the DELETE request method is used to delete the specified resource. It requests that the origin server delete the resource identified by the Request-URL.
I hope this simple definitions help.

Which HTTP methods match up to which CRUD methods?

In RESTful style programming, we should use HTTP methods as our building blocks. I'm a little confused though which methods match up to the classic CRUD methods. GET/Read and DELETE/Delete are obvious enough.
However, what is the difference between PUT/POST? Do they match one to one with Create and Update?
Create = PUT with a new URI
POST to a base URI returning a newly created URI
Read = GET
Update = PUT with an existing URI
Delete = DELETE
PUT can map to both Create and Update depending on the existence of the URI used with the PUT.
POST maps to Create.
Correction: POST can also map to Update although it's typically used for Create. POST can also be a partial update so we don't need the proposed PATCH method.
The whole key is whether you're doing an idempotent change or not. That is, if taking action on the message twice will result in “the same” thing being there as if it was only done once, you've got an idempotent change and it should be mapped to PUT. If not, it maps to POST. If you never permit the client to synthesize URLs, PUT is pretty close to Update and POST can handle Create just fine, but that's most certainly not the only way to do it; if the client knows that it wants to create /foo/abc and knows what content to put there, it works just fine as a PUT.
The canonical description of a POST is when you're committing to purchasing something: that's an action which nobody wants to repeat without knowing it. By contrast, setting the dispatch address for the order beforehand can be done with PUT just fine: it doesn't matter if you are told to send to 6 Anywhere Dr, Nowhereville once, twice or a hundred times: it's still the same address. Does that mean that it's an update? Could be… It all depends on how you want to write the back-end. (Note that the results might not be identical: you could report back to the user when they last did a PUT as part of the representation of the resource, which would ensure that repeated PUTs do not cause an identical result, but the result would still be “the same” in a functional sense.)
I Was searching for the same answer, here is what IBM say.
IBM Link
POST Creates a new resource.
GET Retrieves a resource.
PUT Updates an existing resource.
DELETE Deletes a resource.
Right now (2016) the latest HTTP verbs are GET, POST, PATCH, PUT and DELETE
Overview
HTTP GET - SELECT/Request
HTTP PUT - UPDATE
HTTP POST - INSERT/Create
HTTP PATCH - When PUTting a complete resource representation is cumbersome and utilizes more bandwidth, e.g.: when you have to update partially a column
HTTP DELETE - DELETE
Hope this helps!
If you are interested on designing REST APIs this is an ansewome reading to have! website online version github repository
There's a great youtube video talk by stormpath with actually explains this, the URL should skip to the correct part of the video:
stormpath youtube video
Also it's worth watch it's over an hour of talking but very intersting if your thinking of investing time in building a REST api.
It depends on the concrete situation.. but in general:
PUT = update or change a concrete resource with a concrete URI of the resource.
POST = create a new resource under the source of the given URI.
I.e.
Edit a blog post:
PUT:
/blog/entry/1
Create a new one:
POST:
/blog/entry
PUT may create a new resource in some circumstances where the URI of the new ressource is clear before the request.
POST can be used to implement several other use cases, too, which are not covered by the others (GET, PUT, DELETE, HEAD, OPTIONS)
The general understanding for CRUD systems is GET = request, POST = create, Put = update, DELETE = delete
The building blocks of REST are mainly the resources (and URI) and the hypermedia. In this context, GET is the way to get a representation of the resource (which can indeed be mapped to a SELECT in CRUD terms).
However, you shouldn't necessarily expect a one-to-one mapping between CRUD operations and HTTP verbs.
The main difference between PUT and POST is about their idempotent property. POST is also more commonly used for partial updates, as PUT generally implies sending a full new representation of the resource.
I'd suggest reading this:
http://roy.gbiv.com/untangled/2009/it-is-okay-to-use-post
http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven
The HTTP specification is also a useful reference:
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. If the server desires
that the request be applied to a
different URI,
Generally speaking, this is the pattern I use:
HTTP GET - SELECT/Request
HTTP PUT - UPDATE
HTTP POST - INSERT/Create
HTTP DELETE - DELETE
The Symfony project tries to keep its HTTP methods joined up with CRUD methods, and their list associates them as follows:
GET Retrieve the resource from the server
POST Create a resource on the server
PUT Update the resource on the server
DELETE Delete the resource from the server
It's worth noting that, as they say on that page, "In reality, many modern browsers don't support the PUT and DELETE methods."
From what I remember, Symfony "fakes" PUT and DELETE for those browsers that don't support them when generating its forms, in order to try to be as close to using the theoretically-correct HTTP method even when a browser doesn't support it.

Resources