REST is a design philosophy for designing interfaces. It emphasizes nouns (objects, resources) over verbs (actions, functions, methods). Designing the URLs of your wiki according to this philosophy makes it work well with many HTTP mechanisms.
The basic idea of REST is to only have a few universal verbs (methods), like GET, POST, PUT, DELETE, HEAD, and apply them to various nouns (resources) represented by URLs. The second important idea is the lack of state in the communication: the server deals with every request in isolation, doesn’t need to remember any previous interactions.
The HTTP protocol is the most well known example of this design philosophy in action. Many web services and mechanisms can be made very efficient thanks to dealing with REST.
In case of wikis, resources naturally map to wiki pages, but most wikis use much more verbs than HTTP does. They usually do it by adding an “action” parameter to the URL. For example, when you access the page http://example.com/wiki/SomePage, you see the contents of that page nicely rendered as HTML, but visiting http://example.com/wiki/SomePage?action=source may show you the raw source text of the page, and http://example.com/wiki/SomePage?action=edit will display a page edit form for that page. Worse, visiting http://examaple.com/wiki/SomePage?action=delete, http://example.com/wiki/SomePage?action=save or http://example.com/wiki/SomePage?action=rename may actually result in modifying the page in question (additional parameters may be required by these actions). Some engines won’t even check if these URLs are accessed using GET or POST – which is in violation of the HTTP standard, which says that the GET method should never result in changing the data on the server (other than logs and statistics, at least).
So how do we make our wikis only use the few methods provided by HTTP? Practically we are limited to only two of them: GET and POST. The other two, PUT and DELETE are very poorly supported by modern web browsers, web servers and even some intermediate software, like proxies or advanced firewalls – so we can’t really use them. The HEAD method is used for some caching mechanisms, but otherwise is not useful for us.
Obviously, GETing an URL, such as http://example.com/wiki/SomePage, should result in displaying this page. Rendered as HTML and all that, with links to other pages. We can use POST to the same URL for saving the new page content, but first we need to display an edit form somehow. Some simple wikis will just display the edit form on every page, under the rendered content – this is an interesting approach, but not particularly elegant. We need something better.
Come to think of it, an edit form is not really an action – it’s rather an alternate format of the page. HTTP has a mechanism for requesting the resource in various formats: we just send and “Accept” header in our request, listing the MIME types that we expect to receive. Two problems with that:
So we need to make the editor a separate resource. It actually makes sense, it’s not merely a different format, it’s a whole different view, with additional functionalities: the save button, for example.
So let use have http://example.com/wiki/SomePage for the page itself, and http://example.com/wiki/SomePage/editor for the editor, http://example.com/wiki/SomePage/raw for the raw source, etc. We can save by doing a POST on the editor – this lets us have some forms or something on our regular pages, for example used for some macros.
But is it any better? Not really. For example, I use the “raw” view for serving the CSS style from a page, and also for linking to images stored as wiki pages. To link to an image from inside a stlye sheet, I need to use something like this: url(../image.jpg/raw). Not nice or particularly convenient. It doesn’t also solve the other problem that non-RESTful wikis have: the robots.txt rules are useless, except for blocking particular pages, which is a rare case – you usually want to block particular views or actions.
So, let us change the order of elements in the URL: http://example.com/wiki/editor/SomePage. This is a much better solution! Not only I can link to images from my style sheet with simple url(image.jpg), not only I can block the /wiki/edit path in the robots.txt file, but I can also set a password on them, cache some of them, or even put some of them on a separate server! All this with simple server configuration, without any need for rewrite rules or complicated dispatcher programs.
This also works for some “global” views, like the RecentChanges or PageIndex page – no need to implement them as macros or special pages, just make them into views.
There are several problems with having the “view” name before the page name. Either you have to always have that view name, or you cannot have pages named the same as the views. Actually, you could treat the first segment as a page name when there is no second segment – this would require that you add a trailing slash to the “global” views, like RecentChanges though.
Some broken web serves will not provide a PATH_INFO variable – so you are forced to use the ugly PHP-like solution with “?”.