Designing of a WebService API for paths between two points - web-services

I have a Web Service which returns details of path between given two input points if exists. The Web Service API is something like getPath(Point start,Point end). Now if the path doesn't exist between given start & end points, how should API behave among below options
Return a null object
Throw a PathNotFoundException
Always include a status code in the response along with path details. In this case return empty path and status code as appropriate error code like "PATH_NOT_FOUND" / "ERROR"
Any other option? Please suggest.
Please let me know your views
Thanks,
Harish

Suggestion: 1. return null or empty path.
Throwing exceptions across http is probably not the best idea and returning status codes is a way to workaround throwing exceptions. The lack of a path is not something that should occur as error at the client side.
I would reserve exceptions/status codes for wrong parameters, wrong number of parameters, some server-side problems like inaccessible database etc.
Suppose you are querying the database for a list of customers from NY. Would you throw an exception if the list is empty or just return an empty list? This sounds exactly like your scenario.

Related

Zero-length URL Segments

Using the latest versions of Flask and Flask-RESTful, I have some very basic routes defined as such:
def build_uri_rules(uri_map):
for cls, uri in uri_map.iteritems():
api.add_resource(cls, uri)
uris = {
SampleController: '/samples/<string:hash_or_id>',
SampleFamilyController: '/samples/<string:hash_or_id>/family',
}
build_uri_rules(uris)
This works for uris requested 'properly', but what if the /samples/ endpoint is hit without a parameter, or the sample*family endpoint is hit with an empty sample id? Currently, this results in a 404 error. This works well enough, but I believe the proper thing here would be to throw a 400 error, as they found a proper URL but their data is improperly structured. Is there a way that I can force this behavior?
As a side note:
Looking through the Werkzeug docs, I see that werkzeug.routing allows a minimum length for certain url parameters, but I also see that it's got a minimum of 1. Admittedly, I've not look for why this is the case, but would this be the right tree to bark up? or should I rather simply create a global 404 handler that checks for the length of the parameter and raise the proper error from there?
Thanks!
EDITED: For code correctness.
I would say that hitting /samples/ or /samples/family (or even /samples//family) should result in a 404 as there is nothing at that endpoint.
If, however, you want to do otherwise, the simplest way to handle it would be create a 404 handler for just /samples/ and /samples/family that returns a note with more information about what the consumers of your API are most likely doing wrong.
uris = {
Explanitory400Controller: '/samples/',
SampleController: '/samples/<string:hash_or_id>',
Explanitory400Controller: '/samples/family',
SampleFamilyController: '/samples/<string:hash_or_id>/family',
}

Correct yummly API call for a recipe

I'm trying to use the Yummly API. I've noticed that some of their developers have answered other questions here, so I'm hoping to catch their eye. I used the documentation at the yummly developer site https://developer.yummly.com/documentation#IDs.
Specifically here is my get request:
<http://api.yummly.com/v1/api/recipe/Avocado-cream-pasta-sauce-recipe-306039>
Which returns this:
Please include X-Yummly-App-ID and X-Yummly-App-Key
Seems like this is a sensible thing, except that I don't see anywhere in the documentation for the single recipe call where I'm supposed to insert that info. Any one out there know how to properly format this?
or include them as URL parameters:
_app_id=app-id&_app_key=app-key
https://developer.yummly.com/documentation#IDs
Try this:
http://api.yummly.com/v1/api/recipe/Avocado-cream-pasta-sauce-recipe-306039?_app_id=ID&_app_key=KEY
You need to take the URL you mentioned in the question and add your authentication parameters to it. So it becomes:
http://api.yummly.com/v1/api/recipe/Avocado-cream-pasta-sauce-recipe-306039?_app_id=ID&_app_key=KEY
Instead of ID and KEY insert the application id and key from your account on developer.yummly.com

Parameter not supported by web service

I want to validate an opinion with you.
I have to design a web service that searches into a database of restaurants affiliated to a discount program in a specific country around a given address.
The REST call to such a webservice will look like http://server/search?country=<countryCode>&language=<languageCode>&address=<address>&zipcode=<zipcode>
The problem is that some countries do not have zipcodes or do not have them in the entire country.
Now, what would you do if the user passes such a parameter for a country that does not have zipcodes, but he/she passes a valid address?
Return 400 Bad request.
Simply igonre the zipcode parameter and return results based on the valid address
Return an error message in a specific format (e.g. JSON) stating that zipcodes are not supported for that country
Some colleagues are also favoring the following option
4. Simply return no results. And state in the documentation that the zipcode parameter is not supported. Also we have to create a webservice method which returns what fields should be displayed in the user interface.
What option do you think is best and why?
Thanks!
Well the OpenStreetMap Nomination Server returns results even if you dont know the ZIP Code and you can look at the results anyway. What if the user doesnt know the zip code but wants to find hist object?
I would try to search for that specific object anyway, especially because you said that some countries have zip codes partially.
If you simply return nothing te user doesnt know what went wrong and he wont know what to do.
That would depend on the use case. How easy is it for a user of the API to trigger that case? Is it a severe error which the user really should know how to avoid? Or is it something that is not entirely clear, where a user may know (or think he knows) a zipcode where officially there shouldn't be one? Does it come down to trial and error for the user how to retrieve correct results from your API? Is it a bad enough error that the user needs to be informed about it and that he needs to handle this on his side?
If you place this restriction in your API, consider that it will have to be clearly documented when this case is triggered, every user of the API will have to read and understand that documentation, it needs to be clear how to avoid the problem, it needs to be possible for the user to avoid the problem and every user will have to correctly implement extra code on his side to avoid this problem. Is it possible for the user to easily know which areas have zipcodes and which don't?
I think the mantra of "be flexible in what you accept, strict in what you output" applies...

Hash anchor tag causing errors in URL

On very rate occasions, my error log is showing the following error:
"You specified a Fuseaction of registrationaction#close which is not defined in Circuit public."
The full link is:"http://myUrl/index.cfm?do=public.registrationAction#close"
As you can see, the has merely points to an anchor (close) on the page.
This code is working 99% of the time, but on the odd occasion, Coldfusion / Fusebox throws this error out.
Why is this happening?
Could it be related to the device accessing my page somehow? Like a cell phone or Apple product that for some reason does handle hashes the way I am expecting it to?
Could it be javascript / JQuery being disabled?
Any guidance would be appreciated
Thanks
I used to see stuff like that. Older versions of Internet Explorer were not handling the hashtag properly when there were URL parameters. The best solution I could come up with was kludgey at best, but basically it forced the anchor tag to separate from the URL parameter.
http://myUrl/index.cfm?do=public.registrationAction&#close
I'm not sure there is a simple answer to this. We get odd exceptions all the time on our site for all sorts of reasons. Sometimes it's people not using the site the way you expect and sometimes it stuff like you mention such as user-agent edge cases etc.
Basically you need to start to gather evidence and see what comes up that's unusual with these requests.
So to start: do you catch exceptions in you application? If so dumping all scopes (CGI/CLIENT/FORM/URL/SESSION) in an email along with the full exception and emailing them to a custom emails address (such as errors#yourdomain.com) will give you a reference you can square up to your error times and this might give you a hint as to the real issue.
Hope that helps some!

REST Architecture - How the Url of a complex method would look like?

I have the following Url which returns me the list of resources:
http://example.com/resources/
I also implemented a method which returns a specific resource (in this case, the resource 142).
http://example.com/resources/142
I would like to add a method which is outside the typical HTTP method: List, Create, Retrieve, Replace, Update. What is the pattern to follow? In my specific case, I need to check the availability of resource. How would the Url look like (http://example.com/resources/checkavailability/142)?
I though about simply using the GET method and retrieve that information as part of the object returned. However, some of my colleagues argue that this would not be efficient (the data to transfer would be much bigger than just returning true/false).
Thanks for the help!
There is no need for a resource to check the availability of another resource, and there is no need for a GET request, a HEAD request should be enough, this is the same as a GET request but without transferring the body. You can then look at the return codes, and via those determine if the resource is available. This is assuming you have properly implemented return codes.
Restful over HTTP gives you uniform interface, you often don't need to encode the actions inside your URL
Regarding your mentioned /checkavailability using GET returning payload inefficiency is a valid reason, so use HEAD (it only gives you back the response headers).
request:
HEAD /resources/123
response status:
404 Not Found: equals to /checkavailability == false
200 OK: equals to /checkavailability == true
Other suggestions uniform interface replacements:
/resources/list : GET /resources
/resources/replace/123: PUT /resources/123
/resources/update/123: PUT /resources/123
/resources/create: POST /resources