Introducing Lingwo.ws

Over the past several months, I've been thinking about how to make a really strong RESTful API for Lingwo.flashcards.  At my straight job, there has also been lots of talk about building a RESTful API (although, unfortunately, no actual work!  I'm bursting at the seams to start it!).  This and the fact that all the other Lingwo Projects will need APIs, has compelled me to take the API design I've come up with and release it as an open specification.

So, to start over... Lingwo.ws is an open specification for a pattern by which one can design RESTful web-services.

But why do we need such a specification?

Well, being RESTful means that you adhere to some rather abstract concepts.  Two APIs can be designed in drastically different ways and still be perfectly RESTful.  We can gain alot by having a standard:

  • We can share code for consuming such services.  For example, one only needs to write one Lingwo.ws client for Python, and now all Python programs can consume a Lingwo.ws service with little effort.
  • We can share code for creating services.  For example, one only needs to write a single WSGI implementation of Lingwo.ws services and now service authors in Python have tools for easily building compliant services.
  • We can share expectations.  When someone says their service is RESTful, that means we'll be digging into some documentation and learning how to use it.  But if someone says their service is Lingwo.ws compliant, well, then you may already know what that means.

Now, I have no illusions of grandeur.  There are some situations where a custom designed RESTful API may model the service better than Lingwo.ws.  So, you won't hurt my feelings if you don't make your next service Lingwo.ws compliant. ;-)

What I am trying to accomplish is a design pattern which meets the needs of 80% of service designers.  Now, in that 80% space, there are about 1 million different ways to do the same thing.  This is just one way.  It isn't better or more magical than any other way.  With all those 1 million ways being roughly equal, Lingwo.ws really gets its value by being specified.

Ok, where's it at?

All that said, you can see my current draft in The Lingwo Project's wiki under Lingwo.ws Design.  It is not finished by any means.  And, unfortunately, lots of things that have already been designed haven't landed on that page yet.  I apologize for that.

There is also a reference implementation in the works.  It is both more and less complete than the specification. ;-)  On Launchpad, you can find a mirror of the code.

In future blog posts, I hope to go into more detail about the actual workings of the API.  I'd like to do a tutorial series about using the reference implementation since getting it up and running and poking around may be the easiest way to understand.

Beyond REST...

While I personally love working with RESTful APIs, others may have differing opinions.  Thats why one of the design goals of Lingwo.ws, is that it should be possible to automatically generate SOAP-based web-services on top of the RESTful ones.  After all, any service author's primary goal is get as many consumers as possible.  Give them what they want!

Also, one of REST's main virtues is being stateless.  However, I am going to include a stateful proxy for use with Javascript.  I'll go into this more in later posts (or you can look at the design doc in the wiki), but Lingwo.ws uses a private key scheme for authentication.  Clearly, you need to do everything you can to keep the private key hidden.  But if you are making a pure client-side Web 2.0 application, you can't really put your private key in the web-page can you!

The stateful proxy exists to integrate with your login system, using a session cookie with a shared secret, in order to verify that requests are coming from the user they say they are.  (BTW, the cookie scheme I plan to use is the mod_auth_tkt one, which has become something of a defacto standard with this sort of integration)

However, both these bits, the SOAP proxy and the Javascript proxy, can just be layered on and forgotten.  That's the beauty of having the core be RESTful.  Its very easy to layer non-RESTful stuff on top of REST but much harder to do the reverse.  And we get our one elegant canonical API, while still giving each "audience" what they want.

One advantage some SOAP advocates tout over REST, is that SOAP is discoverable, but with REST you have to read the docs to know what is available.  (Yes, I know there are emerging standards like SMD for REST!)  In Lingwo.ws, there will be a way to find what "containers" exist and the formats of their "documents" (see the design doc for terminology).  I plan to base it on JSON Schema (at last look, SMD seemed unable to describe some of Lingwo.ws's resources correctly but more research is necessary).

Anyway, this is just a quick introduction.  I've been holding off on talking about this for so long and have so much to say, I think I'm just going to stop myself now. ;-)