HTTP and REST: don’t be client-server asshole!

Hi there!

When you have GET/POST/UPDATE/DELETE methods, it looks like you can cover all the REST needs you have. The issue is, REST looks too simple to read the manual before using it.

Do not forget following principles:

  • GET should be safe, it means GET should not change data on server.
  • Respect idempotence principle: POST is not intended to be idempotent: doing 10 POSTs should create 10 new items on the server.
    • On the other hand, PUT and DELETE should be idempotent: try to set the value 10 times or delete it 10 times — the data should be changed during first request only — you can’t delete the element 10 times.
  • Use the force response codes well. Take a look at this secret document and use it wisely. Moreover, using of 52x-58x can bring new light into client-server relations especially when client-side and server-side guys negotiate the meaning of that codes, for instance,
    • considering 520 means “Wrong user id”;
    • 521 means “Wrong filter settings”,
      …or something else.
    • Pay attention, any 4xx and 5xx responses are considered by browser’s Developer Panel as errors and might be shown in the toolbar and/or status bar.
  • Respect the Content-Type!
    • Many frameworks rely on correct Content-Type header expecting JSON. Why try decoding JSON if server informed me that the content is application/text?
    • Browser itself can set responseXML to null even if responseText looks like valid XML. That’s happens when Content-Type is not correct.
    • This is actual for front-end guys too: do not forget to set correct Content-Type when sending appropriate data to the server. God bless frameworks — they do it for you, {{programmerName}}.
    • A trick for front-end guys, you can override the Content-Type provided by server with your own one by doing XHR.overrideMimeType("desired/mimetype").

HTTP debug

Well, it looks everything is fine but you cannot get that [censored] response? Some tools come to rescue:

  • browser’s Networking panel — seriously, it’s a powerful tool.
  • curl (Linux/Cygwin). It’s scriptable so you can use it for testing too!
    curl can send POST data, even files, isn’t it good for testing?
  • If you are into GUI, Wireshark or Fiddler might be an option for you.

Fails I’ve met

Some episodes that make me to write this article:

Fail 1. Boolean mo[censored]er, do you use it?

I’ve got two JSONs created by different (but very similar semantically) classes. One contained
{..., "active": false, ...}, another one —
{..., "active": "false", ...}.
Very nice experience 🙂

Fail 2. Why try harder?

Somewhere in the very end of the method that returns JSON (after back-end guys were asked to add one more field):

// --- before ---
// return user.toJSON();

// --- after ---
return user.toJSON().replaceAll(/}$/, ", \"active\": " + /*...*/ + "}");

Well, it works, but I’d better didn’t know how.

Fail 3. Download PDF or open PDF?

I bet you met several sites that open the .pdf right in the browser. Another ones make the browser download the file.
The difference is,

  • the first server provides Content-Type: application/pdf and your browser knows what to do with this content (like it knows how to handle application/html);
  • the second server provides non-PDF MIME type.
    • You can force this behavior by passing Content-Type: application/octet-stream — this makes browser download even index.html.

With great power comes great responsibility, so use REST wisely.

Advertisements

2 thoughts on “HTTP and REST: don’t be client-server asshole!

    • Hi Nestor,

      If you are talking about examples of bad code, first two were Java back-end. I’m not that good at Java to tell you which framework was used.

      If you are asking about web services in general, it does not really matter what programming language to use. Most of contemporary frameworks respect these rules (ok, try to conform ’em 🙂 ).
      For instance, NodeJS/Express (and all the frameworks using it):

      – it produces correct Content-Type depending on the type of the data you pass as the response;
      – it allows handling response codes precisely.

      Regarding Java, frameworks use annotations that also ensure correct server behavior:

      @GET
      @Path("api/users/{id}")
      @Produces("application/json")
      public User getUserInfo(
      @PathParam("id") String uid,
      @QueryParam("filter") String filter
      ) throws ApiException;

      I believe that PHP also has these mechanisms automated in Yii or Laravel.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s