Return 403 or 201 if a field is not writable - rest

What is the best practice for a response if the user tries to write to a field he or she is not allowed?
Imagine the user wants to create a resource, for example a pizza: POST /pizza
The body:
{
"name": "Hawaii",
"base": "tomato sauce",
"firstMain": "ham",
"secondMain": "pineapple",
"cheese": true
}
Problem is, you can't put secondMain on a pizza (because its pineapple). What's better? Return a 403 error with the message that field secondMain is not writable or return a 201 with the created pizza but without the secondMain?
What's the best practice for this problem? Didn't found anything on Google.

Returning a 403 with a proper error response would work best. Saying 201 but creating something different then what they originally wanted would probably lead to a unhappy customer. I know I'd be annoyed if my pizza didn't come with pineapple and that's what I ordered.
Really guess it varies on a case by case basis depending on your expected result and what your client is expecting to happen. Just make sure to specify in your documentation that extra data sent up with requests that isn't writable will throw an error.
etc
403 response: {error: {"secondMain": "unknown field", "exampleField": "expected but missing"}}

Related

HTTP service API error message best practise

For a error case when calling some HTTP Rest service API, the response is as follows:
{
"statusCode": "400",
"error": "Bad Request",
"message": "Can not construct instance of java.math.BigDecimal from String value 'a': not a valid representation\n at [Source: org.apache.cxf.transport.http.AbstractHTTPDestination$1#2f650e17; line: 1, column: 2] (through reference chain: com.foo.services.dto.request.ItemToUpdate[\"quantity\"])",
"validation": {
"source": "PAYLOAD",
"keys": ["key"]
},
"errorIdentifiers": [],
}
I am wondering if the message field in the response is appropriate. It does reveal certain level of implementation to the end user. Is this considered as
no particular problem at all
just a bad cosmetic issue that won't cause serious problem, just not readable to end user
potential security risk that definitely needs to be fixed
I think that you should only log the stacktrace on the server side. IMO it's technical hints (in addition, perhaps the end user even doesn't use Java to interact with your API) and the only thing that interests the end user of your API is that there is here a validation error within the provided data.
Another remark is that you use the status code and statusmessage within your response payload. I think that you don't need to duplicate this since it's already present in the response.
I would suggest an error message like that:
{
"messages": {
"quantity": "this must be a valid number"
}
}
I use a JSON structure for the field messages since there could be several validation errors within the provided data. Note that it's only a suggestion and you could extend this to your exact needs.
Hope it helps.
Thierry

RESTful way to accept a choice

I have a simple api, that works like this:
A user creates a request ( POST /requests)
Another user retrieves all requests ( GET /requests)
Then adds an offer to a request ( POST /requests/123/offers)
Original user can now see all the offers being made for the request (GET /requests/123/offers)
What i want to do, is allow the inital user to accept an request, but I can't figure out the best way to do it RESTfuly.
Should I do it with the PATCH verb? Like PATCH /requests/123 and require that the patch body contain a valid offer id?
Accepting an offer five times should have the same effect as accepting it once. It is idempotent. So it should be a PUT.
You might want to consider choosing a different name for your "requests." When I do GET /requests/123, I request a response that is a request? This could be a little confusing for clients.
Additionally, try to avoid nesting your resource identifiers. That can create problems for you later. An offer doesn't really have to be "underneath" the corresponding request. What happens when you later want to have offers corresponding to multiple requests?
A good rule of thumb is, if you would consider "Gizmo" an entity in an entity-relationship model, it should be a root-level URI, like in GET /gizmos/17, not GET /widgets/54/gizmos/17. A common mistake is to say "Every Gizmo has exactly one related Widget, so I should nest Gizmo URIs as extensions of Widget URIs."
Below I have a suggestion for how the operations would look. You may want to replace some of the ID references with URIs instead, but that's up to you.
POST /requests ---> 201 Created
Location: /requests/123
GET /requests ---> 200 OK
[
{
"requestId": 123,
"offersUri": "/offers?requestId=123",
...
},
...
]
POST /offers ---> 201 Created
{ Location: /offers/456
"requestId": 123,
"amount": 300,
...
}
GET /offers?requestId=123 ---> 200 OK
[
{
"requestId": 123,
"amount": 300,
...
}
]
PUT /offers/456/approval ---> 204 No Content
PUT /offers/456/approval ---> 204 No Content
PUT /offers/456/approval ---> 204 No Content
Depends on the nature of the Acceptance.
If Acceptance is a simple attribute of an offer, I would POST the Offer with the Acceptance set to True.
If the Acceptance is more complex and therefore a resource in its own right, I would PUT an Acceptance into the offer (PUT /requests/123/offers/acceptance).
If there exists such a thing as a rejection, or a request for offer clarification, I might consider the relevant resource to be a Response, not an Acceptance, and PUT that (put /requests/123/offers/response).

Structuring a RESTful service to respond when no results found

I'm building a RESTful service with Symfony2.
It has a search function which returns a search entity, the entity has an array of results.
If the user performs an improper search there are a few different messages I may need to send them. Thus, My thought on how to structure the response is:
For a good search:
{
"message": "OK",
"search": <insert search object here>
}
and for a bad search:
{
"message: "Please double check your search in such and such fashion"
}
Essentially, always sending a "message" but not always sending a search entity, as one will not have been created if their search failed in certain ways.
Then, I will always return a 200 response, even when their search criteria were off. Or, if there were no results.
Does this jive with the thinking behind REST, or should I be changing the response to a 404 or something?
Thanks!
I think it depends on how you want to structure your RESTful service. When you say If the user performs an improper search to me that sounds like the user is using bad syntax in the search or doing something else wrong, as opposed to a properly formatted search that simply returns no results.
If that's the case I think most REST services return 400 - bad request, or some other error code in the 400 range.
Also, I think most REST services would return the search entity in the response body.

HTTP reponse for error in REST call for Mojolicious

The mojolicious application that I use is JSON based, that is the interaction between the client and the server is more of an exchange of JSON structured data.
I am trying to implement a standard way of handling errors with proper HTTP response code when an error occurs during one of the REST calls. What is the best way of implementing such a standard and where do I do it?
I see a couple of ways of doing it
Create a class and list all the error response and its associated content, a call could be made to this class with the response code, which would return the JSON structure(combination of hashes and arrays) containing all the associated entry, then use the render_json() method in controller and return this as a response to the client
I can create a table in the Database with entry for all the fields that are required for the response, use the filed to access the JSONstructure, create the appropriate response and use render_json() in controller and return this as a response to the client.
Example of error response might be like
{
"Message": "The requested resource is not found"
"Type" : "http://this.is.an.error.com/error/resource_not_found",
"ErrorCode" : 404,
"Created" : "2012-11-05T11:59:29-05:00",
"Request" : "GET /types/Foo/instances"
}
What is the right way of standardizing such a response?
As titanofold mentioned, I'd go for option 2.
Regarding error codes, try to stick with standard HTTP Response Status Codes.
Besides setting the ErrorCode property in your JSON, you should send the status code in the response header because:
you can treat errors in a single place - the error callback of your javascript function
in the future you might have other consumers of your backend (mobile apps for example)
this is why they have been invented
You can achieve that extremely simple with Mojolicious:
$self->render_json( {
Message => "The requested resource is not found",
Type => "http://this.is.an.error.com/error/resource_not_found",
ErrorCode => 404,
Created => "2012-11-05T11:59:29-05:00",
Request => "GET /types/Foo/instances",
},
status => 404);
The wonderful things about standards are that there are so many to choose from, and if you don't like any of them you can make your own.
As to the REST structure, that's up to you. I would go for the generic 'code' rather than 'ErrorCode' as you should return a code on success, too.
For your method options, I'd go with option 2.
I would also opt for option 2. But I do not understand the need for the error details to be part of the database. I would rather suggest you use a the OO concept of base class holding all the error details and the inheriting it to other classes, making sure you have access to it.

How to handle nested resources in Web API ("REST") when not found?

Let say I have a resource Person and on a person I have a nested resource SomeResource. Which status code should be returned and why in the following scenarios?
/Person/1/SomeResource (SomeResource does not exist)
/Person/1/SomeResource (Person does not exist)
I think that 404 should be used in both scenarios but not everyone agrees and I would like to know why. You could argue that Person is the underlying resource and SomeResource is just a "property" on that resource and the request to SomeResource should therefor return nothing in the first scenario but 404 in the second scenario. I think that might be an option, but I still like 404 more. Another scenario that I don't like at all is to return 500 with an error description, that was an alternative I heard in the discussion as well but that forces the consumer to program against exception which I don't like. 500 for me means that something went wrong and you can't really do anything about it.
The problem is that the argument was that you don't know why you got a 404 if you got it, was it because of that the Person didn't exist or because of that the SomeResource didn't exist.
UPDATE 1:
Maybe I should break out SomeResource to a separate resource like
/SomeResource/1
which returns a response like {data: {the data}, person: {person data}}, and this only returns 404 if both are missing but if the data is missing a 200 is returned with empty data.
UPDATE 2:
I think I figured out which status code to use and it is 400 for when the person is not existing since I at that point considering it a request you should never have done, that is, a bad request. When SomeResource is missing I would go for 404 since the Person did exist but the nested resource was missing.
It may be helpful to remember that a given URI is intended to identify at single "resource". Semantically, a URI structure does not support the concept of "nested" resources. It seems you have two resources: Person & SomeResource in your scenario where SomeResource has a relation of some sort with Person. You could try a structure like this to represent this relationship:
GET /person/1
{
name: "Some Value",
someResource: {
"Href": "http://yourSite.com/someresource/123",
"Title": "Get some resource for this specific person"
},
// other key/value pairs as appropriate...
}
This way you are not overloading the 400 & 404 with application specific meanings. If the client has received a valid Person result, it would simply invoke the SomeResource href and would receive the appropriate 404 or not depending on SomeResource 123 existing. If the Person URI does not exists, invoking it would appropriately return 404 since it does not exist.