Backend exception handling for REST app - should we return 4XX error or 200 with error mark - rest

I am working on large-scale web app, and within the project I am developing a REST app for outside clients. I think that this question has not very much to do with the specific technology that I am using, but just in case - it's Django.
We have a convention with the development team that REST resources always return a standard JSON object of type
{'success': <value>,
'object': <value>
'error_msg': <value>,
}
along with the status (200, 201, 403, etc....)
Examples of Django implementation:
return Response({'success': true,
'object': ...,
'error_msg': ...},
status=status.HTTP_200_OK)
The success parameter is assigned true for successful deployment of the resource, and false otherwise.
Now, the entire question here lies in what should be passed in status parameter in those cases when something bad happens - appropriate 4XX code or 200 ?. The development team suggests to ALWAYS use HTTP_200_OK, simply if something bad happened, just assign false to success. The error_msg will contain detailed error message in case of exception.
So the two alternatives among which I can't choose the right one look like this
return Response({'success': false,
'object': ...,
'error_msg': 'Details regarding the error'},
status=status.HTTP_400_BAD_REQUEST)
vs:
return Response({'success': false,
'object': ...,
'error_msg': 'Details regarding the error'},
status=status.HTTP_200_OK)
(in both cases success will equal to false. So in both cases the developer will know that something went wrong by looking at success without having to check status)
However, the very existence of different error codes leaves me with unpleasant doubt that I'm missing something about WHY people have come up with different error codes. And IN WHAT SITUATIONS my project can face trouble if it always returns the same 200 status code.After reading tons of materials, I have no material explanation why specifying appropriate error status codes could outperform the approach of returning 200 status.

HTTP codes are in my opinion a great way to get information on the result of an operation for the following reasons:
They are both machine- and human-readable (at least by developers).
They are integrated in every HTTP transaction, so every library implements mechanisms to deal with them.
The repertoire of error codes is 'standardized' and everyone knows how to deal with it, and it covers a lot of common cases (the DRF framework automatically uses some of those, such as 400, 403 or 405).
By ignoring them, you are increasing the amount of work that you have to implement on your own.
Of course, they might not be enough for particular cases. Suppose you receive a 400 code when you are submitting multiple fields to your API. If you want to know which ones are invalid and why, you still need the value of your error_msg, but the 400 code still simplifies a lot of your logic, since you can filter out a lot of other reasons why the request did not succeed (403, 405...).
Regarding your question:
And IN WHAT SITUATIONS my project can face trouble if it always returns the same 200
Well, if you implement things properly, leaving all error handling to the response date, it should never cause any trouble, but as argued earlier, I feel like this increases the complexity of the task at hand.
Please note that this are just my two cents, and there might be other opinions with better arguments for the opposite case.

Related

REST vs RPC - *Actual purpose* differences

I started writing web-apps and distributed apps when REST was already popular, so I actually never used RPC.
When searching for a simple explanation of the difference between them, I started to understand, but some examples got me confused.
I saw things like this:
GET /getLastUser
or this:
POST /changeUserName
If REST is meant for resources, and RPC is meant for procedures, isn't it a bad practice using RPC for something like this?
Correct me if I'm wrong, but the way I see it, RPC should be more purely functional.
Meaning that calling a procedure should always:
return the same result for the same arguments
not affect state
So, RPC calls like this:
GET /addTwo?num=5
that return something like this:
{
"result": 7
}
seem more logical to me (although that's a very simple example).
If this question gets closed for being too "opinion-based", I'll just know that I should do whatever the heck I want...
RPC is not meant to be functional. Calling a same procedure twice gives no guarantee about the result.
This question can be answered a few different ways, and pretty deep. I think this might be a fair summary.
With RPC the primitives typically are function names, arguments and results.
With REST the primitive is a 'resource representation'.
So where with RPC you might call a function, in REST you are really sending and retrieving the state of a resource, regardless of protocol.
This means you typically only ask a server 'can you give me the state of this resource', or you tell a server 'here's a new resource state, please store it at this location'. The only successful answers REST will give are "the current state" or "this operation worked", but with RPC the question (function + arguments) and answer (the result) can be anything.
So you can argue that when you describe it like this, RPC is a lot more flexible. It probably is, but because REST confines itself to just transmitting state, you gain a lot of guarantees that a simple RPC-based protocol does not give.
REST is not just about transferring state. The usage hyper-links is another important requirement for a service to be called REST, and this is also something that you don't get 'out of the box' with RPC.
Lastly, it can be argued that HTTP itself is an RPC-like protocol. I think it's possible to build a RESTful service on top of any RPC service.

Which REST code for a resource which is conditionally available

I'm making a game where you can start a battle based on a task from a list.
Once you finish a battle (win or lose) the battle state will no longer be available, because there is no battle in progress.
This will be reflected in the API when you GET /battle.
If there is a battle in progress, you get an object response which reflects the current state of the battle, and a 200 REST code.
If there is no battle in progress, it would tell you you can't do this.
My question is as follows: What REST code should I use to express that the battle is not currently available.
Additional:
I haven't opted for the 404 because my interpretation is for a page which doesn't exist, has probably never existed, and might never exist, rather than a resource which might exist but not right now. I'm prepared to be wrong about my interpretation, though.
My extremely-basic research indicates a 409 might be suitably indicative, but that implies that the conflict occurs because of the request (such as a PUT), while the nature of my GET is not to affect the data, just report its state.
I could just detail that no battle is happening in a 200 response, but this feels like a REST code job.
I realise a REST code might not be the correct way to look at this, if so, please offer insights. Also, anything you think I should read. I'm professionally a front-end developer, so I'm usually consuming the API rather than writing it.
Under the constraint of using a unique response code to indicate the result, I would opt for an HTTP 204 (No Content). My rationale is that what you're looking to do is indicate that the resource (your battle) is valid, but there is currently no data available for it.
You could also opt to go HTTP 200 (Ok) and return a payload that indicates the current state, both when a battle is in progress and when it is not. This is what I'd probably go for, personally, as it helps to normalize the shape of your API for callers. Instead of callers having to memorize the rules around return code, they receive the same data structure in both scenarios and interpret it to discern the context. This would also allow you to extend the API with historical data, such as battle stats, after the battle was completed without breaking changes to the API.
I'm thinking something like the following for an in-progress:
{
"Id" : 1234,
"InProgress" : true,
"Battle :
{
"SomeProp" : "SomeValue",
"OtherProp" : "OtherValue"
}
}
...and something like the following for one not in-progress:
{
"Id" : 1234,
"InProgress" : false,
"Battle : null
}
I believe both approaches would be considered appropriate RESTful responses. To me, the choice is personal preference for the API contract that you'd like to offer.

Should a wrong parameter passed via REST call throw an error?

I was accessing REST calls, when I passed wrong parameter to GET request it does not throw any http error. Should the design be changed to throw a http error or wrong parameter can be passed to REST call.
Example 1:(parameters are optional)
https://example.com/api/fruits?fruit=apple
Give list of all apple elements
Example 2:
https://example.com/api/fruits?abc=asb
Give list of all fruits
My question is related to example 2, should example 2 throw an error or is it behaving properly?
It's pretty common to ignore parameters that you aren't necessarily expecting. I think example 2 is behaving as it should.
I know that depending on the browser I would sometimes append an extra variable with a timestamp to make sure that the rest call wouldn't be cached. Something like:
https://example.com/api/fruits?ihateie=2342342342
If you're not explicitly doing anything with the extra parameter then I can't see the harm in allowing it.
For a GET request, the request-line is defined as follows
request-line = 'GET' SP request-target SP HTTP-version CRLF
where request-target "...identifies the target resource upon which to apply the request".
That means that the path /api/fruits, the question-mark ? and the query abc=asb are all part of the identifier.
The fact that your implementation happens to use the path to route the request to a handler, and the query to provide arguments, is an accident of your current implementation.
That leaves you with the freedom to decide that
/api/fruits?abc=asb does exist, and its current state is a list of all fruits
/api/fruits?abc=asb does exist, and its current state is an empty list
/api/fruits?abc=asb does exist, and its current state is something else
/api/fruits?abc=asb does not exist, and attempting to access its current state is an error.
My question is related to example 2, should example 2 throw an error or is it behaving properly?
If abc=asb indicates that there is some sort of error in the client, then you should return a 4xx status to indicate that.
Another way of thinking about the parameter handling is in terms of Must Ignore vs Must Understand.
As a practical matter, if I'm a consumer expecting that my filter is going to result in a small result set, and instead I end up drinking a billion unfiltered records out of a fire hose, I'm not going to be happy.
I'd recommend that in the case of a bad input you find a way to fail safely. On the web, that would probably mean a 404, with an HTML representation explaining the problem, enumerating recognized filters, maybe including a web form that helps resend the query, etc. Translate that into your API in whatever way makes sense.
But choosing to treat that as a successful request and return some representation also works, it's still REST, the web is going to web. If doing it that way gives you consumers a better experience, thereby increasing adoption and making your api more successful, then the answer is easy.

RESTful APIs: what to return when updating an entity produces side-effects

One of our APIs has a tasks resource. Consumers of the API might create, delete and update a given task as they wish.
If a task is completed (i.e., its status is changed via PUT /tasks/<id>), a new task might be created automatically as a result.
We are trying to keep it RESTful. What would be the correct way to tell the calling user that a new task has been created? The following solutions came to my mind, but all of them have weaknesses in my opinion:
Include an additional field on the PUT response which contains information about an eventual new task.
Return only the updated task, and expect the user to call GET /tasks in order to check if any new tasks have been created.
Option 1 breaks the RESTful-ness in my opinion, since the API is expected to return only information regarding the updated entity. Option 2 expects the user to do stuff, but if he doesn't then no one will realize that a new task was created.
Thank you.
UPDATE: the PUT call returns an HTTP 200 code along the full JSON representation of the updated task.
#tophallen suggests having a task tree so that (if I got it right) the returned entity in option 2 contains the new task as a direct child.
You really have 2 options with a 200 status PUT, you can do headers (which if you do, check out this post). Certainly not a bad option, but you would want to make sure it was normalized site-wide, well documented, and that you didn't have anything such as firewalls/F5's/etc/ re-writing your headers.
Something like this would be a fair option though:
HTTP/1.1 200 OK
Related-Tasks: /tasks/11;/tasks/12
{ ...task response... }
Or you have to give some indication to the client in the response body. You could have a task structure that supports child tasks being on it, or you could normalize all responses to include room for "meta" stuff, i.e.
HTTP/1.1 200 OK
{
"data": { ...the task },
"related_tasks": [],
"aggregate_status": "PartiallyComplete"
}
Something like this used everywhere (a bit of work as it sounds like you aren't just starting this project) can be very useful, as you can also use it for scenarios like paging.
Personally, I think if you made the related_tasks property just contain either routes to call for the child tasks, or id's to call, that might be best, lighter responses, since the client might not always care to call to check on said child-task immediately anyways.
EDIT:
Actually, the more I think about it - the more headers would make sense in your situation - as a client can update a task at any point during the task processing, there may or may not be a child task in play - so modifying the data structure for the off-chance the client calls to update a task when a child task has started seems more work than benefit. A header would allow you to easily add a child task and notify the user at any point - you could apply the same thing for a POST of a task that happens to immediately finish and kicks off a child task, etc. It can easily support more than one task. I think this as well keeps it the most restful and reduces server calls, a client would always be able to know what is going on in the process chain. The details of the header could define, but I believe it is more traditional in a scenario like this to have it point to a resource, rather than a key within a resource.
If there are other options though, I'm very interested to hear them.
It looks like you're very concerned about being RESTful, but you're not using HATEOAS, which is contradictory. If you use HATEOAS, the related entity is just another link and the client can follow them as they please. What you have is a non-problem in REST. If this sounds new to you, read this: http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven
Option 1 breaks the RESTful-ness in my opinion, since the API is
expected to return only information regarding the updated entity.
This is not true. The API is expected to return whatever is documented as the information available for that media-type. If you documented that a task has a field for related side-effects tasks, there's nothing wrong with it.

QUnit and Sinon, testing XHR requests

I'm relatively new to unit testing and i'm trying to figure out a way to test an XHR request in a meaningful way.
1) The request pulls in various scripts and other resources onto the page, I want to make sure the correct number of resources are being loaded, and that the request is successful.
2) Should I use an actual request to the service that is providing the resource? I looked at fakeserver and fakexhr request on sinonjs.org, but I don't really get how those can provide a meaningful test.
3) I'm testing existing code, which I realize is pretty pointless, but it's what i'm required to do. That being said, there is alot of code in certain methods which could potentially be broken down into various tests. Should I break the existing code down and create tests for my interpreted expectation? Or just write tests for what is actually there?.... if that makes any sense.
Thanks,
-John
I find it useful to use the sinon fakeServer to return various test responses that will exercise my client-side functions. You can set up a series of tests in which a fakeServer response returns data that you can use to subsequently check the behaviour of your code. For example, suppose you expect ten resource objects to be returned, you can create pre-canned xml or json to represent those resources and then check that your code has handled them properly. In another test, what does your code do when you only receive nine objects?
Begin writing your tests to cover your existing code. When those tests pass, begin breaking up your code into easier-to-understand and meaningful units. If the tests still pass, then great, you've just refactored your code and not inadvertently broken anything. Also, now you've got smaller chunks of code that can more readily be tested and understood. From this point on you'll never look back :-)