APIs

API Styles

If you have decided to create an API, there are several questions to ask. One of them is what style of API you will use. The Ruby on Rails community has rallied around the idea of REST—"representational state transfer", a term coined by Roy Fielding—which basically assumes that each URL uniquely identifies a resource on the Internet. Different actions performed on that resource do not make use of different URLs, but rather of different HTTP request methods.

For example, if you have an address book containing information on many people, the first entry might have a URL of:


/people/1

In such a case, you could retrieve information with:


GET /people/1

and a new entry with:


POST /people

Remember that POST requests send their name-value pairs separately from the URL. Because the parameters aren't part of the URL, it sometimes can be a bit tricky to know precisely what is being sent to the server. I generally check the parameters that are being sent using a combination of tools, including the server's logfile, the Firebug plugin for Firefox, the Web developer plugin for Firefox or the ngrep command-line tool for finding and displaying selected network packets.

In the Ruby on Rails universe, you can update an existing entry using the little-known (and little-supported, at least for now) PUT request method:


PUT /people/1

As with POST, the parameters in a PUT request are sent separately from the URL. Trickier yet is the fact that many browsers cannot handle PUT requests directly. The solution that Rails employs, for the time being, is to use POST, but to add a "_method" parameter as part of the request. When the server sees this, it uses the action that should be associated with PUT, rather than with POST. The system works well, although it obviously would be better if browsers were able to support all of the standard HTTP requests.

One of the key things to remember when working with REST is that URLs should refer to nouns, not verbs. Thus, it's perfectly acceptable, within the REST world, to have URLs that refer to any object on your system, from users to books to airplanes to credit-card statements. However, it's not acceptable to name the action you wish to take in the URL. So:


/airplanes/523

would be perfectly acceptable, but:


/airplanes/get_passenger_list/523

would not be. The difference being, of course, that get_passenger_list is presumably the name of an action that you wish to take on the airplane resource. This means you're no longer using the URL to refer to a specific resource, but instead to an action.

RESTless Development

When it was announced that Rails was moving toward REST, I must admit I was somewhat resistant. I preferred to use URLs that had been traditional in the Rails world until then, naming the controller and action, as well as an object ID, in the URL. Thus, if I wanted to retrieve one person's address, I would use a URL such as:


/people/get_address/2341

where 2341 would be the unique ID for that person. And, for the most part, this paradigm worked just fine.

But, then I discovered what many Rails developers find out: that Rails is, as it claims to be, "opinionated" software, meaning that things are extremely easy if you do them the way it was designed, and very difficult if you try it in any other way. And as time went on, it became clear that my non-REST URLs were giving me problems. Many elements of Rails were no longer working for me, because they depended on REST. When I started to work with Backbone.js in 2011, I found that Backbone works with a variety of back ends, including Rails, but that using a non-REST interface was clumsy to work with, if it was even possible to use at all.

Thus, I began to get REST religion and tried to make every application I wrote conform to this sort of API, and it worked in many ways. The APIs were consistent, and my code was consistent. Because I was using the scaffolding that Rails provided—if only at the start of a project—the code was smaller and more consistent than otherwise would have been the case. In the case of Rails, which dynamically creates identifiers that represent specific URLs (for example, addresses), sticking with the RESTful routes really simplified things.

That is, until it didn't do so. REST, at least in the Rails implementation, gives you a single HTTP request method for each action you want to perform on your resource. This works well, in my experience, until you want to retrieve resources based on parameters, at which point things can get a bit complicated. Sure, you can pass parameters in the HTTP request, but at a certain point, I personally would rather have several small methods than one method with a huge set of if-then statements reflecting different combinations of parameters.

______________________

Reuven M. Lerner, Linux Journal Senior Columnist, a longtime Web developer, consultant and trainer, is completing his PhD in learning sciences at Northwestern University.

Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

At a minimum, I would want

Tony lincle's picture

At a minimum, I would want the box to say "Live Data", Some of the more handy ones will scan the truck, record the data and download it to your computer. Many pull data from the trans, ABS, and other systems.
Truck Adblue Emulator for IVECO

qswatches

qswatches's picture

In the winter, it's quiet, everything seems to be to the original state, as the time to stop down. But it is also and such rise, and seem to be pregnant with new life.rolex daytona & celine bag 2012

Traditional Chinese clothing

Anonymous's picture

Traditional Chinese clothing is usually worn loose and comfortably so as to not get in the way of work and daily activities. An exception to this in ancient times was footwear. It was considered beautiful for women to have exceptionally small feet, especially during the Sung Dynasty of the 1100s, and thus the feet of girls were tied tightly in bandages until the bones were broken and their feet were curled almost in half. Chinese Fashion

django apis example

kiddhustle's picture

Nice article that gave me a refresher on how a restful api should be structured.

Now are there any examples/ codw snippets showing how an api can be constructed in django? Currently looking at getting started with framework but I have no experience as yet.

RE

Johanna's picture

RSS Feeds are indeed not geeky, but they are a bit old, nowadays people connect everything through API's, not through RSS feeds (like prepaid-mobiel.nl ). Welcome to 2012.

absolute REST example?

eMBee's picture

how would a search look like if you follow the REST absolutism you mentioned? i am only starting to look into REST and i can't even conceive why using actions in the url would be a problem. how do you do that then?

what about a resource like /airplanes/523/passengers
or /people/2341/address ?

wouldn't that be the same thing?

as for your routes example, how do the resulting urls look like?

/articles/latest
/articles/123/article_links
/articles/stories

and are those good or bad examples for a REST api?

greetings, eMBee.

Web APIs

Ed Carp's picture

This is what web services are for, and they've been around for a long time. There's nothing new here - output from wherever, wrap XML or JSON or even CSV text, ship it off to a consumer. Consumer strips off the JSON/XML/CSV and does whatever it wants with it. Pretty straightforward, actually.

I'm not sure why the author used a few thousand words to describe what I just did in less than 100. More words isn't necessarily better, unless you're getting paid by the word!

Well, it's not all about data

Ayesh's picture

Well, it's not all about data output. Client can send data to server, server and client can authenticate each other, and there are many actions. Yes it has been there since a long time but it's not all about data output. It's 2012 and rss feeds are no longer geeky.

White Paper
Linux Management with Red Hat Satellite: Measuring Business Impact and ROI

Linux has become a key foundation for supporting today's rapidly growing IT environments. Linux is being used to deploy business applications and databases, trading on its reputation as a low-cost operating environment. For many IT organizations, Linux is a mainstay for deploying Web servers and has evolved from handling basic file, print, and utility workloads to running mission-critical applications and databases, physically, virtually, and in the cloud. As Linux grows in importance in terms of value to the business, managing Linux environments to high standards of service quality — availability, security, and performance — becomes an essential requirement for business success.

Learn More

Sponsored by Red Hat

White Paper
Private PaaS for the Agile Enterprise

If you already use virtualized infrastructure, you are well on your way to leveraging the power of the cloud. Virtualization offers the promise of limitless resources, but how do you manage that scalability when your DevOps team doesn’t scale? In today’s hypercompetitive markets, fast results can make a difference between leading the pack vs. obsolescence. Organizations need more benefits from cloud computing than just raw resources. They need agility, flexibility, convenience, ROI, and control.

Stackato private Platform-as-a-Service technology from ActiveState extends your private cloud infrastructure by creating a private PaaS to provide on-demand availability, flexibility, control, and ultimately, faster time-to-market for your enterprise.

Learn More

Sponsored by ActiveState