
Designing Pragmatic RESTful APIs - coderush
http://info.apigee.com/Portals/62317/docs/web%20api.pdf
======
hakaaak
Developing REST API per definition of REST cannot be done pragmatically in the
way described, so you are going to screw a lot of people if they think this is
the last word on REST.

1\. REST is a hypermedia API that (somewhat) describes its own services by
returning URLs to resources, etc.

Most people don't understand what REST was meant to be that can drive how REST
clients were meant to be developed. Some of the major players with "REST" APIs
don't either.

2\. REST does not have to be versioned if for internal use.

I actually agree with the versioning part, however I've also been on two teams
over the past 10 years that developed versioned APIs and neither time did
versioning matter, because those APIs were for internal use.

3\. This is not a RESTful requirement, but, practically, you shouldn't design
an API that allows any querying of resources beyond what should be needed.

This is because of the memory required for caching responses (in a large
application), because it therefore can be an easy target for attacks (lets
throw a bunch of query params on here... mwhahahahaha), and just because it
opens up security holes. Be explicit in what is allowed in your code and your
documentation.

4\. The querying and filtering I see in this document is insufficient for some
applications and interfaces.

It didn't take us long to run into the limitation of the search functionality
described in this document in our current REST API based app.

~~~
RyanZAG
Could you explain a bit more on the limitations of the search functionality
and how you got around it? Would likely be very useful.

------
arethuza
I rather like the "Richardson Maturity Model" described by Martin Fowler:

[http://martinfowler.com/articles/richardsonMaturityModel.htm...](http://martinfowler.com/articles/richardsonMaturityModel.html)

This gives different levels of "conformance" with the spirit of REST without
name calling.

~~~
nicholassmith
I just got round to reading that article last week, it's incredibly
informative and like you say, avoids any mud slinging.

------
akavi
_Insert standard comment about how this does not touch on HATEOS and is
therefore not only not REST, but evil and perverse and all that is wrong with
the world_

~~~
mpweiher
Maybe we need a new name/acronym for this "pragmatic REST" style?

~~~
regularfry
REST level 1. Or 2.

[http://martinfowler.com/articles/richardsonMaturityModel.htm...](http://martinfowler.com/articles/richardsonMaturityModel.html#level2)

I don't agree with people who say that only level 3 is "true REST", but there
_is_ a qualitative difference.

------
mohamedattahri
Totally agree @hakaaak, especially with the care that should be put into
making the API navigable using hyperlinks.

It's kind of cool to have a browser-friendly API to play with in the
beginning, but it should be pure bonus. APIs are designed to allow a computer
program to interact with another one. Favouring query strings over HTTP
headers for anything other than altering the projection of a resource is non-
sense.

I also don't seem to understand why we must reinvent the wheel and duplicate
features when HTTP clearly mentions how to specify an output format, and how
to handle partial responses (Range, Content-Range, 206 Partial Response, etc).

PUT is not the equivalent of "update" in CRUD. PUT is meant to replace an
existing resource projection with another one. PATCH is the way to go if you
want to update specific attributes of an existing resource.

And what about ETags? conditional requests?

It kills me when people mix pragmatism with embracing years of bad practices.
That's how we end up with standards where history and legacy are more
important than common sense.

~~~
w0utert
>> _I also don't seem to understand why we must reinvent the wheel and
duplicate features when HTTP clearly mentions how to specify an output format,
and how to handle partial responses (Range, Content-Range, 206 Partial
Response, etc)._

It's not just individual features such as pagination and format handling where
the article fails to suggest using standard HTTP features. After the first few
pages -which do a pretty good job of explaining the most basic aspects of REST
APIs- the document more or less switches to a 'just put it in the
querystring'-attitude for about everything that goes beyond basic CRUD
operations. Want a subselection of resources based on attribute values? Put
the attributes in the query string. Want to limit the returned fields? Put
them in the querystring. Need to non-standard logic for handling the request?
Signal it in the querystring, so the API user can 'see it'. Want to query
something or get a calculated response that needs input parameters (i.e. JSON-
RPC)? Put all parameters in the query string. Want to suppress error codes or
otherwise instruct the server to change its behaviour? Querystring...

Personally I don't really like using the querystring for every bit of
information you want to include in a request, because before you know it the
amount of crap you can include in URLS will grow out of hand. I think dumping
everything into the querystring pollutes the URI space of your API, which
makes it harder to efficiently cache responses or limit access to certain API
endpoints.

I'm working on a web application with a REST API at the moment, and I'm trying
to avoid using the querystring as much as possible. For example query
arguments can also be POST-ed to a query URI that returns a link temporary
resource that identifies the query result. Format specification can (and
should) be handled using the Accept/Content-Type headers. Pagination can be
implemented using the range and partial response headers. Complex queries that
are performed often and cannot easily be encoded in a POST body (or a query
string) can get their own URI (e.g. '/dogs/by-age/0-1y', '/dogs/by-age/1-5y',
etc).

Probably this approach has some serious downsides, but I'm still sticking with
it for now. Maybe someone can make me change my mind with good arguments? ;-)

~~~
mohamedattahri
You're heading the right direction.

I'm one of the authors of <http://greendizer.com/docs/api/>, and
<https://github.com/mohamedattahri/Nuages>

Take a look at them.

------
zimbatm
If I had to restart my API over again I would make it self-documentable.

Browsing to /dogs with an Accept: text/html would include a description about
that end-point with the possibly accepted parameters, and links to related
resources.

If authenticated it would also include the content of that actual route and
maybe even a small JavaScript request builder.

~~~
melvinmt
I like the idea of self documentation but please don't do this with a
text/html header. Oftentimes I want to see in the browser what the GET
response is. Probably it's better to explicitly use a .html extension instead.

------
programminggeek
In the section "What about attribute names?" I think they get it wrong by
saying that camel case would be better than snake case because it would make
more sense in Javascript that way.

The issue I take with that is you can't assume your API consumer is using
Javascript at all. Thus, making it camel case might look right in Javascript
or many other languages, but weird in Ruby.

There are a lot of good ideas here, but I think the author messed up on that
assumption. A huge portion of modern API usage is in Objective-C, Java, PHP,
Ruby, C#. So, attribute naming could be valid as FooBar, fooBar, or foo_bar.

I think the right point would be to be consistent in attribute naming style.
Pick one format and use that.

Designing your API to be consumed by one language is mostly foolish unless you
are the only one using the API.

~~~
earth2marsh
Yes, but JSON is JavaScript Object Notation, not (PHP|Ruby|C#|Java|Other)
Object Notation. Therefore, since JSON is a serialization of JavaScript, it
recommends that you should adopt the JavaScript convention of camelCase.

------
bct
bcoates left an excellent comment here that has been marked dead for no reason
that I can see.

------
NanoWar
How does he talk about REST and totally forget about HATEOAS...

