What is SOA? What is REST?

by Hojung posted Dec 25, 2011


Prev이전 문서

Next다음 문서


+ - Up Down Comment Print


What is SOA?

Service Oriented Architecture (SOA) is used in companies that have large numbers of applications for employees in different departments with varying responsibilities. Many of these applications share functionalities, but the combinations of functionalities, user-interface specifics, and usability requirements differ. Like many enterprise architectures, SOA follows a multitier model, but it doesn't stop there. Within the server, functionalities are divided over separate services. A client can consume one or more of the services, and one service can be consumed by many clients. The result is a loosely coupled architecture that propagates the reusability of existing software.

The usual heavyweight implementation

Frequently used acronyms

  • API: Application program interface
  • IT: Information technology
  • XML: Extensible Markup Language

SOA fits particularly well in large companies that have several hundred poorly integrated applications and that need to clean up their IT infrastructures. SOA is a proven practice, capable of working effectively in large environments. Adapters can to translate legacy applications to services that integrate as backends to modern applications. Middleware technology is available to orchestrate services and control access to specific functionalities in the service. Because the need for SOAs is highest in this area, vendors of middleware technology typically focus their products toward large and heavyweight solutions.

SOA and lightweight technology

The ideas behind SOA are just as valuable in smaller companies. The setup costs and required knowledge for a heavyweight solution might prevent a small company from trying SOA—but that shouldn't be the case. Forget the heavyweight implementations for a moment, and think about basic concepts of SOA:

  • Extract services from existing or new applications
  • Centralize them to be consumed by many clients

Nothing is stopping you from implementing this idea with lightweight technology. You can start small and let it grow. If your company grows into a large multinational, you can always migrate to the heavyweight technology later.

What is REST?

Usually, SOA is implemented with the SOAP protocol, described by a Web Services Description Language (WSDL) document. Although many developer tools make it relatively easy to work with SOAP and WSDL, I consider them heavyweight technology, because they're hard to work with if you don't use those tools.

You can implement SOA just as well by sending simple messages over Hypertext Transfer Protocol (HTTP). Basically, this is what RESTful Web services do. Representational State Transfer (REST; the name was coined by Roy Fielding) isn't a protocol or technology: It's an architectural style. REST, a lightweight alternative to SOAP, is resource oriented rather than action oriented. It's often summarized as bringing back remote procedure calls to GET, POST, PUT, and DELETE statements using HTTP. In my opinion, this is the second important step.

The first and most important step is to model all your resources as URLs. URLs combine the simplicity of something easy to remember with the capability of reaching the billions of available Web pages. At least, they're easy to remember if you model them the right way (like http://www.ibm.com/developerworks/xml/) and don't focus so much on the GET, POST, PUT, and DELETE that you forget a URL like http://www.longfakeurl.com/pol_srdm/70612/9,3993.32?id=78688&lang=cz&st=idx isn't intuitive.

In practice, using HTTP is further reduced to GET and POST, because these are best supported by major browsers. Instead of using PUT on http://domain.com/myresources, you do a POST to http://domain.com/myresources/new; and instead of using DELETE on http://domain.com/myresources/oldresource, you do a POST on http://domain.com/myresources/oldresource/delete.

A RESTful design procedure

As a guideline to design a RESTful Web service, you can follow these four steps:

  1. Decide on the resources and their descriptive URLs.
  2. Choose a data format for communication on each URL.
  3. Specify the methods on each resource.
  4. Specify the returned data and status codes.

Here's how to do it. Suppose you're a developer working for an airline company. The airline has software for booking flights and components for handling payments (cash and credit cards). It uses software to track luggage, do internal resource planning, and perform many other tasks.

Suppose the employee at the check-in counter uses a client application that accesses the luggage-tracking service and also uses a service to assign seats to passengers. The people handling the luggage on the ground only need the luggage-tracking service, not the other services. Their client only allows them to confirm the arrival of luggage that's already checked in. They aren't allowed to check in new luggage.

In this example, you'll design the luggage-tracking service. First you decide on the resources: travellers, flights, and pieces of luggage (note that everywhere you see {id}, you can imagine any random number filled in):


Choose a data format for each resource:


<bag id="{id}">
  <traveller id="{traveller-id}"/>
  <flight id="{flight-id}" />
  <status>{current-status: departure/plane/arrival}</status>


<flight id="{id}">
	<traveller id="{traveller-id-0}" />
	<traveller id="{traveller-id-1}" />
	<traveller id="{traveller-id-2}" />
	<bag id="{bag-id-0}" />
	<bag id="{bag-id-1}" />
	<bag id="{bag-id-2}" />


<traveller id="{id}">
  <flight id="{flight-id}" />
	<bag id="{bag-id-0}" />
	<bag id="{bag-id-1}" />
	<bag id="{bag-id-2}" />

Obviously, this model is overly simplistic. For the current example, you need to support only two methods, and this model is sufficient for that purpose. The check-in counter should be able to check in new bags for a traveller. And the ground personnel should be able to change the status of a bag when they put in into the airplane:

  • POST to http://luggagetrackingairlinecompany.com/travellers/{id}/newbag returns a <bag>XML structure.
  • POST to http://luggagetracking.airlinecompany.com/bags/{id}/status/{newstatus} returns the modified XML structure.

For the status codes, you use standard HTTP statuses. Any action that succeeds returns 200. If the system fails to find a resource by its ID, it returns 404. Any errors due to system failure result in a 500.

Code example: URL mapping

You can choose many ways to map URLs to implementation methods. The more sophisticated methods might be more flexible and should perform best on larger applications. This small example uses the simplest thing that could possibly work: regular expressions. Here is the example for the post method on the BagServlet that passes the URL arguments to the underlying servlet. You can find the complete servlet in the download file available with this article. Note that the actual underlying service isn't implemented there. Here's the example:

protected void doPost(HttpServletRequest request, HttpServletResponse response)
	throws ServletException, IOException {
	Pattern pattern = Pattern.compile("^/?.*?/bags/(.*)/status/(.*)$");
	Matcher matcher = pattern.matcher(request.getRequestURI());

	if(matcher.matches()) {
		String bagId =  matcher.group(1);
		String newStatus = matcher.group(2);
		bagService.changeBagStatus(bagId, newStatus);

When this URL is invoked, it implicitly returns a 200 status code when it succeeds. More interesting is the fact that the code returns XML structures The example uses the XStream API to serialize Java™ objects to XML structures. This API requires a minimum of configuration and mostly relies on the field names from the classes choosing the element names.

The example code uses the following simplistic classes for its demonstration:


package eu.adraandejonge.restfulsoa;

public class Flight {
	String id;

	public Flight(String id) {
		this.id = id;


package eu.adraandejonge.restfulsoa;

public class Traveller {
	private String id;

	public Traveller(String id) {
		this.id = id;


package eu.adraandejonge.restfulsoa;

public class Bag {
	private String id;
	private Flight flight;
	private Traveller traveller;
	private String status;

	public Bag(String id, Flight flight, Traveller traveller, String status) {
		this.id = id;
		this.flight = flight;
		this.traveller = traveller;
		this.status = status;

Suppose the underlying BagService returns a bag with flight ID = 1, traveller ID = 1, and status = new. Consider the following GET implementation:

protected void doGet(HttpServletRequest request, HttpServletResponse response)
	throws ServletException, IOException {
	Pattern pattern = Pattern.compile("^/?.*?/bags/(.*)$");
	Matcher matcher = pattern.matcher(request.getRequestURI());
	if (matcher.matches()) {
		String bagId = matcher.group(1);

		Bag bag = bagService.retrieveBag(bagId);

		XStream xstream = new XStream();
		xstream.alias("bag", Bag.class);
		xstream.alias("traveller", Traveller.class);
		xstream.alias("flight", Flight.class);
		xstream.useAttributeFor(Bag.class, "id");
		xstream.useAttributeFor(Traveller.class, "id");
		xstream.useAttributeFor(Flight.class, "id");

		String xml = xstream.toXML(bag);

When you query this URL, it returns the following:

<bag id="1">
  <flight id="1"/>
  <traveller id="1"/>

Where to go from here?

I chose the example code to show the power of URLs without too much underlying communication. For other services, you might need to process XML structures uploaded to the REST service. XStream also helps there. For example, to deserialize a bag, you should call:

Bag bag = (Bag) xstream.fromXML(xml);

Clients and applications

So far, this article has described the implementation on the server side. The code implemented on the client side is very similar. You can share the data classes Flight, Traveller, and Bag with the client, and use the XStream API to serialize and deserialize the XML. The only new part on the client is connecting to a URL and reading the content or posting content. The URL connection provided by the Java class library makes this easy:

String xml = "<newinput>input</newinput>";

URL url = new URL("http://luggagetracking.airlinecompany.com/bags/1/newmethod);
URLConnection connection = url.openConnection();

// set POST
Writer output = new OutputStreamWriter(connectiongetOutputStream());

// display result
BufferedReader input = new BufferedReader(
	new InputStreamReader(connection.getInputStream()));

String decodedString;
while ((decodedString = input.readLine()) != null) {

Interoperability with a technology like Ruby on Rails

Although REST doesn't have an exact specification for how to implement it, out-of-the-box support for REST is increasing. Instead of following standards, you need to follow some conventions. For example, Ruby on Rails offers ActiveResource. If you follow the Rails conventions for URLs and output formats, it's easy to connect a Rails Web client to a Java RESTful Web service with minimal overhead.

Scalability and migration to heavyweight SOA

As your application environment grows, it's likely you'll abstract away from the REST implementation details more and more. After a certain level of growth and abstraction, the point comes where the heavy machinery might turn out to be cheaper than your initial lightweight technology. It shouldn't be too hard to extract the actual business logic behind the services and rewrap it in a SOAP package in the new environment.

Find your own application for RESTful SOA!

The airplane company was just an example to illustrate this article. An actual airplane company should go for the heavyweight technology right away. If you work for a smaller company, it might require some imagination to visualize how the SOA and REST principles are best used in practice. Take some time to think about this: It'll pay for itself in the long run!

Designed by sketchbooks.co.kr / sketchbook5 board skin

나눔글꼴 설치 안내

이 PC에는 나눔글꼴이 설치되어 있지 않습니다.

이 사이트를 나눔글꼴로 보기 위해서는
나눔글꼴을 설치해야 합니다.

설치 취소

Sketchbook5, 스케치북5

Sketchbook5, 스케치북5

Sketchbook5, 스케치북5

Sketchbook5, 스케치북5