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.
Related
I have a question.
In an interview, I was asked if one of the routes of scatter-gather fail, will we get the output. I replied with a no as scatter-gather always gives a consolidated payload taken from all routes, and then they asked me if I still want to get the payload from the successful routes, what should I do -> I answered with Try scope and on-error continue. (I hope I was right here, please explain if I wasn't).
The next scenario they gave me was like this: If I have an on-error-propagate set for the scatter-gather and I also have a payload in that. So when the route fails and the handler comes to on-error-propagate, will the payload present there be printed or not. My answer to this question was a yes and I said that because on-error-propagate executes all its steps, the payload present inside its scope will be printed and then the flow will exit.
I don't know if that was right or not, so please help me with the correct answer for this scenario.
I'm not sure if this is the right platform for these question but I'll try to answer them.
I was asked if one of the routes of scatter-gather fail, will we get the output. I replied with a no as scatter-gather always gives a consolidated payload taken from all routes
Scatter-gather executes all routes simultaneously and generates a LinkedHashMap of all the Mule Events (not just payloads). The payload from each event can certainly be extracted or functions like flatten() can be used to flatten the contents linearly. If one of the routes fail and no error handling is done, an error object will be introduced and scatter-gather will fail.
they asked me if I still want to get the payload from the successful routes, what should I do -> I answered with Try scope and on-error continue.
Your answer seems good to me. Although, please note that on-error-continue should be on another flow that scatter-gather is calling. Having it in the same flow as scatter-gather may suppress the error raised but will not continue executing the next component in same flow.
If I have an on-error-propagate set for the scatter-gather and I also have a payload in that. So when the route fails and the handler comes to on-error-propagate, will the payload present there be printed or not.
The statement is a bit confusing to me as it doesn't specify the placement of the on-error-propagate. If a printing component is inside the on-error-propagate scope and the handler comes to on-error-propagate, it will certainly print. However, if all it has is the payload, the flow will never go to the next component and an error object will be returned to the parent flow (or error is thrown if there's no parent flow).
I have a doubt on Http methods in Rest API.I read lot about over internet on this,that we can use Put for create or update the resource and Post for creating the resource and Delete for delete a resource.
But i am saying is this mandatory?because when we write code we just put the annotation like Put,Post and Delete but what would happen if I use Delete Annotation and in side method i do something else, suppose i write add logic instead of delete.I think i can do it,similarly in others methods(Post and Put.).Then what is the significance of these Annotations.If i can do what i have mention above means write the logic for add in Delete Annotation then for me Delete is only a type of request for me and i can write any logic for add or update.
Similar i read Put is idempotent but if i write add logic instead of update then it is not idempotent.
May be i might be wrong here.Please clarify this.This is causing confusion to me and nowhere it is explained,Every where the generic statement there.
Thanks & Regards
Amitabh Pandey
i am saying is this mandatory?
Not mandatory, no.
Roy Fielding made an interesting observation in 2002:
HTTP does not attempt to require the results of a GET to be safe. What
it does is require that the semantics of the operation be safe
The same holds for the other methods -- we all agree what the request message mean (semantics), because that's what is in the standards (RFC 7230, etc). So PUT always means "please replace your current representation of the target resource with the representation I'm providing", but what your implementation does with that message is up to you.
Of course, if your implementation is surprising, there is an important caveat:
it is a fault of the implementation, not the interface or the user of that interface, if anything happens as a result that causes loss of property
The point of REST is that general-purpose components can interact with your resources via the uniform interface. If your implementation doesn't match the uniform interface, then it's your bug, not a bug in the component, that things don't "just work".
i read Put is idempotent but if i write add logic instead of update then it is not idempotent.
The semantics of PUT are idempotent. If your handler for PUT requests isn't idempotent, then you have made a mistake, and your implementation has a fault. If a general purpose component needs to send multiple PUT messages (for instance, because a response was lost on an unreliable network), then that fault becomes a failure.
"Add logic" isn't necessarily not idempotent, of course -- think about adding a key and value to a dictionary; if you add the same key twice, that's the same as adding the key once.
d = {}
d[k] = v
d[k] = v # idempotent, because this is a no-op
e = {k:old}
if e[k] == old:
e[k] == new:
if e[k] == old: # Again, idempotent, because the second copy of the message is a no-op
e[k] == new
What's supposed to happen, if somebody sends a PUT request and you cannot ensure idempotent semantics, is that you should return a 405 Method Not Allowed, and make sure that your response to OPTIONS doesn't claim that PUT is supported for that resource.
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.
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.
How can I "Fire and forget" certain requests, such as DELETE or PUT or even some POST, with RK?
I've been googling and have found a solution, but I have to believe there is an easier way that I'm missing. This is what I have:
Model: Room
Room GET request: I set up RKObjectMapping, RKResponseDescriptor, route(responds to 200) <--- works perfectly
Room DELETE request: I set up RKObjectMapping, RKResponseDescriptor, route(responds to 204) <--- works perfectly
My question is: Is there an easier way to do this?
Maybe I'm being lazy, but setting up RKObjectMapping, RKResponseDescriptor for every action seems like a lot of extra work if I don't plan on doing anything with the response. (Note: even error handling isn't necessary.)
I'm relatively new to restkit, sorry if I'm missing something obvious. Any advice would be appreciated.
Thanks for indulging my laziness :)
If you don't care about the response (or even the result status) then you don't need to define response descriptors. Technically RestKit will raise an error result because no response descriptors could be found but that doesn't matter to you.
If you aren't using the get/put/post object methods then an alternative would be to define a single mapping to an NSDictionary. The mapping could have a single key (or it may work with no keys). Then, for any request where you don't care about the response you can provide a valid mapping which is basically a no-op.
Another alternative is to write a single method which takes a Class and returns an empty response descriptor. You'll still have some configuration calls but much less code.