wwerner's blog

tutorials, tips and trivia on eclipse, osgi, web & xml technologies

Building web services on Equinox and Restlet #2

with 6 comments

Now that we’ve implemented our greeting application, it’s time to make it more enterprisey. We can’t have it just echo any greeting, can we? We’ll need to make sure that only greetings from a predefined list can be chosen as current greeting, so we can have committees that can spend time discussing and defining greeting standards.
As we want to make our lives easier (let’s assume the committee will change it’s mind every few days or so), we’ll implement a greeting manager that can be used to edit the list of approved greetings.

Beside rants at software development for The Enterprise™, expect a short introduction of the Restlet base classes that are typically assembled into a server application.


Cherry Picking

There are books 1 2 that cover Restlet, so it would be both futile and pointless to try to give you an complete overview. Refer to the Restlet documentation 3 and the books if you are primarily interested in Restlet. This post only illuminates a few concepts of Restlet that need to be understood as a foundation for the next post where we are going to wrap Restlet into Eclipse extension points.

So, what is that Restlet thing anyway? Basically, Restlet is a library that assists you to in building REST style applications 4. Restlet implements many core concepts from Roy T. Fieldings dissertation 5 directly, so if you are familiar with the REST architectural style, you’ll recognize many of the base classes of the API immediately.

The most notable concept for our purpose is the uniform interface. It allows components to to be assembled arbitrarily without revealing their internal structure to clients. Clients don’t need to realize to which kind of component they are talking to, this allows the server components to change without breaking existing clients. Real life examples are Pipes on *nix systems and – of course – the web. Your browser did not notice to which components it was talking to when you were loading this page. Chances are that there are multiple caches, a proxy and a virtual host between you and the physical storage location of this content. The browser doesn’t know about this; all it cares about is that its GET request got handled. And all components along the way know how to do that: They have a uniform interface 6.

Restlet allows for building both client and server applications. We’ll concentrate on the server side in this tutorial. The figures below are actually annotated copies from the Restlet documentation 3, filtered to exclude all elements we won’t use in this tutorial 8

RestletClasses

Since all the the classes that implement the UniformInterface know how to handle HTTP requests, we are able to assemble them very flexibly. Great, this promotes loose coupling in our application. I was tempted to include a matrix of which combinations are valid, but that is beside the point. Better think of it as a variation of the classic composite pattern 9, like this: “Everything is a Restlet (Component). There are special Restlets that can contain other Restlets (Composites).”

While the Restlet derived classes are mostly used to define the hierarchical  structure and the management of the application, the actual business data is served and updated by Resources. Resources are not part of the Restlet inheritance hierarchy but are derived from a common UniformResource base class. Uniform? Heard that before? Yes, Resources also know how to handle HTTP requests. They are the targets of a hypertext reference/URI.

Resources

To go back to the Composite pattern reference, we now also know what the Leafs of the composite pattern are: “Everything is a Restlet (Component). There are special Restlets that can contain other Restlets (Composites). ServerResources are Leafs.”

Given I understood everything correctly, I think the Restlet API could make these points more intuitive by adding a common base class for composite Restlets and by including UniformResource as leafs into the Component inheritance hierarchy. But I do not claim to have any authority on that topic.

If you are familiar with Restlet, you’ll note that this section  contains analogies that are not 100% accurate and even partly misleading. I am aware of that, but I believe thinking of in Composites is a good way to get started with the assembly of a Restlet based application. Now shoot me, or flame away in the comments. 10

Server Architecture

Back to our application. Let’s elaborate on the requirements stated in the teaser:
  • The server must able to issue a greeting
  • There needs to be a controllable list of approved greetings
  • The current greeting must be selectable by a administrator
  • An administrator needs the possibility to add and remove greetings from the list
  • The current list contents must by visible to the administrator
  • For the sake of the examples, a greeting in the list needs to have a mnemonic by which it can be found. The list of greetings is actually a map of mnemonics and greetings.
This means we’ll have two resources: A greeting and a list of greetings. The list can be modified by two operations: “add greeting” and “remove greeting”. I’ll leave setting the default greeting to you as an exercise. When we map this to an URI structure, we get something like this 11:
  • greet: issues the currently active greeting
  • manage: base for the administrative section
  • manage/list: show all greetings
  • manage/list/{mnemonic}: Display a greeting with GET, add or modify a greeting with POST, remove it with DELETE
Now what does that {mnemonic} thing in the URL mean? This is simply a variable that is part of the URL and will be extracted by Restlet. So the last URL is not a concrete URL but rather an URL template. There is a normative specification of URL templates  12 that is implemented in Restlet. URL templates are quite powerful, reading the specification is time well spent. In real life, you may want to think about exposing your domain model directly by annotating it, i.e. make resources from your model classes. This has pros and cons, but is worth considering.

Putting it together

Now that we know that we have many degrees of freedom to assemble our components, we can make the initial application from the first post a little simpler: We’ll attach the greeting Resource directly to the server without having a application a a router in between. Both can safely be removed for now.

As want to control the allowed greeting values, we’ll have to remove the @Put method in GreetingResource to disallow rouge write access.

We modify GreetingStorage to hold a map of valid greetings and allows us to add and remove greetings.

We also need to implement our new GreetingListResource. This resource fulfills three of our requirements:
  1. It displays the current greeting map content a single greeting (list())
  2. It adds a given greeting to the list (set(), via POST & a “greeting” parameter )
  3. It removes a given greeting from the list (remove())

The interesting part is how the application will be assembled: We first create a component and attach an HTTP server to it. Then we create an application containing our management section. This is – for the time being – only a container that creates a new namespace for the administration part . To this application, we attach a Router that is configured to route the requests to GreetingListResource and get the mnemonic part of the URIs.

As in the last post, the complete code is available on github 13.

Now use Poster as described in the last post with the following URLs:
3-NewList

Of course you can also DELETE  greetings:

4-Delete

Must. Resist. Urge …

… to throw in mostly unrelated OSGi stuff, but I can’t.

You’ll have noticed that the the component local variable was turned into a member variable and that a second method, stop() was introduced. Analogous to start() the stop() method of the Activator is called whenever the OSGi runtime stops the bundle.

I did this to be able to hot deploy the bundle within the running OSGi framework without having to restart the server. Sure, if I start the application from the IDE I run it in debug mode, but this won’t help when I make changes to the activator. Remember, the start() method is only called when the bundle is first loaded. As most of the application assembly currently happens there, we’d still have to restart the whole framework for the changes to be picked up.

OSGi to the rescue! One of OSGi core features is the ability to manage (start, stop, install, update) individual bundles within a running framework. OSGi describes management agents that are able to do so. Equinox ships with a management agent as a console. Let’s see how we can use that in our example.

First, we need to tell our launch config to enable the management console.

cons-1

Start the application in debug mode. In the console, you’ll see an “osgi>” prompt now. Type “ss” (for short status) and hit enter. Hey, there is our bundle.

cons-2

Remember the ID for subsequent commands. You can also use the full name of the bundle, but we’re lazy, right14?

cons-3

Let’s suppose you want to change the management URL from “manage” to “admin” 15 16.

So you change that piece of code  and check the new URL. And receive a lovely 404 because no one called the start method in our Activator. So let’s use the management console to restart the bundle: We remembered the bundle ID and just call “stop <ID>” and “start <ID>” in sequence. Now you also see the purpose of the stop() method addition above. We basically attached our components life cycle to the one of our bundle.

cons-4

Hint: Use the “help” command in the console to see if there is a shorter way to do the restart.

Now point your browser to the new URL (http://localhost:8182/tutorial2/admin/list) and be utterly astonished. It works.

cons-5

Where to go from here

You now know how to assemble Restlet applications by using Components, Applications, Routers and Resources. You have learned how to enable and use the equinox OSGi management console. From the last post, you already saw how all this can be wrapped up into a standalone application.

If you want to dive in a little deeper into Restlet, check out the great tutorials on the Restlet home page17 18 19. Some of this will be familiar. A great next step would be to learn what different Representations of a Resource are and how the content types are negotiated.

The next post will introduce equinox’ extension point/extension paradigm and remove the concrete application assembly from the Activator by using it. We’ll also tackle the hidden requirement that we didn’t implement. Can you find it?

A last word of warning: Now that you know how to create those nice looking URLs, don’t build a product and go around advertising your RESTful API, or the holy wrath of Roy T. Fielding will consume your soul 20. You (and I, for that matter) still have a lot to learn. Use the term “CRUD over HTTP” for now, even if it gives you less buzz. Seriously.

I came across the headline “Tutorials should foster thinking” in a smashingmag post yesterday. Did this tutorial make you think? Leave a comment.

  1. http://www.amazon.com/Restful-Web-Services-Leonard-Richardson/dp/0596529260?ie=UTF8&s=books&qid=1173381194&sr=8-1
  2. http://www.manning.com/louvel/
  3.  http://www.restlet.org/documentation/2.0/
  4. You’ll have figured that out by now
  5.  http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm
  6. In this case, they speak HTTP
  7.  http://www.restlet.org/documentation/2.0/
  8. Namely, these are: Clients, VirtualHosts, Filters and Redirectors. Refer to the Restlet homepage for details.
  9.  http://en.wikipedia.org/wiki/Composite_pattern
  10. Oh, and nice comments are welcome as well.
  11. Relative to our base URL, http://localhost:8182/tutorial1/
  12.  http://bitworking.org/projects/URI-Templates/
  13.  http://github.com/wwerner/EquinoxRestletTutorial/tree/post2 (There is a branch for each post/part of a post of this series)
  14. http://c2.com/cgi/wiki?LazinessImpatienceHubris
  15. You also want to do this on the live system, as it is very urgent. The steering committee found that “manage” conflicted with the corporate “Use-Of-The-Word-Management-In-Software-Application” policy and filed a change request. The request, however, got stuck in the workflow as one of the required approvers retired two years ago. By the time you got the issue on your desk, it was already delayed and suffered some serious upper management attention. Someone you report to decided to skip the tests in order to make up for the delay in spite of your protesting.
  16. No, the live system will not run in debug mode from your IDE, but give an old men the possibility to let off a little steam, would ya?
  17. http://www.restlet.org/documentation/2.0/firstSteps
  18. http://www.restlet.org/documentation/2.0/firstResource
  19. http://www.restlet.org/documentation/2.0/tutorial
  20. http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven

Written by Wolfgang Werner

April 11th, 2010 at 10:12 am

6 Responses to 'Building web services on Equinox and Restlet #2'

Subscribe to comments with RSS or TrackBack to 'Building web services on Equinox and Restlet #2'.

  1. Hi Wolfgang,

    Awesome series really! I’ve added a pointer to your posts in the Restlet’s user guide:
    http://wiki.restlet.org/docs_2.0/13-restlet/48-restlet/238-restlet.html

    Two comments:

    1) The @Put annotation should probably be replaced by a @Post in this case as the result of a PUT would be to update the whole GreetingList resource and not add a new entry.

    PUT is an idempotent HTTP method, meaning that it could by replayed several times if needed (network error) with the same final effect, clearly not the case here.

    Other than that, you’re definitely walking on the path of RESTitude :)

    2) Great point about the “Composite” parent class in the Restlet API hierarchy. I’ve though about that in the past but never came to a good formalization. I’ve entered a RFE for it:
    http://restlet.tigris.org/issues/show_bug.cgi?id=1092

    Best regards,
    Jerome Louvel

    Restlet ~ Founder and Technical Lead ~ http://www.restlet.org
    Noelios Technologies ~ http://www.noelios.com

    Jerome Louvel

    6 May 10 at 09:15

  2. Jerome,

    Valid point on @Put vs. @Post in this case, I changed it accordingly, thanks for the correction.

    I’ll follow the discussion on the Composite issue, would be great to see something like this implemented.

    Thanks for the feedback; keep up the great work on Restlet,
    Wolfgang

    wwerner

    6 May 10 at 11:13

  3. [...] the series of posts titled “Building web services on Equinox and Restlet”:  part #1, part #2 and part [...]

  4. REST does not specify whether you should use put or post or what each of those methods does. This is an HTTP W3C specification.
    http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html

    drozzy

    21 Oct 10 at 19:24

  5. Great post btw.

    drozzy

    21 Oct 10 at 19:29

  6. Drozzy,

    REST does not specify which methods to use at all, it is actually protocol agnostic.
    It does specify that you should use only the protocol’s standard methods.
    When using RESTful HTTP, this in turn means that you should use the HTTP verbs idiomatically.

    It’s all so meta.

    Wolfgang Werner

    21 Oct 10 at 19:59

Leave a Reply

I'll never publish your email address ever. However, entering a valid address is required to ensure that you're not posting spam onto my pages (because that sucks). The address is also used to display your Gravatar picture next to your comments (if you have one).