1 2 3 4 Previous Next

mhadley

53 posts

I've extended the declarative hyperlinking module to support the HTTP Link header. It works similarly to the @Link annotation I described earlier except you annotate the response entity class with @LinkHeader (or @LinkHeaders if you need more than one Link header) instead of annotating response entity fields with @Link. Here's a complete example that shows both annotations in action:

@LinkHeader(value=@Link(resource=WidgetResource.class), rel="self")
@XmlAccessorType(XmlAccessType.NONE)
@XmlElement(name="widget")
public class WidgetRepresentation {

  @Link(resource=WidgetResource.class)
  @XmlAttribute
  private String href;
    
  String id;
    
  public WidgetRepresentation(String id) {
    this.id = id;
  }
  
  public String getId() {
    return id;
  }
}

Given a resource class:

@Path("widgets/{id}")
public class WidgetResource {

  @GET
  @Produces("application/xml")
  WidgetRepresentation getWidget(@PathParam("id") String id) {
    return new WidgetRepresentation(id);
  }
}

A GET request for/application/widgets/10 will result in:

HTTP/1.1 200 OK
Server: GlassFish v3
Link: </application/widgets/10>;rel="self"
Content-Type: application/xml
Content-Length: xxx
Date: Thu, 18 Mar 2010 21:04:04 GMT

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<widget href="/application/widgets/10"/>

where the bold text is created by the new linking annotations.

Check out this tutorialon the use of WADL to add a service to Zembly. For those not already familiar with Zembly it is:

"An application development environment that not only targets the web as its native platform, but uses cutting-edge web innovations such as web services, social networking, and Web 2.0, to change the way applications are built, deployed, scaled, and delivered to where users congregate."

Essentially any service described by WADL can be easily used within a Zembly application. If you are using Jersey to build your service then support for WADL comes free.

mhadley

WADL-JSON ? Blog

Posted by mhadley Jul 16, 2010

In a recent message to the GData Python Client Library Contributors mailing list, Joe Gregorio outlines a new discovery capability for GData APIs. E.g. here's a document that describes the Buzz API. Look familiar ? To me it looks very much like a JSON version of WADL.

Joe goes on to describe the benefits of this approach and notes that it "allows very lightweight client libraries" and "the actual code for the client is very small". Maybe its time to revisit thatDo We Need WADL post ? After all, the criticism levelled at WADL applies equally to this JSON variant.

Last week saw the release of three new WADL frameworks:

Python
WADLLib
C#
WADL#
Ruby
Ruby client for the Web Application Description Language

Earlier I had committed, but failed to blog about, changes to wadl2java that enable the latest version to read both the current and prior versions of WADL files. This is driven by an XSLT stylesheet filter that updates the previous version to the latest version while leaving the current version intact.

mhadley

Time for a Change Blog

Posted by mhadley Apr 27, 2010

This week is my last at Oracle, next week I'll be starting a new job with Mitre.

I started looking around for a "Plan B" prior to the Sun acquisition closing in February, mainly due to uncertainty about whether I'd be offerred a position with Oracle. A friend introduced me to an excellent opportunity at Mitre and, after a couple of rounds of interviews and a lot of thought, Plan B morphed into Plan A.

I've enjoyed my short stint with Oracle, it was great to be able to work on Jersey again after 18 months or so doing other things and hopefully the declarative hyperlinking extensions and WADL generation improvements I've been working on will have legs after I leave. I don't know yet whether my new role will afford the opportunity to contribute further to Jersey and/or JAX-RS but I'll be working on the application of open services technologies to national problems so its possible.

I plan to continue blogging here when I can, so stay tuned for the next chapter.

I've spent some time fleshing out the code in the experimental declarative hyperlinking module I blogged about earlier. In that earlier entry I showed how you could use the new @Link annotation with existing URI templates either explicitly like this:

@Link("widgets/{id}")
URI link;

or by referencing a resource class @Path annotation value like this:

@Link(resource=WidgetResource.class)
URI link;

Expression Language Support

With the latest trunk code you can now use EL in explicit@Link templates, thanks to Ed Burns for helping to get me bootstrapped with the EL APIs. E.g.:

@Link("widgets/${instance.id}")
URI link;

The above would extract the value of the idproperty of the instance bean. Three beans are currently supported:

instance
The object whose class contains the @Linkannotation currently being processed.
entity
The response entity object returned by the resource class method.
resource
The resource class instance that returned the entity.

Its straightforward to add others but these seemed like a useful set to start with.

Custom Bindings

By default, a URI template parameter is replaced by the value of a same-named property in the current instance. The following two annotations are therefore equivalent:

@Link("{id}")
@Link("${instance.id}")

Custom bindings allow the source of the value of a URI template parameter to be changed, e.g.:

@Link(value="{id}", bindings={
  @Binding(name="id", value="${resource.widgetId}")
})

In the above the {id} template parameter will be replaced with the value of the widgetId property of the resource class instance that returned the response. Thename property of an @Binding gives the name of a URI template parameter, the value is an EL expression that defines how to get the value of the parameter.

One of the areas I'm keen to improve in the next version of JAX-RS is link creation. JAX-RS already offers UriBuilder but I think an annotation driven approach could save a lot of repetitive coding.

I've been experimenting with a couple of annotations that I think would be useful and I just checked in an experimental extension that partially implements what I have in mind. Suppose you have a resource like this:

@Path{"widgets"}
public class WidgetsResource {
  ...
}

and you want to include a URI to this resource in a representation. Using the new extension you can just annotate a field in your representation class like this:

@Link(resource=WidgetsResource.class)
URI link;

and then Jersey will build the appropriate URI and inject it into the representation before the representation is serialized by a message body writer.

If the URI template contains parameters, their values are obtained by looking for a bean property or field by the same name in the representation. E.g. consider the following representation class:

public class WidgetRepresentation {
  @Link("widgets/{widgetId}")
  URI link;
  
  String getWidgetId() {...}
}

After processing by the extension, if thegetWidgetId method returned "abc123", the value of the link field would be/context/widgets/abc123 wherecontext is the deployment context.

The optional style property of the@Link annotation can be used to select between absolute URIs, absolute path and relative path depending on requirements.

Using the Extension

In order to try out the extension you have to:

  • Declare a dependency on the newjersey-server-linking module which is available in Jersey trunk under the experimental directory.
  • Install the response filter in your application using aninit-param in the web.xml like this: 
    <servlet>
      <servlet-name>Jersey Web Application</servlet-name>
      <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
        <init-param>
            <param-name>com.sun.jersey.config.property.packages</param-name>
            <param-value>your application packages here</param-value>
        </init-param>
        <init-param>
            <param-name>com.sun.jersey.spi.container.ContainerResponseFilters</param-name>
            <param-value>com.sun.jersey.server.linking.LinkFilter</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    

Next Steps

The Javadoc of the @Link annotation describes a couple of things that I plan to implement next:

  • Support for the @Binding annotation already sketched out in the code. This will allow the values of template parameters to be pulled from alternate sources including differently named properties of the representation and resource.
  • Support for EL expressions in link templates. This will allow a little more expressivity for templates that don't already exist as values of @Path annotations.
mhadley

WADL Submitted to W3C Blog

Posted by mhadley Oct 23, 2009

For those of you who've been patiently waiting for WADL to be submitted to a standards organization, I'm pleased to announce thatWADL is now a W3C Member Submission.

The specification submitted to the W3C is a reformatted version of the draft update I blogged about here. If you already switched to that version then you are current. If not, now would be a good time to think about updating to the latest grammar, the changesare fairly minimal but did require a new namespace since they were not backwards compatible.

mhadley

HATEOAS with WADL Blog

Posted by mhadley Apr 2, 2009

Craig asked me how you would describe something like the Sun Cloud APIs with WADL and I thought others might be interested in the answer. A key feature of the cloud APIs is that they make good use of hypertext as the engine of application state or HATEOAS for (relatively) short. What this means is that rather than documenting a set of URIs and URI templates and relying on the client to construct URIs to access the resource they need, the cloud APIs only publish a single "root" URI and then document where to find additional URIs in representations that clients can use to traverse the service. This is much closer to how a browser user traverses links in web pages. In a recent blog entry Craig describes the advantages of HATEOAS.

So, how to describe this kind of Web application in WADL ? The key is to:

  1. Use resource types to describe each kind of resource,
  2. Parameterize representations to identify links embedded within them,
  3. Define the types of resource each embedded link identifies.

To illustrate I'll use the Sun cloud APIs and the root level representation of the VDC. In WADL we describe this top level resource as follows:

<resources base="http://example.com/">
  <resource path="/" type="#vdc"/>
</resources>

The above declares a top level resource of type "vdc" at the URI "http://example.com/". Next we need to describe the resource type "vdc":

<resource_type id="vdc">
  <method name="GET">
    <response status="200">
      <representation mediaType="application/vnd.com.sun.cloud.compute.Vdc+json">
        <parameter name="attach" path="vms[].attach" style="plain">
          <link resource_type="#button"/>
        </parameter>
        <parameter name="detach" path="vms[].detach" style="plain">
          <link resource_type="#button"/>
        </parameter>
        <parameter name="backup" path="vms[].backup" style="plain">
          <link resource_type="#button"/>
        </parameter>
        ...
      </representation>
    </response>
  </method>
</resource_type>

The above says that a representation of resources of type "vdc" can be obtained with GET and that such representations contain links to other types of resources. I've shown three links here but in reality a VDC document contains many more. Each link is contained within a parameter that describes where in the representation the link can be found. In this case each link is to the same type of resource that essentially acts like a push button, here's the description of that resource type:

<resource_type id="button">
  <method name="POST">
    <response status="204">
  </method>
</resource_type>

The above says that resources of type "button" only support POST and return an empty 204 response on success.

I've glossed over one important issue related to the use of JSON for the representation of a VDC. If the representation used XML then the value of the path attribute of the parameter element is an XPath and it has semantics for selecting a set of nodes. For JSON theres no such standard path language (that I'm aware of) so I've had to improvise. The "vms" property of the vdc JSON object is an array and the "[]" in the path attribute values is meant to signify that the path will match multiple properties of the JSON object, if anyone has a better idea then let me know.

A draft of the JAX-RS 1.1 specification and API is now available. We're now working on implementing the new features in Jersey and adding corresponding tests to the TCK. It will be a while before 1.1 can be declared final since there's quite a bit of new functionality, particularly in the areas of integration with Servlet 3.0, EJB 3.1 and JSR 299 - none of which are yet final.

mhadley

Draft WADL Update Blog

Posted by mhadley Feb 3, 2009

Its been just over two years since the last version of WADL was published and, in the intervening time, a number of issues have accumulated. I've held off making regular updates for reasons of stability but I think there's sufficient backlog now to require a new version. First drafts of the updated specification and schemas are available at:

Changes since the November 2006 Publication:

  • The XML namespace name was changed to http://wadl.dev.java.net/2009/02.
  • Resolved issue 13. The status attribute was moved from the representation element to the response element. The cardinality of the response element was changed from 0–1 to 0–many. The fault element was removed.
  • Resolved issue 17. Allow parameters at top level and parameter references to prevent repetition when a parameter is used in multiple places.
  • Resolved issue 18. A resource type element may now contain resource child elements.
  • Resolved issue 20. Allow multiple resources elements within an application.
  • Updated the Atompub example to RFC syntax.

Unfortunately the changes required by issue 13are not backwards compatible hence the namespace change. Existing WADL docs will require minor edits as a result.

All feedback on the new draft is welcome. Now would be a good time to file bug reports or request enhancements.

The proposed final draft of JAX-RS is now available for review. We are now concentrating on completing the reference implementation (Jersey) and the TCK for a planned final 1.0 release in September.

The JAX-RS public review draft is now available for, er, review - download it here.

If you are attending JavaOne we'd love to see you at any or all of the following sessions:

I'll also be on Glen's panel "REST Versus SOA: Can We All Just Get Along?" which follows our BOF in the same room at 21:30 (Tuesday is shaping up to be a busy day).

mhadley

JAX-RS Implementations Blog

Posted by mhadley Apr 1, 2008

The Restlet team just announced a new release. Amongst the new features is support for JAX-RS, see an example here. With the RI (Jersey), Apache CXF, and JBoss RESTeasy, that makes a total of four implementations currently underway. The feedback we're receiving as a result of these parallel implementations is proving very useful and I'm grateful for the all the good input we've been getting.

The graph below shows the monthly totals for emails sent to the dev, users, issues and commits mailing lists for both JAX-RS and Jersey.

activity.png

As you can see, traffic on the lists has picked up quite a bit over the last few months and a good proportion of the increase is due to the additional implementation work flushing out issues. We've also been working through our issues list with a view to publishing a JCP public review draft in the not too distant future.

I'm working on an internal project building some RESTful services using a combination of Jersey, JPA, Glassfish and Derby. Actions on some resources require authentication and I need access to the name of the authenticated user in the resource method. This entry describes the steps to set this up - kudos to my colleague Hubert for working out much of the below.

Obviously you're going to need all the ingredients listed above. I'm using NetBeans which came bundled with Glassfish and Derby so all I had to do was install the RESTful Web Services plug-in, YMMV.

Next you need a database to store username, password and group information. Here's the table definitions I used:

CREATE TABLE users (
    id INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    username VARCHAR(64) UNIQUE NOT NULL,
    password VARCHAR(64) NOT NULL,
);
CREATE INDEX username ON users(username);

CREATE TABLE groups (
    id INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    username VARCHAR(64) NOT NULL REFERENCES users(username) ON DELETE CASCADE,
    groupname VARCHAR(64)
);

Depending on your needs you could lose the integer fields, the important thing is to have a column in the group table with the same name as the column in the users table that holds the username. Those two columns are used to join the users table to the groups table. The Glassfish security realm is going to execute a query like this to retrieve the groups (which map to security roles) that a particular user is a member of:

SELECT groupname FROM groups g, users u where g.username = u.username and u.username = ?

Add some users and groups for testing purposes, note that the password should be an md5 hash, not plaintext - there are several web sites that offer online MD5 generators that you can use. I used groups named USERS and ADMINISTRATORS, you'll see where these come in later.

Next you need to define a JDBC data source, connection pool and security realm in Glassfish. The first two are pretty straightforward and will likely be taken care of already if you have deployed a web application using the database. Setting up the security realm is also straightforward once you have a suitable database structure as described above. You do this via the admin console as shown below (there are a couple of additional fields on the form, you can leave those blank):

realm.png

Its now possible to require authentication for access to a JAX-RS resource via web.xml. Say I have a resource that only authenticated users can use, e.g.:

@Path("dropbox")
public class DropBox {
    @Context
    SecurityContext security;
    
    @POST
    public Response drop(InputStream data) {
        String username = security.getUserPrincipal().getName();
        ...
    }
}

Note the use of dependency injection to get an instance ofSecurityContext and how that interface provides access to the username. In order for this to work we have to tell the container that authentication is required for access to the/dropbox URI. Add the following lines to your web.xml to restrict use of this resource to members of the USERS group:

<security-constraint>
    <display-name>DropBox</display-name>
    <web-resource-collection>
        <web-resource-name>DropBox</web-resource-name>
        <description></description>
        <url-pattern>/dropbox</url-pattern>
        <http-method>GET</http-method>
        <http-method>POST</http-method>
        <http-method>HEAD</http-method>
        <http-method>PUT</http-method>
        <http-method>OPTIONS</http-method>
        <http-method>TRACE</http-method>
        <http-method>DELETE</http-method>
    </web-resource-collection>
    <auth-constraint>
        <description>Have to be a USER</description>
        <role-name>USERS</role-name>
    </auth-constraint>
</security-constraint>
<login-config>
    <auth-method>BASIC</auth-method>
    <realm-name>userauthn</realm-name>
</login-config>
<security-role>
    <description/>
    <role-name>USERS</role-name>
</security-role>

That about it, after you redeploy the application, the next time you try to access /dropbox you'll get a 401 Unauthorized response unless you include a suitable Authorization header in the request.

Filter Blog

By date: