The Delightful Web Application Platform provides an escape hatch from traditional web development and sets developers on the path to a service oriented future.
As a web developer, you've been using this pattern in part or whole already. The following are characteristics of the Delightful pattern:
I can't point to a single person, developer, or organization who invented this pattern. It evolved out of best practices and emerging technologies.
All I've done is given it a name (Delightful) and collected practices and case studies to help you determine if and when this pattern is appropriate for the problem you're trying to solve.
Delightful breaks web development habits. We've been designing and developing web applications in the same way since 1993, evidenced by the continual chasing of the next big toolkit, code generator, or application server. Most web development still takes the form of page output, control, validation, persistence, and logic within an application container (such as a webserver with a PHP interpreter, or a Tomcast server executing servlets), a pattern refined but never replaced since CGI.
Delightful proposes a clean decoupling of the service and front-end by taking advantage of the REST application pattern.
By decoupling the client, the user interface, first level validation, flow control, etc., the service can concentrate on implementing business rules and providing resources. This leads to several development advantages:
Don't underestimate the important of REST. Providing a document-centric view of data (available via URIs) adds flexibility, and compared to SOAP implementations the REST requests are concise. A REST request, for example, uses the request context (such as the HTTP message) to transport the authentication for a service call, while SOAP includes this inside the message envelope. This difference means that REST resources are validated by the web server against a configuration-based security model while a SOAP request is validated by the service implementation. REST services aren't called unless the request is authenticated and can separately handle authorization logic for any resource, while a SOAP service receives requests regardless of authentication. This simplifies development and testing for REST services and moves the application security domain into the hands of the server administrators and out of the hands of the development team.
Because idempotent REST requests may be cached, services may find opportunities to reduce service load and potentially reduce network load. Aggressive and well-balanced caching can mean a REST service has lower load than an equivalent SOAP service or web application.
Existing web applications can be migrated to the Delightful pattern with a few caveats and some pre-planning.
The first task should be resource definition. As an example, imagine that you provide services to a number of customers who will need to create, review, update, and cancel orders.
These verbs need to be evaluated with different perspectives in mind.
Each HTTP action has different characteristics that make it appropriate for some activities and inappropriate for others.
GET fetches content in an idempotent manner, that is with no side-effects. Although the content may be changed independently of the GET call (from other POST, PUT, or PATCH calls, or by other back-end processes) the GET call will never mutate the data or record.
GET calls should be bookmarkable as they reference a specific document.
POST supplies new data without knowledge of the destination resource path or identity. POST is appropriate when new documents are added but the document path won't be known in advance, such as documents identified in-part by a generated sequence.
PUT supplies new or replacement data to a known destination resource. PUT is appropriate when the document resource path is known and all the content is being replaced.
PATCH supplies replacement data to a known destination resource, changing part of the document. PATCH is appropriate for updating part of a record or document, but does not replace the original resource.
DELETE removes a document or resource identified by a path.
Resources or documents provided by a REST service are identified by unique paths. Every document should be distinctly addressed by a resource path rather than URI parameters or arguments.
The bad resource paths accept parameters and are written as API calls, identified by the IDs passed into the service call.
Consider the hierarchy of resources in the organization. Which is more inclusive, a customer or an order? Build your paths from general and inclusive to specific and exclusive.
Orders have attributes of customer, date, item, order line, quantity, total cost, shipping address, etc.
Customers have attributes of address, credit cart, registration date, full name, login account, etc.
Customers make orders.
From these characteristics, a hierarchy of inclusiveness becomes apparent:
Customer → Order → Order Line → [ Quantity, Item, Cost ]
Using this hierarchy helps define the URI paths for these resources.
It's important to note that REST itself doesn't specify or require any particular scheme for authentication or authorization. Authentication addresses how a service client's identity is verified. Authorization addresses how a service allowes an authenticated client to access specific resources.
Authentication can typically be handled by the hosting web server, proxy server, or the REST server framework. The body of the REST request doesn't contain authentication data as in a SOAP request, rather the HTTP message headers include the authentication data.
Authorization is up to the business rules of the implementation and describe whether the resource requires specific authentication to access. In the example, orders may only be visible to the customer and customer service, and the service would need to implement those business rules to only return the order document when then client is properly authenticated and belongs to one of those groups.
Web-based applications may rely on other external authentication schemes like OpenID or OAuth2. As with any other REST service, the web application's host environment (web server or REST service implementation) should provide authentication services and allow the business rule implementation to determine if the authenticated user has access to a given resource.
Given that the REST service doesn't handle authentication, how can users be authenticated? Assume that an authenticated session is managed with cookies.
Is the resource actually a document? Does the call represent a document action or something independent?
Orders can be naturally represented as documents as can Accounts. Other kinds of data, such as login credentials, may not be as easy to represent as a document. This is an opportunity to be creative in representing the data.
For JSON representations a document simply needs to be a data structure. Anything short of a pure method call should be able to be represented as a document.
Documents may include an action field to describe the new state of the document, such as created, updated, or removed. The action field allows documents to describe how to be processed without demanding API-like URIs (such as /Customer/DeleteOrder).
A quick evaluation of each verb yields the following starting points.
|Create order||POST||/Customer/Order||Yes||An order, action = New|
|Update order||PUT||/Customer/Order/order-number||Yes||An order, action = Update|
|Cancel order||PUT||/Customer/Order/order-number||Yes||An order, action = Cancel|
|Review open orders||GET||/Customer/Order||Yes||A list of orders|
|Review order history||GET||/Customer/Order/year/month/day||Yes||A list of orders|
|Create account||POST||/Customer/Account/||No||An account, action = Create|
|Cancel account||PUT||/Customer/Account/account-id||Yes||An account, action = Cancel|