URI Design: Web API


Tim Bray posted about web style software. I’ve been doing a lot of thinking about uri design schemes and web style software. I’ve also been adoring web apis like Evdb.com. I’d like to do all my new projects in this style. Then I can simply write the web interface after the API is done. There are plenty of tools for that, but I’ve been having trouble finding information on developing just the web api. I’d like to present a generalized uri scheme. Feel free to disagree, but I think this provides a granular, scalable, and maintainble way to provide a web api for any data set.

URI Scheme


TODO: present this better


I’m assuming http protocol. It’s widely deployed and well understood.
Service is what kind of service is being exposed. This may be something like “maps”, “blog”, or “api”.
your website.
What do you want? Do you want to query this service? Would you like to get help on how this URI should be used? This has several benefits. In many systems that perform actions on things, it’s common to offer no-ops just to see what it might do. This is the same thing. By specifying “query”, we tell the service that it should actually perform the operation specified. Otherwise, if we say something like “help”, just give use some information about how to use this URI and what we can expect from it. Besides, this also makes your help and documentation available programmatically.
The output format. This may be something like one of:

  • json
  • html
  • xhtml
  • jpeg
  • xml
  • rdf

This way you give yourself room to grow into new formats as you might want them. I suppose this could easily be done with http headers, but doing it with http headers presents a burdern for some languages. For example, a very idiomatic way to access things in php is to use get_file_contents($url);. Anyone know how to set http headers using that function? Besides, putting the format you expect in the URI makes it nice and opaque. No surprises.

object or resource specifies what kind of things we are interested in. Might be something like articles or messages or widgets. This is what we think of when we do something like new Foo(bar); in a programming language. The foo‘s of the world. It’s the germaine records of data.
operation is the action we actually intend to perform. This is sightly redundant because our HTTP verbs duplicate some of the semantics for this. However, I believe it’s necessary to opaquely specify what granularity we are talking about. An example of an operation might be

  • new
  • modify
  • delete
  • retrieve

It will tend to be a verb. To clarify what I meant before about being granular, consider the following two cases:

  • DELETE /query/xml/articles
  • DELETE /query/xml/articles/delete#1232

Which one seems clearer? I vote for the latter. I suspect this point will find some disagreement. I plan to edit this post as necessary to reflect current thinking.TODO: put this as a page, not a blog post? Also, if you think of URI as pointers to objects, this would be the method name. So if you had var foo = new Bars(baz); foo.delete(1232);, delete is the operation name just like in the URI. Think of the operations as methods. In fact maybe I should rename operation to method.

manifest data
Have you ever noticed that when you are writing a bunch of functions, there is typically one argument to the function that is the main argument of interest? Like in the delete example just above, delete() might take other arguments. If it did these would probably be options, or an array of options. They aren’t as interesting as the id that was passed. Manifest data is the piece of information that is the most germaine and interesting piece of information. It might also be specified, if it is an ID, for example, as the fragment identifier. So think of something like /query/xml/articles/retrieve/20060901 That pretty clearly says to get the article from yesterday.
This may be the body of the message, or additional parameters need to fulfill the request. If the operation is something to be done with HTTP GET, the format for this is obvious (url encoding). If it’s not, there are more choices available, but remember that reuse improves efficacy.

If you are designing a new service, try making URI’s this way at first. You might drop me an email at bewest at gmail dot com to let me know how it goes.

Remember that this is your programmatic API, not necessarily what you expose to end users. You develop your web interface on top of this API. You can keep it private if you want, but it’s probably better to make it public. Don’t assume you know how best to present your information! The value of an information system is increased when more people use it, and by keeping your web api public, you enable other people to make your system more valuable.


One Comment

Post a Comment

Required fields are marked *

%d bloggers like this: