Lab 2: Developing REST Services

Presenter Notes

Schedule of This lab

2:00 — 2:15
Part 1: Handling HTTP requests
3:00 — 3:10
Coffee break
3:10 —
Part 2: Designing a REST Web-Service

Presenter Notes

Part 1: Handling HTTP requests

Presenter Notes

HTTP requests

GET rfc5023#section-10 HTTP/1.1⏎
Host: tools.ietf.org⏎
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:9.0.1) Gecko/20100101 Firefox/9.0.1⏎
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8⏎
Accept-Language: en-us,en;q=0.5⏎
Accept-Encoding: gzip, deflate⏎
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7⏎
Connection: keep-alive⏎
If-Modified-Since: Mon, 09 Jan 2012 22:47:46 GMT⏎
If-None-Match: "1827ba7-21df5-4b6202feb4880;4b6ff84c9e6cf"⏎
Cache-Control: max-age=0⏎
⏎

Presenter Notes

Starting a server

public static void main(String[] args) throws Exception
{
        // Setup the server
        Server server = new Server(8080);
        server.setHandler(new SimpleResourceServer());
        server.start();
        server.join();
}

Presenter Notes

Handling requests

public class SimpleResourceServer
  extends AbstractHandler {

  public void handle(String target,
                    Request baseRequest,
                    HttpServletRequest request,
                    HttpServletResponse response) {
  }

  ...

Presenter Notes

Handling requests

public void handle(String target,
                  Request baseRequest,
                  HttpServletRequest request,
                  HttpServletResponse response) {

  //Check whether we can handle request

  //Handle the request and write the output to response

  baseRequest.setHandled(true);
}

...

Presenter Notes

Accept Headers

RangeMatcher<MediaRange> acceptMatcher =
    new RangeMatcher<MediaRange>(new MediaRangeParser());

acceptMatcher.registerKnownType("text/plain");
acceptMatcher.registerKnownType("application/xml");

String request = "text/plain;q=0.5,text/html";
System.out.println(acceptMatcher.getBestMatch(request));

//Displays text/plain

Presenter Notes

Questions

Presenter Notes

Part 2: Designing REST Web-Services

Presenter Notes

Context

Design a RESTFul web service to manage a list of contacts. This service exposes its data as Atom feeds.

Contacts have a first name, a last name, a name used for display, and an email address.

Contacts can be associated with different groups.

Presenter Notes

AtomPub

AtomPub is a recommendation that defines a protocol for publishing and editing Web Resources. The protocol is based on HTTP transfer of Atom-formatted representations.

This short introduction does not cover every single concept.

Check RFC 5023 for details.

Presenter Notes

Entries

Analogy: Blog post

  • Metadata (id, title, author, etc.)
  • Links (edit, self, etc.)
  • Categories (analogy: tags)
  • Content

Represented as atom entries.

Support GET, PUT, DELETE

Presenter Notes

Collections

Analogy: Blog

  • Metadata (id, title, author, etc.)
  • Links (e.g. next page)
  • Entries, possibly shortened with edit link.

Represented as atom feeds.

Support GET, POST

Presenter Notes

Service Document

Entry point of the service

  • Different workspaces
  • Each points to different collections
  • Restricts the content-type and categories of entries

Presenter Notes

AtomPub

assets/doc.svg

Presenter Notes

Exercise 1

Goal: designing the contacts list REST Service.

That is, mapping the resources to URIs and semantics.

E.g.

Resource Path Method Semantics
Root / GET Retreives the contacts collection

Presenter Notes

Entries with Abdera

final Entry entry = Abdera.getInstance()
        .getFactory().newEntry();

entry.setTitle("Title);
entry.setEdited(new Date());
entry.setId("id:1234567890");
entry.addLink("http://example.org/", "edit");
entry.addLink("http://example.org/", "self");

Presenter Notes

Collections with Abdera

final Feed contactsFeed = Abdera.getInstance().
    getFactory().newFeed();

contactsFeed.setTitle("My Feed");
contactsFeed.addLink("http://www.example.org/", Relations.SELF);
contactsFeed.setId("id:0987654321");
contactsFeed.setUpdated(new Date());

contactsFeed.addEntry(entry1);
contactsFeed.addEntry(entry2);
contactsFeed.addEntry(entry3);

Presenter Notes

JAX-RS

Java specification for defining REST-style services

@Path("/a/b/c/resource")
public class ResourceImpl {
    @GET
    @Produces("text/plain")
    public Response getSomething() {
        final String resp = "Hello";
        return Response.ok(resp).build();
    }

Presenter Notes

JAX-RS

@PUT
@Produces("text/plain")
@Consumes("text/plain")
public Response getSomething(final Reader data) {
    //Read from data

    //Build a response
    final String resp = "Hello";
    return Response.ok(resp).build();
}

Presenter Notes

JAX-RS

@Path("/a/b/c/resource/{variable1}/{variable2}")
public class ResourceImpl {

    @Get
    @Produces("text/plain")
    public Response getSomething(
        @PathParam("variable1" final String var1)
        @PathParam("variable2" final String var2) )
    {
        //Build a response
        final String resp = "Hello " + var1 + var2;
        return Response.ok(resp).build();
    }

Presenter Notes

Exercise 2 & 3

  • Resources are automagically fetched from the be.ac.ulb.code.wit.resources namespace. Look at the existing ServiceDocument.java for an example (see also jsr 311)
  • Contacts and groups serialization helpers in be.ac.ulb.code.wit.resources.serializers.

Presenter Notes