QR code

RESTful API and a Web Site in the Same URL

restful xslt xml

Look at GitHub RESTful API, for example. To get information about a repository you should make a GET request to api.github.com/repos/yegor256/rultor. In response, you will get a JSON document with all the details of the yegor256/rultor repository. Try it, the URL doesn't require any authentication.

To open the same repository in a nice HTML+CSS page, you should use a different URL: github.com/yegor256/rultor. The URL is different, the server-side is definitely different, but the nature of the data is exactly the same. The only thing that changes is a representation layer.

In the first case, we get JSON; in the second—HTML.

How about combining them? How about using the same URL and the same server-side processing mechanism for both of them? How about shifting the whole rendering task to the client-side (the browser) and letting the server work solely with the data?

The Good, the Bad, The Wierd (2008) by Kim Jee-woon
The Good, the Bad, The Wierd (2008) by Kim Jee-woon

XSLT is the technology that can help us do this. In "XML+XSLT in a Browser" I explained briefly how it works in a browser. In a nutshell, the server returns an XML with some data and a link to the XSL stylesheet. The stylesheet, being executed in a browser, converts XML to HTML. XSL language is as powerful as any other rendering engine, like JSP, JSF, Tiles, or what have you. Actually, it is much more powerful.

Using this approach we literally remove the entire rendering layer ("View" in the MVC paradigm) from the server and move it to the browser.

If we can make it possible, the web server will expose just a RESTful API, and every response page will have an XSL stylesheet attached. What do we gain? We'll discuss later, at the end of the post. Now, let's see what problems we will face:

  1. JSON doesn't have a rendering layer. There is no such thing as XSLT for JSON. So, we will have to forget about JSON and stay with XML only. For me, this sounds perfectly all right. Others don't like XML and prefer to work with JSON only. Never understood them :)

  2. XSLT 2.0 is not supported by all browsers. Even XSLT 1.0 is only supported by some of them. For example, Internet Explorer 8 doesn't support XSLT at all.

  3. Browsers support only GET and POST HTTP methods, while traditional RESTful API-s exploit also, at least, PUT and DELETE.

The first problem is not really a problem. It's just a matter of taste (and level of education). The last two problems are much more serious. Let's discuss them.

XSL Transformation on the Server

XSLT is not supported by some browsers. How do we solve this?

I think that the best approach is to parse the User-Agent HTTP header in every request and make a guess, whether this particular version of the browser supports XSLT or not. It's not so difficult to do, since this compatibility information is public.

If the browser doesn't support XSLT, we can do the transformation on the server side. We already have the XML with data, generated by the server, and we already have the XSL attached to it. All we need to do is to apply the latter to the former and obtain an HTML page. Then, we return the HTML to the browser.

Besides that, we can also pay attention to the Accept header. If it is set to application/xml or text/xml, we return XML, no matter what User-Agent is saying. This means, basically, that some API client is talking to us, not a browser. And this client is not interested in HTML, but in pure data in XML format.

POST Instead of PUT

There is no workaround for this. Browsers don't know anything about PUT or DELETE. So, we should also forget them in our RESTful API-s. We should design our API using only two methods: GET and POST. Is this even possible? Yes. Why not? It won't look as fancy as with all six methods (some API-s also use OPTIONS and HEAD), but it will work.

What Do We Gain?

OK, here is the question—why do we need this? What's wrong with the way most people work now? Why can't we make a web site separate from the API? What benefits do we get if we combine them?

I've been combining them in all web applications I've worked with since 2011. And the biggest advantage I'm experiencing is avoiding code duplication.

It is obvious that in the server we don't duplicate controllers (in the case of MVC). We have one layer of controllers, and they control both the API and the web site (since they are one thing now).

Avoiding code duplication is a very important achievement. Moreover, I believe that it is the most important target for any software project.

These small web apps work exactly as explained above: s3auth.com, stateful.co, bibrarian.com. They are all open source, and you can see their source code in GitHub.