1) HTTP features the "Accept" header which allows the user-agent to specify the format of the response. The "*.json" thing is not standard and breaks HTTP.
2) "tickets/search" endpoint is not a resource. It's a different projection of the "tickets" collection. It's basic filtering. Rule of thumb is whenever you're about to use a verb to name an API endpoint, you can guess you're probably about to do something wrong.
3) A RESTful API needs hyperlinks. Resources must point to each other to help the developer navigate the API tree and access every single point it contains. The API origin (company.supportbee.com) should be the only information I need to discover the structure of your API.
The WWW is an example to follow. It's the most RESTful "service" out there.
> The "*.json" thing is not standard and breaks HTTP. It's more of a Rails convention and so we just followed it in the docs. Everything works fine without .json using the HTTP Accept header.
> "tickets/search" endpoint is not a resource. It's a different projection of the "tickets" collection. It's basic filtering. Rule of thumb is whenever you're about to use a verb to name an API endpoint, you can guess you're probably about to do something wrong.
Interesting. How would you approach it? Extend the /tickets endpoint to include some search parameters?
> A RESTful API needs hyperlinks.
I agree. However at this point it just seems a lot more work and also I have never really seen anyone use it (except for a few often quoted examples). We should change our documentation to use the word RESTlike.
Thanks once again for your feedback. We will improve the documentation soon.
It's a lot more work for the end user to have to assemble URLs themselves instead of you providing them in the response.
Let's say someone does a GET request on /tickets. The response should include URLs for each ticket that gets returned, e.g. something like:
{
"tickets": [
{
"ticket_id": 1337,
"url": "/tickets/1337"
},
{
"ticket_id": 1336,
"url": "/tickets/1336"
}
]
}
Again, the analogy of the WWW itself is instructive. When you browse to the home page of a website, that page has links to the other pages on the site.Similarly, the home page of a REST web service should have links to the other resources on the web service, e.g.
{
"resources": [
{
"resource_name": "Foos",
"url": "/foos"
},
{
"resource_name": "Bars",
"url": "/bars"
},
{
"resource_name": "Tickets",
"url": "/tickets"
}
]
}
That is simple, predictable, discoverable and self documenting for the end user.> Interesting. How would you approach it? Extend the /tickets endpoint to include some search parameters?
Exactly. I would do something like /tickets?q=somefilter.
As for the rest, I have nothing to add to the previous reply.
But it's easy to know you're not going in the right direction when a choice of yours contradicts or duplicates something clearly mentioned in the specifications of one of these protocols.
For example, the ".json" suffix to URLs is a convention is Rails. How can a language/framework-agnostic API borrow conventions from a framework?
It's not about usability. It's about consistency which will impact developers perception of simplicity. They'll just have less work to do before they can actually get started using it.
Regarding the content, I'm puzzled as to why versioning a web API should be a hard problem when you can just include the version number in the URL. Sure, you need to maintain this code path forever afterwards, but that's true of any platform with ambitions of backward compatibility.
Except that the cost in term of infrastructure and ongoing maintenance (code review, etc) is higher, which IMHO makes it likely to be phased out sooner than a web API.
I wonder if a better solution is something like Yahoo Pipes [1].