REST Client calls with Scala and Jersey (JAX-RS)

[UPDATE] this post is really old. I’ve written a new one: klick [/UPDATE]

Usually client calls to Jersey (see API) are looking like this:

1
2
3
4
5
6
...
WebResource resource = client.resource(baseURI);
Units units = resource.path("units/" +
                      id).accept(MediaType.APPLICATION_XML).
                      get(Units.class);
...

Using many different HTTP method calls with changing paths is sometimes not very concise. Scala provides the possibility to use closures in a very elegant way.

I wanted to reduce the code to the relevant things and to support an easy to read method. It lead me to:

1
2
3
4
5
6
7
8
...
  private final implicit val basePath = UNITS_RES_PATH
  def setStatus(id:String):Units = {
    rest {
      _.get(classOf[Units])
    } path (id)
  }
...

The implicit variable basePath is used to create a default path to the Resource that is relevant for all REST calls. It has only to be set once in the scope of the method (f.e. in a base class or as class property). The method parameter id is used to append the id string to the default path.

It is much more obvious what the code is doing, right?

Additionally you can put some common exception handling code into the path method to throw an exception or other things.

Here is the (not perfect!) code that provides this functionality:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class ClientBaseClass {
...
  protected def rest[A](body: (WebResource#Builder) => A): DoRestWithPath[A] =
          new DoRestWithPath[A](body)
 
  protected class DoRestWithPath[A](body: (WebResource#Builder) => A) {
    def path(path: String = null)(implicit basePath: String): A = {
      var p = path
      if (basePath != null)
        p = basePath + (if (path != null) path else "")
 
      if (p != null)
        body(resource.path(p).accept(MT).`type`(MT)).asInstanceOf[A]
      else
        body(resource.accept(MT).`type`(MT)).asInstanceOf[A]
    }
  }
...
}

BTW: The best REST implementation is here

Comments are closed.