Enterprise Java

REST 101 For Developers

Local Code Execution

Functions in high-level languages like C are compiled into procedures in assembly. They add a level of indirection that frees us from having to think about memory addresses.rest-easy

Methods and polymorphism in object-oriented languages like Java add another level of indirection that frees us from having to think about the specific variant of a set of similar functions.

Despite these indirections, methods are basically still procedure calls, telling the computer to switch execution flow from one memory location to another. All of this happens in the same process running on the same computer.

Remote Code Execution

This is fundamentally different from switching execution to another process or another computer. Especially the latter is very different, as the other computer may not even have the same operating system through which programs access memory.

It is therefore no surprise that mechanisms of remote code execution that try to hide this difference as much as possible, like RMI or SOAP, have largely failed. Such technologies employ what is known as Remote Procedure Calls (RPCs).

One reason we must distinguish between local and remote procedure calls is that RPCs are a lot slower.rpc

For most practical applications, this changes the nature of the calls you make: you’ll want to make less remote calls that are more coarsely grained.

Another reason is more organizational than technical in nature.

When the code you’re calling lives in another process on another computer, chances are that the other process is written and deployed by someone else. For the two pieces of code to cooperate well, some form of coordination is required. That’s the price we pay for coupling.

Coordinating Change With Interfaces

We can also see this problem in a single process, for instance when code is deployed in different jar files. If you upgrade a third party jar file that your code depends on, you may need to change your code to keep everything working.

Such coordination is annoying. It would be much nicer if we could simply deploy the latest security patch of that jar without having to worry about breaking our code. Fortunately, we can if we’re careful.

Interfaces in languages like Java separate the public and private parts of code.interface

The public part is what clients depend on, so you must evolve interfaces in careful ways to avoid breaking clients.

The private part, in contrast, can be changed at will.

From Interfaces to Services

In OSGi, interfaces are the basis for what are called micro-services. By publishing services in a registry, we can remove the need for clients to know what object implements a given interface. In other words, clients can discover the identity of the object that provides the service. The service registry becomes our entry point for accessing functionality.

There is a reason these interfaces are referred to as micro-services: they are miniature versions of the services that make up a Service Oriented Architecture (SOA).

A straightforward extrapolation of micro-services to “SOA services” leads to RPC-style implementations, for instance with SOAP. However, we’ve established earlier that RPCs are not the best way to invoke remote code.

Enter REST.

RESTful Services

rest-easyRepresentational State Transfer (REST) is an architectural style that brings the advantages of the Web to the world of programs.

There is no denying the scalability of the Web, so this is an interesting angle.

Instead of explaining REST as it’s usually done by exploring its architectural constraints, let’s compare it to micro-services.

A well-designed RESTful service has a single entry point, like the micro-services registry. This entry point may take the form of a home resource.

We access the home resource like any other resource: through a representation. A representation is a series of bytes that we need to interpret. The rules for this interpretation are given by the media type.

Most RESTful services these days serve representations based on JSON or XML. The media type of a resource compares to the interface of an object.

Some interfaces contain methods that give us access to other interfaces. Similarly, a representation of a resource may contain hyperlinks to other resources.

Code-Based vs Data-Based Services

The difference between REST and SOAP is now becoming apparent.

In SOAP, like in micro-services, the interface is made up of methods. In other words, it’s code based.soap

In REST, on the other hand, the interface is made up of code and data. We’ve already seen the data: the representation described by the media type. The code is the uniform interface, which means that it’s the same (uniform) for all resources.

In practice, the uniform interface consists of the HTTP methods GET, POST, PUT, and DELETE.

Since the uniform interface is fixed for all resources, the real juice in any RESTful service is not in the code, but in the data: the media type.

Just as there are rules for evolving a Java interface, there are rules for evolving a media type, for example for XML-based media types. (From this it follows that you can’t use XML Schema validation for XML-based media types.)

Uniform Resource Identifiers

So far I haven’t mentioned Uniform Resource Identifiers (URIs). The documentation of many so-called RESTful services may give you the impression that they are important.

identityHowever, since URIs identify resources, their equivalent in micro-services are the identities of the objects implementing the interfaces.

Hopefully this shows that clients shouldn’t care about URIs. Only the URI of the home resource is important.

The representation of the home resource contains links to other resources. The meaning of those links is indicated by link relations.

Through its understanding of link relations, a client can decide which links it wants to follow and discover their URIs from the representation.

Versions of Services

evolutionAs much as possible, we should follow the rules for evolving media types and not introduce any breaking changes.

However, sometimes that might be unavoidable. We should then create a new version of the service.

Since URIs are not part of the public interface of a RESTful API, they are not the right vehicle for relaying version information. The correct way to indicate major (i.e. non-compatible) versions of an API can be derived by comparison with micro-services.

Whenever a service introduces a breaking change, it should change its interface. In a RESTful API, this means changing the media type. The client can then use content negotiation to request a media type it understands.

What Do You Think?

what-do-you-thinkLiterature explaining how to design and document code-based interfaces is readily available.

This is not the case for data-based interfaces like media types.

With RESTful services becoming ever more popular, that is a gap that needs filling. I’ll get back to this topic in the future.

How do you design your services? How do you document them?
 

Reference: REST 101 For Developers from our JCG partner Remon Sinnema at the Secure Software Development blog.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

7 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Stas
Stas
11 years ago

I have no idea why you said RPC had failed. When working on integration between systems developed by different teams, I want to make sure that parameters I pass and response I get are always validated according to agreements we made. And hence I can’t rely on REST, it is too fuzzy. Here is an example. I want to retrieve some document, containing a list of some items. How do I suppose to pass optional filters in REST? Yeah, with query parameters. How should I specify them to be supported by server? Yeah: “Hello, my friend. Will you please support… Read more »

Rafael Gonzaga
Rafael Gonzaga
11 years ago
Reply to  Stas

I agree with you, i don’t think RPC had failed. I think that every tool has an objective, if we can say that, e.g: here in Brazil, we have a service provided by the govern, that needs that every sells that you do, you have to notify them, which means contact a Webservice that receive data of this sale. It works fine, you know, that process have too much fields in it and would be hard to dealing with as REST service, i guess. So in this case, it works fine and they don’t have reasons to change it, i… Read more »

Ray Sinnema
11 years ago
Reply to  Rafael Gonzaga

Hi Rafael,

I agree that context is important. The context I’m talking about is that of the API Economy, where APIs are exposed to the public that can use them and mash them up at will. There will be “standard” clients consuming the API, but anybody can write their own clients as well.

I stand by my statement that SOAP has failed to scale to that level.

Thanks,
Ray

Rafael
Rafael
11 years ago
Reply to  Ray Sinnema

Hi Ray,
As you said on the post below, for some environments and business that really make sense be used, in other words, the right tool for the right work. Btw, scale anything will be hard if you can’t handle this well enough I think.
[]’s

Ray Sinnema
11 years ago

Hi Stas, Thanks for responding. RPC interfaces are brittle, because they are tightly coupled. This makes it very difficult to evolve server and client separately. This is fine if you can control both. However, this is *not* fine when you can control only one end, say the server. That’s why the API Economy is powered by REST, not SOAP. I’ll have more to post on documenting REST services. I agree that we need to do better in that field. But tight coupling through WSDL is not the answer for the scenarios that I’m talking about. Of course, if WSDL works… Read more »

Stas
Stas
11 years ago
Reply to  Ray Sinnema

Hi Ray, Thanks for explanation. I would argue about tight coupling as I can see it in as enforcing stable integration. When you evolve your rest interface on server part, in order to support old clients, you anyway need to distinct new requests and responses from old requests and responses. And hence you introduce versioning of your API if it changed. You can say, that you don’t change your REST API in the way you break old clients, as you just extend requests with new parameters (optional ones, obviously, like it on not) and extend response with new data. But… Read more »

Ray Sinnema
11 years ago
Reply to  Stas

You’ll only get a “huge list” if you keep adding lots of parameters. That’s not what usually happens. It’s much more likely that you’ll add new resources. Furthermore, a longer parameter list isn’t harder to parse. Tools like JAX-B do it for you quite easily and give you the same type-safety as the WSDL-tools. REST really isn’t more error-prone. Also, you don’t have to support old parameters forever. Only as long as there are clients out there that use it. Or even shorter if you don’t mind breaking them. Even if we did introduce a new “version” of our API,… Read more »

Back to top button