May 17, 2015

RESTful JSF with POST-redirect-GET (part 1 of 5)


Did you know that JSF has great support for RESTful URLs and a stateless server? Whilst it’s true that JSF no longer is the one single answer for building a Java-backed web application, some critique really comes from lack of understanding these features. To be fair, this is yet another topic within the Java EE tech stack where documentation doesn’t really shine. Thus I’d like to present here a simple walk-through tutorial for building a RESTful JSF application, implementing best practices. And I will explain why this, in my opinion, is JSF done right in 2015.

This tutorial really is built upon the brilliant work and ideas of other people and on concepts which I believe to be known as standard best practices in the industry. There’s nothing new here. If you search for more information about REST’s concepts, which I will only briefly cover here, please search the interweb.

Most notably, this article builds upon the ideas Ed Burns presents in his short tutorial about JSF’s REST capabilities, as introduced with v. 2.2, and which he, as the Specification Lead of the JSF specification, promotes as best practices for using the framework. Whilst his article concentrates on the pure technical application and the basic functionality of the components involved, I will here show how I would apply these concepts and components in a real world application, and show how the implementation is driven by REST best practices and standards.

Why should I go RESTful?

REST is driven by a few simple concepts:
  • resources (i.e. information) are uniquely identified by a URI and exist independent of their actual representation
  • there is a fixed set of actions (most prominently GET, POST, PUT, DELETE) used to interact with these resources
  • the application state is defined at any time by the outcome of the last action.
There are a couple of widely accepted advantages a REST-based software architecture provides. For web applications in general, REST is a natural choice as is matches the way the underlying HTTP protocol works.

For our considerations, these attributes of a RESTful architecture are the most beneficial ones:
  • REST is CRUD
  • Stateless services, stateful models
  • RESTful URLs are user-friendly

REST is CRUD

Thinking in REST means thinking in nouns, i.e. in business models and their relations, not in verbs, i.e. actions on business models. That way, REST is truly object-oriented, and as such it is the opposite of a service-oriented architecture (yes, that would be SOA, which is a REST-anti-pattern).

Let me illustrate this with a pseudo-code example: “Update address information of the customer with the customerId provided”.

In SOA:
addressService: UPDATE_ADDRESS(customerId, address)
In OOA / REST:
customer = customerService: GET(customerId)
customer.address = address
customerService: POST(customer)
With this highly simplified example alone, we can observe:
  • In a SOA, the business logic resides in the service and the service API.
  • In REST, the business logic resides in the business model.
I assert that the latter is the way to go, for a couple of reasons:
  • This matches well an object-oriented language like Java. The state and the behavior reside in the business object.
  • The business object is a rich domain object. Having the logic within that structure enables DRY design. (Within this design, the anemic domain model becomes a true anti-pattern.)
  • The service API is restricted to the fixed set of RESTful actions, i.e. verbs (GET, POST,…). This allows to take full advantage of abstraction techniques with core Java language features (inheritance and generics). Also, the service API thus really becomes a self-documenting no-brainer.
Actually, all we need in the service API really is CRUD, and this is what four of RESTs actions / verbs provide:
Create: PUT
Read:   GET
Update: POST
Delete: DELETE
…plus potentially a bunch of findBy(attributeValues…) Read queries.

Stateless services, stateful models

Since the state resides in the client (the response of the last HTTP request and most prominently the URL) and eventually in the persistent model entity, the services really can and should be stateless implementations.

Again, this works well with an object-oriented language, and it also concurs to the central wisdom of functional programming: that an application with mutable state is hard to maintain, and avoiding state is preferred.

At least in theory, this allows us to freely choose any scope for our controller / service beans, all the way down to @RequestScoped (we will actually implement this later on). This really embraces the stateless nature of the HTTP protocol rather than trying to abstract it away with potentially leaky concepts such as the session.

RESTful URLs are user-friendly

RESTful URLs are highly user-friendly as they represent the application’s state and as such reflect the user’s current location.

More importantly, RESTful URLs are bookmarkable and work well with the browser’s back / forward button functionality. These are central usability aspects today’s web application users typically expect.

A more sophisticated, truly RESTful URL will even reflect the hierarchical relations between business entities, thus acting as a true “breadcrumb” for the web application. Because these URLs adhere to commonly agreed de-facto-standards, their functionality is easily understood both by humans and automated clients.

RESTful JSF

Within this article, we will apply REST on the UI layer only whilst taking the underlying CRUD concept all the way through the service layer. However, we will not build a RESTful service API! The service is actually called from the UI layer using local Java method calls as it is dependency injected into the UI layer (using Java EE framework capabilities). To learn how to build a RESTful service API, please look for a different tutorial on the web.

The UI layer solution will be based on REST maturity level 2 (out of 3):
  • Using URIs to address resources.
  • Using a subset of the HTTP verbs for interactions. Actually, we will only use GET and POST as other verbs are not supported by HTML forms.
  • We will however not use return status codes and other true HATEOS features as they do not add value to the desired user experience and / or are not supported by JSF.
What we want to and will achieve in this tutorial is:
  • URL rewriting, bookmarkable URLs and back / forward button functionality*
  • The application is implicitly ready for lazy-loading
  • The application is implicitly ready for optimistic locking (e.g. using a @Version entity property)
  • Optionally @RequestScoped controllers (truly stateless controllers)
  • Optionally true RESTful URLs with PrettyFaces
*More specifically, I would describe this requirement as: The user can hit ENTER in the browser’s address bar at any time, and that will always trigger a page refresh, but no page navigation. The address line always matches the current view.

Update November 15, 2015: You may also be interested in CrudFaces, which provides a simple, lean framework to build best-practices compliant RESTful JSF applications, as explained in this article, and comes with many useful general-purpose components to make JSF development easier.

The example application

We will build a very simple example web application with CRUD functionality for these two business entities:

Each entity is uniquely identified by its id which is auto-generated on persist.

A customer can have one or more payments, and one payment is associated with exactly one customer. A customer of employment type unemployed must not have a company name.

There will be a master view (list of all entities) and a detail view (edit page for current entity) for each entity type, respectively. The payments master view will be integrated in the detail view of the parent customer entity.

For simplicity reasons, I will use vanilla JSF (Oracle Mojarra) core component only, instead of a more sophisticated UI library such as PrimeFaces.

I will however use functionality of the OmniFaces utility library because reinventing the wheel is not DRY compliant.

Here’s how the outcome of this tutorial will look like (for the enhanced version with truly RESTful URLs see this tutorial’s last section about using PrettyFaces):

Customers Payments
List /customers/list.xhtml /customers/edit.xhtml?id=1#payments


Edit /customers/edit.xhtml?id=1 /payments/edit.xhtml?id=1


Create /customers/edit.xhtml?id=1 /payments/edit.xhtml?customer=1



Pages: 1 2 3 4 5