Bill the Plumber

Software plumbing using middleware wrenches

  • My New Book

  • Recent Posts

  • Categories

  • Archives

Archive for the ‘REST’ Category

New HornetQ REST Interface

Posted by billburke on August 9, 2010

After being distracted a lot with RESTEasy releases over the past few months, I finally have something usable (and more importantly, documented) for the HornetQ REST Interface I’ve been working on.  The interface allows you to leverage the reliability and scalability features of HornetQ over a simple REST/HTTP interface. Messages are produced and consumed by sending and receiving simple HTTP messages containing the XML or JSON (really any media type) document you want to exchange.

Other than being buzzword compliant here are some of the reasons you might want to use the HornetQ REST Interface:

  • Usable by any programming language that has an HTTP client library.
  • Zero client footprint. We want HornetQ to be usable by any client/programming language that has an adequate HTTP client library. You shouldn’t have to download, install, and configure a special library to interact with HornetQ.
  • No envelope (i.e. SOAP) or feed (i.e. Atom) format requirements. You shouldn’t have to learn, use, or parse a specific XML document format in order to send and receive messages through HornetQ’s REST interface.
  • Lightweight interoperability. Since interactions are RESTful the HTTP uniform interface provides all the interoperability you need to communicate between different languages, platforms, and even messaging implementations that choose to implement the same RESTful interface as HornetQ (i.e. the REST-* effort.)
  • Leverage the reliability, scalability, and clustering features of HornetQ on the back end without sacrificing the simplicity of a REST interface.

HornetQ REST Features

  • Duplicate detection when producing messages
  • Pull and Push consumers
  • Acknowledgement and Auto-acknowledgement protocols
  • Create new queues and topics
  • Mix and match JMS and REST producers and consumers
  • Simple transformations

Visit the HornetQ REST Interface web page to find links for downloading and browsing docs, source code, and examples.

Posted in JAX-RS, REST, REST-star, RESTEasy, hornetq | 3 Comments »

RESTEasy 2.0.0 Released!

Posted by billburke on July 19, 2010

Our first major release of 2010.  After a bunch of betas, I’m pleased to announce that RESTEasy 2.0.0.GA has been released.  A lot of work within the RESTEasy community has been done to improve on our last successful GA.  Follow the links from the RESTEasy website to download the new release.  Special thanks to Jozef Hartinger for the CDI integration, Eoghan Glynn for fixing a bunch of bugs, Stef Epardaud for the new Javascript client, and many others for their continuing support.  Some highlights:

  • CDI Support
  • Spring 3.0 Support
  • TCK 1.1 Compliance
  • Async Servlet 3.0 Support
  • A new Javascript API.  A javscript servlet scans JAX-RS deployments and generates Javascript code that can be downloaded that can be used as stubs.
  • Relicensed under ASL 2.0.  We switched to be compatible with HornetQ and Drools as we’re developing REST interfaces for these guys.
  • Tons of bugfixes and performance improvements reported by the community over the past 8 months.

Browse our release notes for the last few betas to look at all the bugs and features implemented.

The upcoming JBoss AS 6-Milestone 4 release will also have deeper integration with RESTEasy so that you can do automatic scanning, EJB injection, CDI injection, etc.  All the stuff you’d expect from a JAX-RS integrated EE 6 solution.

Posted in JAX-RS, REST, RESTEasy | Leave a Comment »

REST core values

Posted by billburke on April 12, 2010

REST attempts to answers the questions of: What properties of the web have made it so successful?  How can I apply these properties to my applications?  While REST is simple, it takes awhile to figure out how to follow this architectural style effectively when designing distributed interfaces.  REST promises greater decoupling, change resistance, and scalability if its principles are followed.  The thing is though, for anybody not fresh out of school, we’ve heard these types of promises again and again over the years made by various industry efforts: DCE, CORBA, WS-*, and insert-your-favorite-distributed-framework.   While the success of the Web leads me to believe that REST principles are strong, there has to be something more fundamental that it promotes or we’re never going to break the cycle of complex, bloated, infrastructure runtimes.  That’s why I’ve adopted a set of core values for myself when writing RESTful interfaces.

Simplicity

Perhaps the most important reason why developers initially are attracted to REST is that, at its core, REST is very simple HTTP interactions.  A good restful service can be understood simply by looking at the messages that are exchanged.  If you were around in the early days of the web, did you look at HTML source to learn how a specific website wrote their page?  Same applies to RESTful web services.

Zero Footprint

To write a RESTful web service all you need is a platform that can web requests.  You can write restful services using Apache+CGI+(python/php), Servlets, JAX-RS, Restlet, Rails, Grails, whatever.  From a client perspective, all you need is an HTTP client library.  While frameworks can make you more productive, just using an HTTP client library is practically productive enough.

Lightweight, true, interoperability

Have you ever had trouble getting two different CORBA or SOAP vendors to interoperate?  What about getting two different versions of the same vendor’s CORBA or WS-* stack to interoperate?  These are common problems that happen every day with traditional stacks.  Because REST focuses on exchanging representations through ubiquitous protocols like HTTP, these interoperability problems, on the protocol level, pretty much don’t exist.  HTTP is everywhere and well supported.  HTTP content negotiation allows clients and servers to decide, at runtime, what formats they want to exchange.  REST+HTTP removes the vendor interoperability problem and allows developers to focus on application integration.

Frameworks for productivity, not for coupling

REST frameworks should help with developer productivity and not create a lockin between the client and server that requires the framework’s runtime be installed on both sides of the pipe.  I feel this will lead to interoperability problems and complexity.

I’ve been yelled at before for stating my core values on why REST is important to me.  I think I was misunderstood.  I think there’s a distinction between what you want to accomplish and how you accomplish it.  Right now REST is the how, and my core values are the what.  Also, these core values are why I’ve been skeptical openly about things like WADL, Atom, RDF, and PATCH and why I’m nervous about how transactions are going to turn out in our REST-* effort.  After all these years, its so important to get things right.

Posted in REST | 2 Comments »

Possible iteration on avoiding duplicates

Posted by billburke on April 2, 2010

Draft 5 of REST-* messaging talked about iterating on the reliable posting protocol.  Recently, I was arguing with Jan Algermissen on a completely unrelated subject.  As a result of this conversation, I ended up re-reading Roy’s post on hypermedia for the 4th time in 2 years. Re-reading Roy’s blog got me thinking a bit about improving the message posting protocol of REST-* Messaging so that it is driven more by in-band information, rather than out-of-band information.

Firstly, I want to remove the post-message-once and post-message link relationships.  Instead, a destination resource would only publish the create-next link.  When a client wants to post a message to a queue or topic, it will use this link to create a new message resource on the server.    The type of this link would be “*/*” meaning it accepts any media type.

The key change to the protocol would be for the client to be aware that responses to creating messages through a create-next link may contain a new create-next links.  The client is encouraged to use these new, on-the-fly, create-next links to post additional messages to the topic or queue.  An important point of this change is that the server is not required to send a create-next link with its responses.  How, and if, the server protects itself from duplicate message posting is up to the server.

So how could the server protect itself from duplicate message posting?  One implementation could be that the server returns a 307 response code, “Temporary Redirect” for the initial POST to the static top-level create-next link published by the destination resource.  This 307 requires the client to re-POST the request to a URL contained in a response Location header as defined by the HTTP 1.1 specification.  The Location header would point to a one-off URL (like the previous protocol defined in Draft 5).    If a network failure happens, then the client re-POSTs to this  URL.  If the messages was previously successfully processed by the server, the server would respond with a 405, Method Not Allowed.  If no network failure happens on the re-POST from the 307 redirection, then the server would just return a success code.  In either response, the server would also return a new create-next link as a Link header within the response.  The client would use this new create-next link to post new messages.  Subsequent posts to these new links would not have to go through the re-direct protocol because they would be newly generated one-off URLs.

I have been reading a bit that some weird or undesirable behavior may be experience with some user agents when using 307 and POST/PUT.  So, I think that if the REST-* Messaging specification leaves it undefined how a server implementation handles the initial response of a duplicate-message protection protocol, we can let it evolve on its own.  The key here is that the client should be encouraged to look within the response for new create-next links even from error responses.  For example, if instead of 307, the initial POST return a 415, Preconditions Failed and that error response contained a create-next link header, the client should use that link to re-post the request.  NOTE!  I think 307 is probably the best implementation, but maybe its best to give flexibility to implementors.

Keep the *-batch links

I still want to have separate links for submitting batches of messages.  Specifically rename post-batch to create-next-batch (and remove post-batch-once).  I want the distinction so that the server knows that it is receiving a collection of messages vs. the server just forwarding a message to message consumers that just happens to be a collection media type.

Posted in REST, REST-star | 1 Comment »

Links instead of PATCH

Posted by billburke on April 1, 2010

Here’s some random thoughts I’ve had about REST while interacting with commenters on my previous blog.  Please, please, they are just thoughts, not rules of thumb I’m taking on.  Some things to think about and ponder…

Use Links instead of PATCH

The idea of using the new PATCH HTTP operation makes me squeamish.  I’m not sure why, but intuitively I don’t like it.  Maybe its because so many semantics can be hidden behind it?  Maybe its because a user is going to have to read a lot of documentation to understand how to interact with it?  I think I’d rather use links instead.  Let me elaborate.  Consider this customer XML document:

<customer>
   <first-name>Bill</first-name>
   <last-naem>Burke</last-name>
   <address>
       <link rel="edit" href="/customers/333/address" type="application/xml"/>
       <street>...</street>
       ...
   </address>
   <billing-address>
       <link rel="edit" href="/customers/333/billing-address" type="application/xml"/>
       ...
   </billing-address>
...
</customer>

If you were using links instead of PATCH, doing a GET on a specific customer resource returns you a document that pretty much describes to you how to interact with it.  The “edit” link elements under address and billing-address let you know that you can partially edit the document without having to refer to any user documentation (or yuck, and WADL document) on whether PATCH is supported or how you use PATCH on the resource.

Posted in REST | 28 Comments »

RESTEasy 2.0-beta-2 released

Posted by billburke on March 31, 2010

I don’t usually blog about beta or RC releases, but people have had a few problems with Apache Client 4.0 integration with RESTEasy, specifically, a bunch of connection cleanup bugs.  I have fixes those bugs reported for this.  Also, this release ran successfully against the JAX-RS 1.1 TCK.  I had to make a bunch of encoding fixes here.

You can download from the usual places.  Go to our home page for more info.

Posted in JAX-RS, REST, RESTEasy | 1 Comment »

Modeling operations in REST

Posted by billburke on March 25, 2010

A Red Hat Colleague of mine, Bryan Kearney,  recently solicited my advice about a RESTful interface his team was creating for an entitlement system being used for our products.  Here’s what he wrote to me:

The project is called Candlepin, and it is an entitlement engine. You can see it at https://fedorahosted.org/candlepin/ and the code at http://git.fedorahosted.org/git/candlepin.git/. We are using RESTEasy as the engine, and I would say our API is at gen 2. We are no longer doing too much RPC style calls.. but are not yet doing a HATEOAS API.

Our current quandry is around how to model state trnasitions on resources. We have seen a couple of possible approaches, and none leaps out as a best practice yet.

Asssume I have a Consumer who has entitlements. The entitlement resource is really the relationship between the consumer and a product they have purchases. Today, we model this as:

GET /consumers (Gets all)
GET /consumers/{UUID} (Gets a Consumer)
GET /consumers/UID/entitlements (Gets the entitlements for a consumer)
GET /entitlements?consumer={UUID} (Gets the entitlements for a consumer)

if we terminate a consumer, we want to terminate all his entitlements. We also think that we will not want to delete objects from the DB, and instead just filter out the terminated.

Approach 1
———-
First approach is to PUT /consumers/{UUID} the full consumer object with a new state. The method would then look for state changes and do the needful. This seems the most Hateoas-ey

Approach 2
———-
Since we know we wont want to delete objects, we could hijack

DEL /consumers/{uuid}

And not really delete, just terminate. This seems kinda hackey.

Approach 3
———–
Approach 3 would create “action” links. We would therefore support

POST /consumers/{uuid}/terminate

and do the termination logic there. This would mean that the POST to /consumers/{uuid} would be pure object update only. This seems very RPCish

Approach 4
———–
The final one would be to support both

/consumers/
and
/inactiveconsumers/

So.. a

DEL /consumers/{uuid}

would allow me to now do a

GET /inactiveconsumers/{uuid}

We had a bit of an email exchange, but here’s the advice I gave him summarized.

Have your clients consume links, not a URI scheme

Modelling URI schemes is an implementation detail.  You need to do it when designing your application and then finally implementing it because the URI scheme of your restful web services has a huge affect on how they work.

BUT, URIs are an implementation detail of your restful web services.  URIs should be almost completely opaque to your clients.  Instead only one top-level resource’s URI should be published to the outside world.  Representations of this root URI should have links (or link headers) embedded within them to publish other entry points into your suite of web services.  Why is this important?

  1. Location Transparency.  Lets give an analogy.  If you were writing a CORBA, Java RMI, or SOAP based application, would you publish each and every endpoint to the client?  No, you would not.  You would use a Naming service or UDDI to register a logical name for your endpoints.  A client would go to this naming service to obtain the location of your object/service.  Another analogy is, how do you interact with your browser?  You read an HTML page and click on a word that is underlined as a link to go to a new document.  You don’t cut and paste the actual URL in your browser window to go to another page.  The same thing should happen with your web services.
  2. Clients become immune to URI scheme refactorings. Over time as your services evolve, you may want to change how the URI schemes are modeled and defined.  If your clients are using a harded coded URI scheme and you change it, you’ve broken all clients that are using the older scheme.  Links protect clients from refactorings and allow server developers the freedom to refactor to their hearts desire.

Avoid changing the meaning of an HTTP verb: specifically DELETE

I would like to preface this with I used to think the approach Bryan preferred was the best approach.  His preferred approach was to have DELETE change the state of a consumer to make it inactive.  IMO, this is changing the meaning of delete.  Instead of removing a resource, which is what DELETE was designed to do, DELETE (in his example) is actually changing the state of a resource.  This is bad, IMO.  So what approach did I recommend from his list?  Approach 3.

Use links to model operations (Approach 3)

I prefer Approach3.  While it smelled RPCish to Bryan, IMO, it is not, if you model it correctly using link relationships.  For example:

GET /consumers/{UUID}
would return.

<consumer id="333">
   <name>Bill</name>
   ...
   <atom:link rel="terminate" href="/consumers/333/terminate"/>
</consumer>

The href here is *IRRELEVANT*.  URI’s should be opaque to the client (just as they are opaque when a human surfs the web through a browser).

Think of a link almost as a form.  When you get the representation of the consumer, the atom:link elements act like forms.  They tell client of possible state transitions, what representational information is expected, and what URL to post the representation too.

Having terminate as a link gives you a lot of flexibility.  1st iteration of the link might be an empty POST.  2nd iteration you might want simple form parameters to specify the parameters of the termination.   3rd iteration you might define a actual media type for termination.  Because termination is now a resource you can store this type of information there and link it within your consumer representation.

Another interesting thing that can be done is to publish (or not publish) different links based on the state of the resource.  For example, if a consumer in Bryan’s service has been terminated, a GET of that consumer resource might publish a “reinstate” link and remove the “terminate” link.

But isn’t this RPCish? No, it is not.  Why?  Well, think how you would implement something like this through an HTML/browser-based UI.  How would you model terminate in this situation?  From the consumer HTML page you would either have a link that brought you to a page with a HTML Form you had to fill out to terminate the consumer, or, the consumer HTML page would have a mini form that terminated the consumer.  In each case, the form would point to a specific URI that handled the state transition.

There’s some other interesting aspects that came out of my dialogue with Bryan, but I’ll save those for another blog.  Thoughts?  Do you think it is ok to model operations as links?


Posted in REST | 23 Comments »

Webinar on REST, RESTEasy, JBoss – March 23rd

Posted by billburke on March 23, 2010

I’m doing a webinar tomorrow on REST, JAX-RS, RESTEasy, and REST-*.  I only have 40 minutes, so it will be a brief overview of all those subjects and how they fit into our EAP product.  I’ll be giving it twice:

9am – EST

2pm – EST

For more information, click here

Posted in JAX-RS, REST, REST-star, RESTEasy, jboss | Leave a Comment »

REST-* Messaging Draft 5: new post and subscribe patterns

Posted by billburke on March 4, 2010

I’ve made some small changes to REST-* Message Draft 5.  First is to the reliable posting of messages to a message destination.  The second is to the push model default subscription creation method.

New post-message-once protocol

Previously, the post-message-once link used the POE pattern to avoid duplicate message posting.  I asked around and it seems that the POE pattern isn’t used a lot in practice.  I’m glad because it kinda breaks the uniform interface (unsafe GET) and isn’t really consistent with the other protocols I defined.  It is also very inefficient as you have to make two round trips to post each message.  Nathan Winder, on the reststar-messaging list suggested using a one-off link generated with each message post.  Here’s how it looks:

The post-message-once link URL provided by this link is not used to actually create a message, but rather to obtain a new, one-off, URL. An empty POST should be executed on the post-message-once link. The response provides a new “create-next” link which the client can then post their message to. The link is a “one-off” URL. What that means is that is that if the client re-posts the message to the create-next URL it will receive a 405 error response if the message has already successfully been posted to that URL. If the client receives a successful response or a 405 response, there should be a Link header returned containing a new “create-next” link that the client can post new messages to. Continuously providing a “create-next” link allows the client to avoid making two round-trip requests each and every time it wants to post a message to the destination resource. It is up to the server on whether the create-next URL is a permanent URL for the created message. If it is not permanent, the server should return a Content-Location header to the message.

post-message-once example

  1. Query the destination root resource for links.Request:
    HEAD /topics/mytopic HTTP/1.1
    Host: example.com
    

    Response:

    HTTP/1.1 200 OK
    Link: <...>; rel="post-message",
          <...>; rel="post-batch",
          <http://example.com/topics/mytopic/messages>; rel="post-message-once",
          <...>; rel="message-factory"
    
  2. Client performs a POST request to the post-message-once Link to obtain a create-next link.Request:
    POST /topics/mytopic/messages
    Host: example.com
    

    Response:

    HTTP/1.1 200 OK
    Link: <http://example.com/topics/mytopic/messages/111>; rel="create-next"
    
  3. Client POSTs message to create-next LinkRequest:
    POST /topics/mytopic/messages/111
    Host: example.com
    Content-Type: application/json
    
    {'something' : 'abitrary'}
    

    Response:

    HTTP/1.1 200 Ok
    Link: <http://example.com/topics/mytopic/messages/112>; rel="create-next"
    

Change to push model subscription

I also added a minor change to the push model’s subscriber registration protocol.  In the previous version of the spec, the client would post form parameters to a subscribers URL on the server.  The form parameter would define a URL to forward messages to and whether or not to use the POE protocol to post this message.  I changed this to simple require the client to post an Atom Link.  Since links define protocol semantics, the server can look at the link relationship registered to know how to interact with the subscriber when forwarding messages.  So, if the client registers a post-message-once link when it creates its subscription, the server knows how to interact with the link.  This gives the client and server a lot of simple flexibility in describing how messages should be forwarded.  For example:

This example shows the creation of a subscription and the receiving of a message by the subscriber.

  1. Client consumer queries topic resource for subscribers link.
    Request:

    HEAD /mytopic
    Host: example.com
    

    Response:

    HTTP/1.1 200 OK
    Link: <http://example.com/mytopic/subscribers, rel=subscribers, type=application/atom+xml
          ...
    
  2. Client does POST-Created-Location pattern to create subscriber
    Request:

    POST /mytopic/subscribers
    Host: example.com
    Content-Type: applicatin/atom+xml
    
    <atom:link rel="post-message-once" href="http://foo.com/messages"/>
    

    Response:

    HTTP/1.1 201 Created
    Location: /mytopic/subscribers/333
    
  3. A message comes in, the message service does a POST to this subscriber based on the interaction pattern described for post-message-once
    Request:

    POST /messages
    Host: foo.com
    

    Response:

    HTTP/1.1 200 OK
    Link: <http://foo.com/messages/624>; rel=create-next
    

    Request:

    POST /messages/624
    Host: foo.com
    Link: <http://example.com/mytopic/messages/111>; rel=self,
          <http://example.com/mytopic>; rel=generator
    Content-Type: whatever
    
    body whateve

Posted in REST, REST-star | Leave a Comment »

Mapping response on client side

Posted by billburke on February 19, 2010

I’ve been prototyping a bit lately for the REST-* effort, specifically for BPM.  I rely heavily on Link headers to pass links around.  RESTEasy has become pretty decent at handling links on the client side.  Here’s an example of client request/responses and link following via link headers:

      InputStream jpdl = Thread.currentThread().getContextClassLoader().getResourceAsStream(file);
      ApacheHttpClientExecutor executor = new ApacheHttpClientExecutor();

      ClientRequest request = executor.createRequest("http://localhost:8081/bpm/definitions");
      request.body(mediaType, jpdl);
      Link definition = request.create();
      Assert.assertNotNull(definition);
      ClientResponse response = null;

      response = definition.request().head();
      Assert.assertEquals(200, response.getStatus());
      Link instanceFactory = response.getLinkHeader().getLinkByTitle("instances");

      MultipartFormDataOutput form = new MultipartFormDataOutput();
      form.addFormData("order", "$199.99", MediaType.APPLICATION_XML_TYPE);
      response = instanceFactory.request()
              .body(MediaType.MULTIPART_FORM_DATA_TYPE, form)
              .post();
      Assert.assertEquals(201, response.getStatus());
      System.out.println(response.getLinkHeader().toString());
      Link instance = response.getLocation();
      Assert.assertNotNull(instance);

      Link next = response.getLinkHeader().getLinkByTitle("continue");
      Assert.assertNotNull(next);

      Link variables = response.getLinkHeader().getLinkByTitle("variables");
      Link newVariables = response.getLinkHeader().getLinkByTitle("variable-template");

      response = variables.request().head();
      Assert.assertEquals(200, response.getStatus());
      System.out.println(response.getLinkHeader().toString());
      Link order = response.getLinkHeader().getLinkByTitle("order");
      String xml = order.request().getTarget(String.class);
      request = newVariables.request();
      response = request.pathParameter("var", "customer")
             .body(MediaType.APPLICATION_XML_TYPE, "bill")
              .put();
      Assert.assertEquals(201, response.getStatus());
      response = request.pathParameter("var", "customer")
             .body(MediaType.APPLICATION_XML_TYPE, "bill burke")
              .put();
      Assert.assertEquals(204, response.getStatus());

      response = next.request().post();
      Assert.assertEquals(204, response.getStatus());

The thing about this code, it is a little hard to read.  Because HTTP is being treated like a messaging API, the code is a conglomeration of simple API calls.  The RESTEasy client proxy framework provides a nice way to map Java method calls to HTTP requests.  It also allows you to map automatically, a response body to a Java object.  Unfortunately though, this doesn’t work that well for my usecases.  Because I’m relying a lot on Link headers to pass information around in REST-*, I need something that can represent an HTTP response as a whole in a nice way.

A POJO Response Mapping

So, I thought, why not define (or reuse JAX-RS annotations) to map an HTTP response to a Java POJO?  It would kind of be the opposite of the RESTEasy @Form feature (where form maps an incoming request to a POJO).  It could look something like this:

@ResponseMapping
@ExpectedCode(200)
public interface MyResponse {

   @Body
   public Customer getCustomer();

   @LinkHeader
   public Link getNext();

   @LinkHeader("last")
   public Link getLastCustomer();

   @Header("ETag")
   public String getHash();

}

In this example, the client code would be expecting a response code of 200 (OK), a message body converted to a Customer object, a Link header named “next”, and a HTTP response header “ETag”. Using the RESTEasy proxy framework, you could then return this as a method return value, i.e.

@Path("/customers")
public interface CustomerClient {

   @Path("{id}")
   @Produces("application/xml")
   public MyResponse getCustomer(@PathParam("id") int custId);
}

What about errors?

For responses where the response code does not match, you could define similar mappings on an exception class.

@ResponseMapping
@ExpectedCode(404)
public class NotFoundException extends RuntimeException {}

You’d integrate it with the RESTEasy proxy framework by putting it within the throws clause.

@Path("/customers")
public interface CustomerClient {

   @Path("{id}")
   @Produces("application/xml")
   public MyResponse getCustomer(@PathParam("id") int custId) throws NotFoundException;
}

What do you think?
Maybe I’m going a little overboard here. Maybe not? I don’t know. Let me know what you think.

Posted in JAX-RS, REST, RESTEasy, java, jboss | 7 Comments »