REST Response Codes - rest

When implementing a RESTful API, we should deliver the user proper responses on actions.
The architecture of REST API basing on proper building of the link and sending it with proper verb allows user to ask the API any request about any data. What response code should I provide to the user, when he will ask for method that is not implemented for the data he is asking for?
Example:
API is allowing the user to add articles via postAction but not allowing to delete articles at all. What response should I provide to the user when he will send REST DELETE request to my API? 404?

If it's a user permission issue, 403 seems most appropriate. (Forbidden - you're not allowed to do this but someone else might be able to)
If no-one is allowed to perform a DELETE but it's an otherwise valid URI, 405. (Method not allowed)
If it's an access to a non-existent resource, but DELETEs are supported against such resources, then 404 is appropriate. (Not found)
If it's more than one of these scenarios (i.e. the user isn't allowed to DELETE, and the URI they've provided is for a resource that doesn't actually exist) then you need to decide which piece of information is more important. I'd probably pick 404.

You need to respond with response code 405 Method Not Allowed.
List of status codes: Wikipedia

There are basically four methods that are used in RESTfull services. GET, POST, PUT and DELETE.
You are probably adding article using POST service.
When a REST api called using different method other than the expecting one then API automatically returns
HTTP status code 405 (Method not allowed)
If you are allowing this API to using DELETE method as well and then any one can call using DELETE method as well. If you want to disallow user to delete the particular then you may return 403 (forbidden) response code.

Related

What should be REST response for GET call with identifiers as the query parameter if user does not have access to some of the requested resources?

I am designing a REST API, where the user can place a GET call and fetch a list of items.
One of the query parameters that this API is allowing is also ids, a comma-separated list of identifiers that should be fetched.
This is an ability to filter items based on the known ids of resources.
GET /entities?ids=1,2,3
Now, there is also an authorization framework in this mix that provides an answer of what resources the user actually has access to.
So, say from the list of requested ids: 1,2,3 the user has access only to 1 and 3.
They are not allowed to access a resource with id 2.
What should be the REST response in this case?
Should I ignore the fact the user is asking for the forbidden resource and return 200 with the body containing items with ids 1 and 3?
Or, maybe, return 403 in this case... Opinions?
This request should fail
The client is explicitly requesting a specific resource that it doesn't have access to. That should not be part of the normal flow of your application, and I'd say it warrants an outright rejection.
The client may need to process the returned data, so a successful response that doesn't include the requested data should not be allowed to happen. If you do it, your client needs to write more code to account for this outcome, raising the likelihood of bugs and breaking trust with the client. Just return an error instead. Your client needs to handle these in any case.
My choice would be a 403 response with a message that informs the client why the request failed and includes steps to correct the issue.

What is the best way to implement checking whether a username is already registered on the client side, if I want to keep my API RESTful?

As the title suggests, I am looking to have the client be able to check whether a username or email is already registered before the user submits the registration form. I had considered using an API endpoint that would return true or false for a given username, but this seems more RPC than RESTful. Is it bad practice to have such an endpoint if the rest of my API is RESTful? If so, what would a RESTful approach to this situation look like?
A key concept in REST is that anything that can be named can be a resource; this includes procedures. If you want to have an endpoint that accepts a username in the request body and returns true/false that's perfectly fine.
Alternatively, you can (or may already) treat a user as a resource. Take the GitHub API as an example: you can fetch a user by sending a GET request to https://api.github.com/users/{username}. If the user exists, and therefore the username is taken, you'll get back 200 OK. If the user does not exist you'll get 404 Not Found.
If you want to check if a username has been taken you can just issue a request for that username and then check the response. If you choose this approach HEAD is the more appropriate method. HEAD is essentially the same as GET except that the response body is empty. Since you don't need the body to determine if the user exists you can save a tiny bit of bandwidth with HEAD over GET.
You could do a POST /registrations and return a 400 with validation errors array and just have client side logic filter that array for invalid username. In other words, no reason you can't hit the endpoint multiple times. This should help decouple your UX from your API.

How to handle false negative responses from integrating system

I'm looking to get some discussion regarding how handle the following scenario with integrated apis.
You call the 3rd party API to create a resource
The API returns a 500 Exception (however, it still creates the resource in their system, but we do not create the resource since the request return an error code)
Normally, the API would return a 200 OK and an identifier for the resource.
Then the user retries to create the resource
The API returns a 400 Exception Resource because it already exists
How would you gracefully handle this? (keep in mind I have to influence on the API developers to fix this)
Incase if you can’t make the developers fix the issue in the point-2, you can very well try the following for the point-4.
If the result of processing a POST would be equivalent to a representation of an existing resource, an origin server MAY redirect the user agent to that resource by sending a 303 (See Other) response with the existing resource's identifier in the Location field.
Refer the last paragraph under POST

How should "weak" resources be handled in a RESTful website?

In RESTful websites, each resource should be identified by an URI. But how should I handle what are called "weak entities" in relational databases, aka, ressources that only make sense when related to another resource? Should these have specific URIs pointing to them too?
To give an example: Say I have a website for showing events going on in a city. Each event can have comments posted by users.
An event is a resource, with corresponding URI (/events/:id).
But should each comment have an URI, too? Like /events/:eventid/comments/:commentid ? Comments only make sense when they're associated with the corresponding event, so having a page just to represent one message seems weird/unnecessary. I only want the comments to appear on the page of the event.
I guess the /events/:eventid/comments/:commentid URI could be used for a DELETE request, but what should it return to a GET request?
An event is a resource, with corresponding URI (/events/:id).
But should each comment have an URI, too? Like /events/:eventid/comments/:commentid ?
If comment is a resource, it must have an identifier, but it doesn't mean that you have to support all operations for such resource. The server can return a response with the 405 status code if a method is not supported by the target resource:
6.5.5. 405 Method Not Allowed
The 405 (Method Not Allowed) status code indicates that the method received in the request-line is known by the origin server but not supported by the target resource. [...]
I guess the /events/:eventid/comments/:commentid URI could be used for a DELETE request, but what should it return to a GET request?
Return a representation of the comment with the given identifier.
In RESTful websites, each resource should be identified by an URI. But how should I handle what are called "weak entities" in relational databases, aka, ressources that only make sense when related to another resource? Should these have specific URIs pointing to them too?
It depends. An important thing to recognize is that resources and entities are not one to one. You are allowed to have many resources (web pages) that include information from the same entity.
Jim Webber described the distinction this way
The web is not your domain, it's a document management system. All the HTTP verbs apply to the document management domain. URIs do NOT map onto domain objects - that violates encapsulation.
Domain Driven Design for Restful Systems
I guess the /events/:eventid/comments/:commentid URI could be used for a DELETE request, but what should it return to a GET request?
As noted by Cassio, 405 Method Not Allowed is the correct status code to use if the client erroneously sends a request with an unsupported method. OPTIONS is the appropriate mechanism for informing a client of which methods are currently supported by a resource.
You could also have it respond by redirecting the client to the /events/:eventId resource; it might even make sense to take advantage of URI Fragment support, and redirect the client to /events/:eventid#:commentid - allowing the client to use its own fragment discovery to identify the specific comment within the representation of the event.
Or, if there are useful integrations that you want to support, you could simply have this resource return a representation that exposes the integrations.
It really depends on how the client wants to work with the domain. Would an app want to get a list of all the comments for an event? Are users allowed to update their commments? Or are they anonymous comments?
If you plan to only ever use the same page to display the backend information of events and comments, then you prolly don't need a separate comments api. If you want to open the dataset to app vendors (perhaps you might want to develop an app in future) a comments api would be handy. i.e. get all comments for an event.

RESTful API design: Validity of username

I am designing a RESTful API which should return the validity of a username for registration. The invalid cases include:
duplicate username
too short or too long
invalid characters
My current design is:
GET /valid_username/{username}
returns 204 for valid username
returns 404 for invalid username with {err: 'DUPLICATE_USERNAME'}
Is this the preferred way in RESTful API?
Is this the preferred way in RESTful API?
I don't think so.
The guiding star for designing a REST API is a single question: How would you implement this as a web site?
As an integration protocol, when the client submits the username, you either want to advance them to the next form, or you send them back to the "previous" form with a bunch of error messages.
Technically, you could use 204 to do that in the happy path, with a Link in the meta data that the client could follow to go from the success page to the next. But it's a lot more likely that you would just send a representation of the next page at once; so 200 would be your most likely play.
For the unhappy path, instead of sending a representation of the next page, you'd probably send a representation of the current page with the data pre-filled in and the errors highlighted.
So key point: the human being is looking at the rendered representation, not at the meta-data in the headers. The browser is the audience for the metadata. The browser doesn't care anything about the semantics of the message, it just wants to know things like "can I cache this response?"
The most obvious choice of status codes for this case is: 200. Semantically, the representation of the integration resource change from one that would allow you to proceed (username Bob was available) to a representation that would force you to make another choice (username Bob is no longer available). The various headers in the meta data describe the appropriate caching policy to apply to this representation, and so on.
Technically, I think 404 "works", in so far that you can make it do what you want. The semantics are incorrect; from RFC 7231
The 404 (Not Found) status code indicates that the origin server did not find a current representation for the target resource or is not willing to disclose that one exists
My interpretation of that passage is that the server is claiming that the client submitted a bad request (all 4xx status codes share that meaning) , and more specifically that the spelling of the resource identifier is the root of the problem.
It's a bad fit because the server, in this case, isn't having any difficulty fulfilling the request -- it understands the request just fine; the "problem" is that the representation being returned isn't the one that the client is hoping for.
REST is about exposing, creating, and mutating resources. Each endpoint URI defines the location of that resource. In the case of a User resource, you would typically expose an endpoint to the collection of User resources with a URI like /users, and an endpoint for individual User resources of that collection with a URI like /users/{id}. Each endpoint is tied to a resource; not an operation. Endpoints that expose operations follow RPC architecture.
To do this RESTfully, your validations would be run when attempting to create a User resource using the user input. This could be done using an HTTP request line like POST /users. Upon invalid format of the username value, you would respond with a 400 status code, to indicate error on the user's part. Upon conflict with an existing username, you could return a 409 status to indicate a conflict between the request and internal API state. Your responses should also contain a body with further details of the issue. Upon a successful creation of a User resource, you should respond with a 201 status to indicate that the resource was created successfully.
Another way to go about this RESTfully, would be to key the individual User resource URI on the username, so that you would have something like /users/{username}. Then, to check if a username already exists, you would simply form a request like GET /users/{username}. If a User resource with that username does not exist, the API should respond with a 404 status, which would indicate to your client that the username is available. A response status of 200 would obviously indicate that the username is already in use.