CS639 Class 24 Chap 5. Hypermedia Service

PA4 Intro: Expanding orderService, or client to orderDap

From pa4.html:

We will add a payments and receipts to orderService, to make it follow Fig. 4-1 and more exactly, Fig.  5-9, which shows the additional resources involved. The orders go through states UNPAID, PREPARING, READY, and TAKEN. We won’t use the hypermedia approach however. In addition, we will use another set of resources under /catalog/... to specify the menu options, specified after class discussion.

New services over those in orderService:

·                              POST /order/{orderId}/payment    to pay for this order, receipt is returned, with URI /order/{orderId}/receipt

·                              GET /order/{orderId}/receipt

·                              DELETE /order/{orderId}/receipt  to finish

This groups everything for an order together in URI-space, and uses hierarchy, so you can try out subresources (not required.)

Supplied project orderDap, the hypermedia REST service described in Chap. 5 is available in a form that works with tomcat.

Fig. 5-4 and 5-5 shows the app for Chap 5, what we’re trying to do here, with slightly different URIs, and no hypermedia

POST  /order                 creates new order, status UNPAID

PUT /order/1234          update UNPAID order, fail if another status

DELETE /order/1234   cancel order, succeeding only if UNPAID

Pa4 variant on payment URI:

POST /order/1234/payment   submit payment, succeeding only if order is UNPAID; order becomes PREPARING, returning receipt

POST /poke                  make oldest PREPARING order READY (barista finished work)

GET  /order/1234/receipt    get copy of receipt, if order is PAID

DELETE /order/1234/receipt    if order is READY, make it TAKEN: complete the order

GET /order/1234        return order with current status

DELETE /order        delete all orders (is in orderService but not in orderDap, but should be)

 

We’re using POST instead or PUT for payments so wget can do it.

POST /poke was added for cs639.  It is an “admin” action.

orderDap and Chap. 5

Fig. 5-5: slightly different names for states, and “cancelled” is not a state of order. The order is removed from the repository in this case.

Also, orderDap uses GUIDs for ids, much longer than 1234. I simplified this for orderService.

Consider the orderDap sources. Note these additions over orderService

resources: PaymentResource, ReceiptResource  (as first-level resources)
representations: PaymentRepresentation, ReceiptRepresentation, for XML
domain: Payment is new, OrderStatus has 4 values, note no Receipt object here:  a receipt can be generated from a Payment object
activities: PaymentActivity, ReadReceiptActivity, CompleteOrderActivity, exceptions for them
repositories: PaymentRepository: just copy this

Where’s the hypermedia here?

Recall the basic idea that hypermedia means responding to each service request with not only the answer but also a description of what can be done next by the client, specifically by listing URIs for such next steps.

See handout on the Hypermedia service

The Hypermedia service of Chap 5 has a DAP, a domain application protocol

The following XML is returned by “ant restAdd” in orderDap, and put in file order-response.xml. The order id here is 2a3fcd5c-0aef-41cf-9ebd-0b7de5d88382, not 1234.The constant strings are in lowercase here, because of additional markup in the enum classes.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
        <ns2:order xmlns="http://schemas.restbucks.com/dap"
                   xmlns:ns2="http://schemas.restbucks.com">

   <link mediaType="application/vnd.restbucks+xml"
        uri=http://localhost:8080/orderDap/rest/order/f0001d50-e244-4068-84f6-73b800244964
        rel="http://relations.restbucks.com/cancel"/>

         <link mediaType="application/vnd.restbucks+xml"

uri="http://localhost:8080/orderDap/rest/payment/f0001d50-e244-4068-84f6-73b800244964"

rel="http://relations.restbucks.com/payment"/>

         <link mediaType="application/vnd.restbucks+xml"

uri=http://localhost:8080/orderDap/rest/order/f0001d50-e244-4068-84f6-73b800244964 rel="http://relations.restbucks.com/update"/>

  <link mediaType="application/vnd.restbucks+xml"

uri="http://localhost:8080/orderDap/rest/order/f0001d50-e244-4068-84f6-73b800244964"

rel="self"/>

         <ns2:item>

              <ns2:milk>semi</ns2:milk>

              <ns2:size>large</ns2:size>

              <ns2:drink>cappuccino</ns2:drink>

         </ns2:item><ns2:location>takeaway</ns2:location>

         <ns2:cost>2.0</ns2:cost>

         <ns2:status>unpaid</ns2:status>

</ns2:order>

Notes:

We see 4 <link>s, one for each action that the user could take after ordering: cancel, pay, update, plus one for “self”.

Since the URIs are generated dynamically, the uses of localhost, etc. are replaced in a real service installation by proper server URIs.

Each link has an attribute rel=name, giving a name for the type of link this is, and a URI.

The hypermedia links don’t themselves say what HTTP verb to use with the URI, or what XML data (or other representation) is expected.

The rel value, along with the current URI, is used to look up what HTTP verb to use, (and representation format) in (unsupplied) metadata for the service.

These links are like Atom links. Example: pg. 198, in Chap. 7, the Atom Syndication Format.

This XML has two namepaces:

ns2:  prefix for “http://schemas.restbucks.com”, the NS we are using in orderService

default: no prefix for "http://schemas.restbucks.com/dap"  the NS for the DAP links

There could be schemas for these namespaces, but none are shown in the book.  Since the orderDap project is implemented in Jersey, we can get schemas from the server for the POJOs that are handled directly by Jersey.  Look at schemas next time.

Pg. 116 has similar XML, but better prefixes. With more annotations, we should be able to specify our prefixes, like dap: for the DAP NS, but my attempts at this worked only for prefixes in the schemas, not in the generated XML, so JAXB is still in-progress (or possibly I need to upgrade to a newer JDK).

This XML is POSTed with Content-Type header of application/vnd.restbucks+xml, the media type for this service. More on this later.

Following the DAP by looking at the message responses and their links

Example 5-8, Pg. 118 has Payment response with only two links: for another order or for a receipt. The next normal step has to be done by the barista, so the customer doesn’t have much to do at this point.

Example 5-9 shows what you get back if you follow the receipt link.   Now the only way forward is back to the order, to find out how it’s doing.

Example 5-10 shows that the links from order are really dynamic: if the order is “preparing”, there’s nothing to do but ask again for its status.

Metadata for Hypermedia Services and Vendor-specific media types

Now all this hypermedia XML assumes the client knows how to use a <link>  but this <link> is not really a WWW standard (though it looks a lot like an Atom link).  How can the client get started, other than guessing?

This is not entirely answered in Chap. 5, but there are pieces of the puzzle.

The service does serve out WADL, but it’s not complete.  However, it does say that requests and responses for most resources will be of mediaType “application/vnd.restbucks+xml”, which warns the clients that there is a vendor-specific mediatype in use, so they need to find out about it. It also gives the base URI for the service, so you know it’s associated with some particular web address. Of course you needed that to get the WADL, normally.

The WADL is also supplying XSD.  So it’s some help, but it’s not really meant for hypermedia services, since it gives out URI templates for direct access to various resources, rather than expecting them to be determined dynamically by links in responses.

But WADL isn’t in very active use anyway.  For example, Amazon S3 doesn’t provide it.

Back to Fig. 5-2, pg. 109 to look at the big picture.  We see Media type at the top, with schemas and Link relations and Processing models.

Media types are defined on pg. 103, as the server’s preferred scheme for interpreting the representation (i.e, the XML in our case) sent or received by a service.

The Processing models describe possible flows from one app state to another, where the Links show how we can go out from a particular state, each with its “rel” name and possibly associated schema. Here we would find out what schema is needed for a “payment” transition.

The app state here is mainly defined by the order and its status, and the order is the resource for a certain URI, but there is also a corresponding payment resource that is more app state, and has its own URI/unique id. The receipt has another URI, but it has no independent state: it’s just a reflection of the other resources.

The media type is using URIs as just identifiers, not HTTP-specific names.  The media type has to be combined with a Protocol before anything can actually happen. 

A Protocol specifies not only media types, but also HTTP verbs and entry-point URIs. In particular, it supplies a map from rel values to HTTP verbs to use.  Here is where we find out that the “rel” name “payment” needs to use PUT.

Nice pic, but no actual metadata to show it in action.  I think this is mainly a call for action, though they do give references to two existent languages related to the diagram.

Vendor-specific media types

Anyway, the use of vendor-specific mediaTypes is more general. From Wikipedia Internet media type

For example

application/vnd.google-earth.kml+xml for Google Earth KML data

application/vnd.ms-excel for old-style Excel data

There is a media type registry at IANA (this is the application part). IANA runs the domain name system.  The entry for google-earth has a link to a doc on it. The one for ms-excel has an email from 1996 for the registration.

Unfortunately, there is no standard way to go from the mediaType to a current description of it, other than web search (though this should work pretty well)

Note that the media type is usable for more than HTTP, for example email protocols using SMTP, so keeping the HTTP-specifics out of the media type has a purpose.

Specifying a Protocol Processing Model

How to describe a protocol?  Good question.  Can use FSMs (finite state machines).

In the .NET section, the authors show a DSL (domain-specific language) for the protocol. They devised this language, so it’s not specifically related to .NET. This is another way to describe a protocol. See Examples 5-26 and 5-31 if interested.

In the “enterprise world”, WS-BPEL (Web Services – Business Process Execution Language) is a framework for describing such workflows, but it is SOAP-centric.

Implementation

We can use JAXB to generate multi-NS XML, with attributes...

To simplify annotations, packages representations and domain both have package-info.java setting up the non-DAP NS as default, so we only have to override it for the DAP NS

The annotations have been simplified relative to the orderService ones, and propOrder annotations added, to show a good application setup.

Handling Attributes in JAXB: pretty easy

Class Link, in package representations, has fields rel, uri, mediaType, turned into XML attributes as follows:

@XmlRootElement(namespace = Representation.DAP_NAMESPACE)

// make sure the schema type is in the same namespace as the element itself

@XmlType(name="link", namespace = Representation.DAP_NAMESPACE, propOrder = {

            "rel", "uri", "mediaType"})

 

public class Link {

    @XmlAttribute(name = "rel")

    private String rel;

    @XmlAttribute(name = "uri")

    private String uri;

 

    @XmlAttribute(name = "mediaType")

    private String mediaType;

...

 

We see the DAP NS being specified for the class and the type, overriding the default set up in package-info.java for this package. Alternatively, we could put Link.java in its own package with a package-info specifying the DAP NS.

The message-level POJOs: OrderRepresentation, PaymentRepresentation, and ReceiptRepresentation, all extend Representation

Class Representation sets up a List<Link> field so that each subclass can have its own number of Links as needed, or even a variable number of links as needed (recall OrderRepresentation having 4 at the start and none at the end). Since there is a List<Link> here, there will be a sequence of link elements, each with attributes as specified above, and the link elements are in the DAP NS.

public abstract class Representation {

    public static final String RELATIONS_URI = "http://relations.restbucks.com/";

    public static final String RESTBUCKS_NAMESPACE = "http://schemas.restbucks.com";

    public static final String DAP_NAMESPACE = RESTBUCKS_NAMESPACE + "/dap";

    public static final String RESTBUCKS_MEDIA_TYPE = "application/vnd.restbucks+xml";

    public static final String SELF_REL_VALUE = "self";

 

    @XmlElement(name = "link", namespace = DAP_NAMESPACE)

    protected List<Link> links;

 

    protected Link getLinkByName(String uriName) {

        if (links == null) {

            return null;

        }

 

        for (Link l : links) {

            if (l.getRelValue().toLowerCase().equals(uriName.toLowerCase())) {

                return l;

            }

        }

        return null;

    }

}

 

Each Representation class extends Representation, so it gets the List<Link> by inheritance. Note

Example: OrderRepresentation.java:  the orderService structures are in the old namespace (because of the package-info setup), but now it additionally has a List<Link> from its superclass, using DAP NS.

@XmlRootElement(name = "order")

@XmlAccessorType(XmlAccessType.FIELD)

@XmlType(name = "orderRepresentation", propOrder = {

           "items",

          "location",

          "cost",

          "status"

      })

public class OrderRepresentation extends Representation {

    @XmlElement(name = "item", required = true)

    private List<Item> items;

 

Pg. 152, end of Chap. 5, says we now have “all the elements at our disposal to build RESTful services”.

But we would like to understand the schemas too, not covered in the book.