Jump to content

How to Use Links to Manage Application Flow

0
  adfm's Photo
Posted May 13 2010 01:03 PM

If you're building a web service and would like to use links to control application flow on the server, but don't know where to start, try this recipe from Subbu Allamaraju's RESTful Web Services Cookbook.


One of the key applications of hypermedia and links is the ability to decouple the client from learning about the rules the server uses to manage its application flow. The server can provide links containing application state, thereby using hypermedia as the engine of application state.

Problem

You want to know how to keep clients decoupled from the business logic used to implement the flow of the application.

Solution

Design each representation such that it contains links that help clients transition to all the next possible steps. If the server needs to carry forward state from one step to the next, encode the state in links.

Discussion

Imagine a web service that manages an employee hiring process. This process has multiple steps, such as (a) enter candidate details, (b) check references, © conduct background security checks, and (d) make an offer. Each step must happen in sequence. You can use the resources and URIs shown in Table 5.2 to implement this sequence. The token {id} in these URIs is the candidate ID.

Table 5.2. URIs for employee hiring process

Method

URI

Purpose

POST

http://www.example.org/hires

Create a candidate resource.

POST

http://www.example.org/hires/{id}/refs

Submit reference comments.

POST

http://www.example.o...s/{id}/bgchecks

Submit background check results.

POST

http://www.example.org/hires/{id}/hire

Make an offer.

POST

http://www.example.o...es/{id}/no-hire

Do not make an offer.


Assume that this web service is governed by the following business rules:

  • After entering candidate information, start the reference check.

  • After receiving at least two positive references, start the background check.

  • After getting background clearance, make an offer.

Given these rules and the URIs, you can implement a client for the employee hiring process. After each step, the client can check the rules to see whether it can move to the next step. However, this introduces coupling between the client and server’s business rules, since the server, and not the client, should be responsible for managing those rules.

When your web service requires clients to learn and implement application flow rules, you are introducing yet another kind of coupling between your clients and servers. Just like the details to construct URIs, such flow rules also become part of your web service’s public interface and therefore cannot be changed without breaking clients.

A better alternative is to let the server provide clients with “contextual” links containing URIs for possible next steps. When the client discovers a link, it can attempt a transition to the next step in the process. When the link is absent in the representation, the client can assume that the transition is not possible. This prevents the client from having to learn and hard-code application flow.

For an analogy, consider a user interacting with a browser-based web application. The browser, as instructed by the user, follows the links and forms without prior knowledge of the flow of the application. The purpose of links is to extend the same benefit to application clients. Here is a representation of the newly entered candidate resource created by the server:

# Request to enter candidate info

POST /hires HTTP/1.1

Host: www.example.org

Content-Type: application/json



{

 "name": "Joe Prospect",

 ...

}



# Response containing a link to post reference checks

HTTP/1.1 201 Created

Location: http://www.example.org/hires/099

Content-Location: http://www.example.org/hires/099

Content-Type: application/json



{

 "name": "Joe Prospect",

 "id": "urn:example:hr:hiring:099",

 ...

 "link" : { 1

	"rel" : "http://www.example.org/rels/hiring/post-ref-result",

	"href" : "http://www.example.org/hires/099/refs"

 }

} 

1

Link to post reference check results

This representation has a link to submit new reference check results. Since there is no other link, the client cannot yet initiate the background check process or make an offer.

After entering two positive reference check results, the server can return a representation to indicate that the client can start the background check:

# Request to enter first reference comment

POST /hires/099/refs HTTP/1.1

Host: www.example.org

Content-Type: application/json



{

 "text" : "Joe is a ...",

 "by" : "...",

 "on" : "2009:10:12T16:05:00Z"

}



# Response

HTTP/1.1 200 OK

Content-Location: http://www.example.org/hires/099

Content-Type: application/json



{

 "name": "Joe Prospect",

 "id": "urn:example:hr:hiring:099",

 ...

 "link" : {

	"rel" : "http://www.example.org/rels/hiring/post-ref-result",

	"href" : "http://www.example.org/hires/099/refs"

 }

}



# Request to enter second reference comment

POST /hires/099/refs HTTP/1.1

Host: www.example.org

Content-Type: application/json



{

 "text" : "Worked with Joe, ...",

 "by" : "...",

 "on" : "2009:10:12T17:00:00Z"

}



# Response

HTTP/1.1 200 OK

Content-Location: http://www.example.org/hires/099

Content-Type: application/json



{

 "name": "Joe Prospect",

 "id": "urn:example:hr:hiring:099",

 "refs": ...,

 ...

 "links" : [{ 1

 	"rel" : "http://www.example.org/rels/hiring/add-ref-result",

 	"href" : "http://www.example.org/hires/099/refs"

	},

	{ 2

 	"rel" : "http://www.example.org/rels/hiring/add-background-check",

 	"href" : "http://www.example.org/hires/099/bgchecks"

	}]

} 

1

Link to post reference check results

2

Link to post background check results

At this point, the client can either enter more reference checks or move on to submit background check results. If the results are acceptable based on the server’s business policies, the server can include a link to make an offer.

# Request to submit background check results

POST /hires/099/bgchecks HTTP/1.1

Host: www.example.org

Content-Type: application/json

{

 "text" : "...",

 "by" : "...",

 "on" : "..."

}



# Successful background check

HTTP/1.1 200 OK

Content-Location: http://www.example.org/hires/099

Content-Type: application/json;charset=UTF-8



{

 "prospect" : {

	"name": "Joe Prospect",

	"id": "urn:example:hr:hiring:099",

	"refs": ...,

	"link" : { 1

 	"rel" : "http://www.example.org/rels/hiring/make-offer",

 	"href" : "http://www.example.org/hires/099/hire"

	}

 }

} 

1

Link to make an offer

In this manner, the server guides the client through an employee hiring process without forcing the client to implement any more logic than it should.

The mere presence of a link will not still decouple the client from having to know how to prepare the data and make a request for the transition. Servers will have to establish and document how to find links and the semantics of all extended link relation types.

RESTful Web Services Cookbook

Learn more about this topic from RESTful Web Services Cookbook.

While the REST design philosophy has captured the imagination of web and enterprise developers alike, using this approach to develop real web services is no picnic. This cookbook includes more than 100 recipes to help you take advantage of REST, HTTP, and the infrastructure of the Web. You'll learn ways to design RESTful web services for client and server applications that meet performance, scalability, reliability, and security goals, no matter what programming language and development framework you use.

See what you'll learn


Tags:
0 Subscribe


0 Replies