Communication System
Stream synchronization
Persistence
- Persistent communication
➥Definition:
- Transient communication
➥Examples: email, pony express
mail stored and sorted to be sent out depending on destination and when pony and rider available
PersistenceSynchronicity
– Example: transport-level communication services offer transient communication
Example: Typical network router
• Asynchronous communication
• Synchronous communication
• Six combinations of persistence and synchronicity
persistence and synchronicity combination
Persistent asynchronous communication (e.g., email)
Persistent synchronous communication
Transient asynchronous communication (e.g., UDP)
Receipt-based transient synchronous communication
Delivery-based transient synchronous communication at message delivery (e.g., asynchronous RCP)
Response-based transient synchronous communication (RPC)
•Persistent communication
Persistence and Synchronicity: Comments
• Transient synchronous comm: response-based, delivery-based and reply-based
• Transient asynchronous comm: messagepassing systems
• Persistent comm: developing of middleware for large-scale interconnected networks; failure masking and recovery
Message-Oriented Transient Communication
• Many distributed systems built on top of the simple message-oriented model
➥Example: Berkeley sockets – Socket?
Berkeley Socket Primitives
Message-Passing Interface(MPI)
•Sockets designed for network communication
(e.g., TCP/IP)
➥Support simple send/receive primitives
➥Use general-purpose protocol stacks such as TCP/IP
• Abstraction not suitable for other protocols in clusters of workstations or massively parallel systems
➥Need an interface with more advanced primitives
• A large number of incompatible proprietary libraries and protocols
➥Need for a standard interface
• Message-passing interface (MPI)
➥Hardware independent
➥Designed for parallel applications (uses transient communication)
• Key idea: communication between groups of processes
➥Each endpoint is a (groupID, processID) pair
• Support most of the forms of transient communication (c )-(f)
MPI Primitives
Message-Oriented Persistent Communication
Message-Queuing Model
• Message queuing systems or Message-Oriented
Middleware (MOM)
➥Support asynchronous persistent communication
➥Intermediate storage for a message while sender/receiver is inactive
➥Example application: email
• Communicate by inserting messages in queues
• The sender is only guaranteed that the message will be eventually inserted in the recipient’s queue – When/if the message will be read?
• General architecture of
MOM
Message-Queuing System
The general organization of a message-queuing system with routers
Stream-Oriented Communication
Data Stream
• Message-oriented communication: request-response
➥When communication occurs and speed do not affect correctness
• Timing is crucial in certain forms of communication
➥Examples: audio and video (“continuous media”)
➥30 frames/s video => receive and display a frame every 33ms
• Stream-oriented comm is required!
• A data stream is a sequence of data units • Discrete or continuous:
➥Discrete stream
➥Continuous stream
• For the continuous stream, three transmission modes:
➥Asynchronous transmission mode
• No timing requirements
➥Synchronous transmission mode
• Maximum end-to-end delay
➥Isochronous transmission mode
• Both minimum and maximum end-to-end delay
Setup Stream
Quality of Service(QoS)
• Time-dependent and other requirements are specified as a quality of service (QoS)
➥Requirements/desired guarantees from the underlying systems
➥Application specifies workload and requests a certain service quality
➥Contract between the application and the system
Specify QoS: Token Bucket
• The principle of a token bucket algorithm
➥Parameters (rate r, burst b)
➥Rate is the average rate, burst is the maximum number of packets that can arrive simultaneously
Specify QoS: Flow Specification
QoS: Set Up Stream
• Lack of a model
➥Specify QoS parameter
➥Generically describe resources in any communication system
➥Translate QoS parameters to resource usage
• Expressing and establishing QoS is often difficult
• Incompatible approaches exist
QoS: RSVP
Stream Synchronization
• Deal with maintaining temporal relations between streams
• Example:
➥A slide show on the Web that has been enhanced with audio
➥A movie play
• Two issues:
➥Synchronization mechanism
➥The distribution of synchronization mechanisms
Synchronization Mechanisms
Resources
The fundamental concept in any RESTful API is the resource. A resource is an object with a type, associated data, relationships to other resources, and a set of methods that operate on it. It is similar to an object instance in an object-oriented programming language, with the important difference that only a few standard methods are defined for the resource (corresponding to the standard HTTP GET, POST, PUT and DELETE methods), while an object instance typically has many methods.
Resources can be grouped into collections. Each collection is homogeneous so that it contains only one type of resource, and unordered. Resources can also exist outside any collection. In this case, we refer to these resources as singleton resources. Collections are themselves resources as well.
Collections can exist globally, at the top level of an API, but can also be contained inside a single resource. In the latter case, we refer to these collections as sub-collections. Sub-collections are usually used to express some kind of “contained in” relationship. We go into more detail on this in Relationships.
The diagram below illustrates the key concepts in a RESTful API.
We call information that describes available resources types, their behavior, and their relationships the resource model of an API. The resource model can be viewed as the RESTful mapping of the application data model.
Resource Data
Resources have data associated with them. The richness of data that can be associated with a resource is part of the resource model for an API. It defines, for example, the available data types and their behavior.
Based on my experience, I have developed a strong conviction that the JSON data model has just the right “richness” so that it is an ideal data model for RESTful resources. I would recommend that everybody use it.
In JSON, just three types of data exist:
- scalar (number, string, boolean, null).
- array
- object
Scalar types have just a single value. Arrays contain an ordered list of values of arbitrary type. Objects consist of an unordered set of key: value pairs (also called attributes, not to be confused with XML attributes), where the key is a string and the value can have an arbitrary type. For more detailed information on JSON, see the JSON web site.
Why the strong preference for JSON? In my view, JSON has the right balance between expressiveness and broad availability. The three types of data (scalars, arrays and objects) are powerful enough to describe in a natural way virtually all the data that you might want to expose as a resource, and at the same time, these types are minimal enough so that almost any modern language has built-in support for them.
XML would be the other obvious contender. Actually, in the final incarnation of the RHEV-M API, XML is used to describe resources, via an XMLSchema definition. With hindsight, I believe that the XML data model is a bad choice for a RESTful API. On one side, it is too rich, and on the other side, it lacks features. XML, as an SGML off-shoot, is in my view great for representing structured documents, but not for representing structured data.
Features of XML that are too rich include:
- Attributes vs elements. An XML element can have both attributes as well as sub-elements. A data item associated with a resource could be encoded in either one, and it would not be clear beforehand which one a client or a server should use.
- The relevance of order. The order between child-elements is relevant in XML. It is not natural in my view for object attributes to have ordered.
The limitations of the XML data model are:
- Lack of types. Elements in XML documents do not have types, and in order to use types, one would have to use e.g. XMLSchema. XMLSchema, unfortunately, is a strong contender for the most convoluted specification ever written.
- Lack of lists. XML cannot natively express lists. This can lead to issues whereby it is not clear whether a certain element is supposed to be a list or an object, and where that element ends up being both.
Application Data
We define the data that can be associated with a resource in terms of the JSON data model, using the following mapping rules:
- Resources are modeled as a JSON object. The type of the resource is stored under the special key: value pair “_type”.
- Data associated with a resource is modeled as key: value pairs on the JSON object. To prevent naming conflicts with internal key: value pairs, keys must not start with “_”.
- The values of key: value pairs use any of the native JSON data types of string, number, boolean, null, or arrays thereof. Values can also be objects, in which case they are modeling nested resources.
- Collections are modeled as an array of objects.
We will also refer to key: value pairs as attributes of the JSON object, and we will be sloppy and use that same term for data items associated with resources, too. This use of attributes is not to be confused with XML attributes.
REST Metadata
In addition to exposing application data, resources also include other information that is specific to the RESTful API. Such information includes URLs and relationships.
The following table lists generic attributes that are defined and have a specific meaning on all resources. They should not be used for mapping application model attributes.
Other Data
Apart from application data, and REST metadata, sometimes other data is required as well. This is usually “RPC like” data where a setting is needed for an operation, and where that setting will not end up being part of the resource itself.
One example that I can give here is where a resource creation needs a reference to another resource that is used during the creation, but where that other resource will not become part of the resource itself.
It is the responsibility of the API code to merge the application data together with the REST metadata and the other data into a single resource, resolving possible naming conflicts that may arise.
Representations
We have defined resources and defined the data associated with them in terms of the JSON data model. However, these resources are still abstract entities. Before they can be communicated to a client over an HTTP connection, they need to be serialized to a textual representation. This representation can then be included as an entity in an HTTP message body.
The following representations are common for resources. The table also lists the appropriate content-type to use:
Note: all these content types use the “x-” experimental prefix that is allowed by RFC2046.
JSON Format
Formatting a resource to JSON is trivial because the data model of a resource is defined in terms of the JSON model. Below we give an example of a JSON serialization of a virtual machine:
{
"_type": "vm",
"name": "A virtual machine",
"memory": 1024,
"cpu": {
"cores": 4,
"speed": 3600
},
"boot": {
"devices": ["cdrom", "harddisk"]
}
}
YAML Format
Formatting to YAML is only slightly different than representing a resource in JSON. The resource type that is stored under the “_type” key/value pair is serialized as a YAML ”!type” annotation instead. The same virtual machine as above, now in YAML format:
!vm
name: A virtual machine
memory: 1024
cpu:
cores: 4
speed: 3600
boot:
devices:
- cdrom
- harddisk
XML Format
XML is the most complex representation format due to both its complexity as well as its limitations. I recommend the following rules:
Resources are mapped to XML elements with a tag name equal to the resource type.
Attributes of resources are mapped to XML child elements with the tag name equal to the attribute name.
Scalar values are stored as text nodes. A special “type” attribute on the containing element should be used to refer to an XML Schema Part 2 type definition.
Lists should be stored as a single container element with child elements for each list item. The tag of the container element should be the English plural of the attribute name. The item tag should be the English singular of the attribute name. Lists should have the “xd:list” type annotation.
The same VM again, now in XML:
<vm xmlns:xs="http://www.w3.org/2001/XMLSchema">
<name type="xs:string">My VM</name>
<memory type="xs:int">1024</memory>
<cpu>
<cores type="xs:int">4</cores>
<speed type="xs:int">3600</speed>
</cpu>
<boot>
<devices type="xs:list">
<device type="xs:string">cdrom</device>
<device type="xs:string">harddisk</device>
</devices>
</boot>
</vm>
HTML Format
The exact format of a HTML response can be API dependent. HTML is for human consumption, and the only requirement is therefore that it be easy to understand. A simple implementation may choose the following representation:
- For a collection, a <table> with a column per attribute where each object is listed in a separate row.
- For a resource, a <table> with two columns, one with all the attribute names, one with the corresponding attribute value.
Content-Types
As can be seen above, I am advocating the use of a generic content types “application/x-resource+format” and “application/x-collection+format”. In my view this represents the right middle ground between two extremes that are commonly found in RESTful APIs:
Some RESTful APIs only use the “bare” XML, JSON or YAML content types. An example of such as API is the Red Hat Enterprise Virtualization API. In this case, the content type expresses nothing but the fact that an entity is in XML, JSON or YAML format. In my view, this is not sufficient. Resources and collections have some specific semantics around for example the use of “href” attributes, “link” attributes, and types. Therefore, these are a specialization of XML, JSON and YAML and should be defined as such.
Other RESTful APIs define a content-type for every resource type that exists in the resource model. Examples of such APIs include for example VMware’s vSphere Director API. In my view, this is not proper either. Specifying detailed content types invites both the API implementer, as well as a client implementer to think about these types as having specific interfaces. In my view though, all resources should share the same basic interface, which is defined by the RESTful design principles and expressed by the “application/x-resource” content type.
One reason that is sometimes given in favor of defining detailed content types is that this way, the content type can be associated with a specific definition in some type definition language (such as XMLSchema). This, supposedly, facilitates client auto-discovery because a client can know available attributes for a certain type. I go into a lot of detail on this topic in Forms but the summary is that I do not agree with this argument.
Selecting a Representation Format
Clients can express their preference for a certain representation format using the HTTP “Accept” header. The HTTP RFC defines an elaborate set of rules in which multiple formats can be requested, each with its own priority. In the following example, the client tells the API that it accepts only YAML input:
GET /api/collection
Accept: application/x-collection+yaml
Fielding’s Constraints
Fielding created these constraints with the ultimate goal of making applications faster, more reliable, and easier to scale.
As a web service designer, your service should try to comply with these constraints as closely as possible in order to reap their benefits. So let's dive into them.
Constraint #1: Client-Server Architecture
The first constraint proposed by REST is the separation of the server from its client. You should encourage separation of concerns between your server and clients wherever possible. Your goal should be to maximize the division of labour — and minimize overlap — between the two.
The server, or back end, is typically responsible for storing your application’s persistent data, along with all the business logic required to interact with it. This could include user authentication, authorization, data validation, and so on.
The client, or front end, is responsible for making requests to the service, then doing something meaningful with the response that it receives.
The client itself may be a web service, in which case it simply consumes the data. Alternatively, it may be user-facing. An example of this would be a web or mobile app. Here, it is also responsible for both presenting the data to the user, and presenting an interface for the user to interact with it.
You should be able to treat each of these two components as a black box with respect to one another. This way, they can be modified independently. This encourages modularity within the application.
This concept is not unique to RESTFul applications, or even web applications. Most developers try to break up their projects into independent components anyway. But by stating this as an explicit constraint of RESTful design, Fielding further encourages this practice.
Lastly, reducing the number of things that the server is responsible reduces the amount of logic necessary. This, in turn, allows for better scalability and increased performance.
Constraint #2: Statelessness
The next important constraint proposed by REST is that of statelessness.
Broadly speaking, the main goal of a stateless service is to make incoming requests self-sufficient and execute them in complete isolation.
Each request must have all the information that the server might need to properly process it and respond. In other words, the server does not need to use information from previous requests. The responsibility of maintaining the application state of a client is thus handed off to the client itself.
In order to understand this, consider a very simple web service responsible for responding to a user’s search queries. The exact representation of the entity being searched for is irrelevant. What’s important is that, instead of returning hundreds of search results in a single go, the server employs pagination: returning only 10 results at a time out of an arbitrarily large result set.
In a traditional “stateful” model of development, the server may be designed in such a way that it keeps track of all of its clients, along with all the pages they’ve already accessed.
And so, when a request comes in for a new page, the server’s ability to look up the client in its system and determine the most recent page is received.
Then the server can proceed to respond with the next page, and update its system to reflect this. This goes on as the client continues navigating the result set.
In an alternate, stateless, approach, the responsibility for maintaining its state is decentralized and shifted onto the client. The client then must specify the actual page numbers of the result they want, as opposed to asking for the next page. For example:
GET http://my-awesome-web-service.com/pages/1
GET http://my-awesome-web-service.com/pages/3
A stateless approach brings a couple of major advantages with it. First off, keeping track of client state becomes increasingly taxing on a server as the number of clients scales.
Secondly, and more importantly, a stateless service is also easily distributable. If a server is responsible for maintaining information about an application’s state, then it is also imperative that future requests are routed to the server that is storing this information.
If there are hundreds of servers responsible for processing incoming requests, then there must be some mechanism in place to ensure that requests from a specific client always end up at a specific server instance.
In the event that a server instance goes down, all information about a client’s state that was stored on that server goes down with it.
Of course, you could come up with an architecture where server instances can share data among themselves. But this adds quite a bit of complexity.
A stateless service, by contrast, makes it much simpler to add and remove server instances on an ad-hoc basis. You can then further balance the load between them as needed.
Since the servers are agnostic to the incoming requests, scaling up is just a matter of adding more servers to the load balancer. Similarly, killing servers — intentionally or otherwise — does not impact a service’s reliability.
Of course, this simplicity comes at a cost. Having the client attach identical data with every request is a potential source of redundancy. Bandwidth isn’t free, so any additional information transferred adds some amount of overhead.
Constraint#3: Cache
The third constraint is that of explicit cacheability. The idea is to mark messages returned by service as explicitly cacheable or non-cacheable. If they’re cacheable, the server should figure out the duration for which the response is valid.
If the client has access to a valid cached response for a given request, it avoids repeating the same request. Instead, it uses its cached copy. This helps alleviate some of the server’s work, and thus contributes to scalability and performance.
This is a form of optimistic replication — also known as lazy replication — where the service does not try to guarantee 100% consistency between itself and its clients unless absolutely critical. Instead, it makes this sacrifice in exchange for a gain in perceived performance.
For example, an API corresponding to a blogging platform may choose to make the list of blog posts cacheable for a couple of minutes if it knows that the frequency with which people try to access the posts far exceeds the frequency with which new posts are created. As a result, users may occasionally be presented with stale data, but the system as a whole performs better.
Of course, the cacheability of a resource and its duration are not universal and require some consideration. If you chose incorrectly, this may frustrate your users.
Web services typically achieve cacheability using the standard Cache-Control header. Sometimes they do this in conjunction with other headers specified by HTTP.
The Cache-Control header effectively serves as a switch, determining whether a browser should cache the response in question.
Resources marked as private are cached only by the client, and are therefore limited to that one client only.
Resources marked public, on the other hand, may be cached by one or more intermediate proxies between the service and the client.
As a result, these resources may potentially be served to multiple users. Alternatively, one may pass in the argument no-cache and completely stop any caching of the resource.
Here’s what one of these Cache-Control headers looks like:
Cache-Control: public;max-age=3431901
The header also lets you specify the duration for which the resource is valid. This lets the client know when it should stop using its cached copy and request a new copy.
Here’s the logic behind this:
Apart from this, HTTP also has mechanisms in place to perform what is known as a conditional request. The goal here is for the server to return certain resources to the client only when specific conditions are met.
Assuming the client has a saved copy of a resource in its cache, it can make a request to the server to determine whether there is an updated copy of that same resource. If there is one, the server returns the new copy. Otherwise, it tells the client to keep using its local copy.
This helps prevent the redundant transfer of data over the network, while also making sure that the client has access to fresh data at all times.
There are a couple of ways HTTP lets you accomplish this:
Caching Approach #1: If-Modified-Since/Last-Modified
Along with every response that the server sends back, it may choose to attach a Last-Modified timestamp. This indicates when the resource was last changed.
When the client needs to request the resource again in the future, it makes the request to the server as it normally would, but with a relevant If-Modified-Since header. This tells the server to return the new copy of the resource if one exists.
Otherwise, the server returns the status code 304, which instructs the client to keep using the copy it already has.
Caching Approach #2: If-None-Match/ETag
This scheme works similar to the previous one, except for the way resources are identified. Instead of using timestamps, the server sends back with each response a unique hash explaining the state of the resource at that point in time (known as the ETag).
For future requests, the client sends the relevant ETag to the server. If a resource exists with the same ETag, the server tells the client to keep using the cached copy. Otherwise, the server sends a new one back to the client.
Caching is complicated. As your service begins to add more users, you’ll want to learn more about caching and how you can use it to your advantage.
Constraint #4: Uniform Interface
The Uniform Interface (or Uniform Contract) tells a RESTful service what to serve, in the form of a document, image, non-virtual object, etc.
REST does not, however, dictate how you choose to interact with these resources, as long as they are consistent and well understood.
In general, before a client can interact with a RESTful service, it needs to agree on:
Identification: There must be a way to uniquely identify every resource that the service has to offer.
Manipulation: There must be a standard set of operations that can be performed on any given resource with predictable outcomes. The outcomes of these operations must also be self-descriptive and uniquely understood.
HTTP, for example, makes use of URLs for the identification of resources. It also uses a handful of action verbs and well-documented status codes to facilitate interaction with the resource. (For a more in-depth detailed explanation of HTTP’s constructs, you can go back and read Part I of this series.)
Up until this point, we have considered RESTful services as being strictly tied to HTTP. With regards to web services, this is almost always accurate.
But in theory, REST can be implemented over any protocol that provides a decent way to achieve the two conditions I described above. For this reason, REST is sometimes also referred to as REST over HTTP to clarify that it’s being used over the web.
Constraint #5: A Layered System
A layered system builds on the client-server constraint we discussed earlier, and enforces an even more separation of concerns. The overall architecture of your service can be separated into individual layers, each serving a specific function.
More importantly, each layer must act independently, and interact only with the layers immediately adjacent to it. This forces requests to propagate in a predictable manner, without bypassing layers.
For example, in order to scale, you may make use of a proxy behaving like a load balancer. The sole purpose of the proxy would then be to forward incoming requests to the appropriate server instance.
The client, on the other hand, does not need to be aware of this division. It simply continues making requests to the same URL, unconcerned with the details of how the requests are being processed.
Similarly, there may be another layer in the architecture responsible for caching responses in order to minimize the work needed to be done by the server.
Another layer may behave like a gateway, and translate HTTP requests to other protocols.
One way you could use this would be to implement an FTP server. The client would continue to make requests to what it perceives to be an HTTP server, while you actually have an FTP server doing the work under the hood.
Just like the client-server distinction, this layered system constraint minimizes the risk of coupling functionality in your service, but at the expense of additional overhead in the system.
RESTful Key Elements
Web services have really come a long way since its inception. In 2002, the Web consortium had released the definition of WSDL and SOAP web services. This formed the standard of how web services are implemented.
In 2004, the web consortium also released the definition of an additional standard called RESTful. Over the past couple of years, this standard has become quite popular. And is being used by many of the popular websites around the world which include Facebook and Twitter.
REST is a way to access resources which lie in a particular environment. For example, you could have a server that could be hosting important documents or pictures or videos. All of these are an example of resources. If a client, say a web browser needs any of these resources, it has to send a request to the server to access these resources. Now REST defines a way on how these resources can be accessed.
The key elements of a RESTful implementation are as follows:
- Resources – The first key element is the resource itself. Let assume that a web application on a server has records of several employees. Let's assume the URL of the web application is http://demo.guru99.com. Now in order to access an employee record resource via REST, one can issue the command http://demo.guru99.com/employee/1 - This command tells the web server to please provide the details of the employee whose employee number is 1.
- Request Verbs - These describe what you want to do with the resource. A browser issues a GET verb to instruct the endpoint it wants to get data. However, there are many other verbs available including things like POST, PUT, and DELETE. So in the case of the example http://demo.guru99.com/employee/1 , the web browser is actually issuing a GET Verb because it wants to get the details of the employee record.
- Request Headers – These are additional instructions sent with the request. These might define the type of response required or the authorization details.
- Request Body - Data is sent with the request. Data is normally sent in the request when a POST request is made to the REST web service. In a POST call, the client actually tells the web service that it wants to add a resource to the server. Hence, the request body would have the details of the resource which is required to be added to the server.
- Response Body – This is the main body of the response. So in our example, if we were to query the web server via the request http://demo.guru99.com/employee/1 , the web server might return an XML document with all the details of the employee in the Response Body.
- Response Status codes – These codes are the general codes which are returned along with the response from the web server. An example is the code 200 which is normally returned if there is no error when returning a response to the client.
Restful Methods
The below diagram shows mostly all the verbs (POST, GET, PUT, and DELETE) and an example of what they would mean.
Let's assume that we have a RESTful web service is defined at the location. http://demo.guru99.com/employee . When the client makes any request to this web service, it can specify any of the normal HTTP verbs of GET, POST, DELETE and PUT. Below is what would happen If the respective verbs were sent by the client.
- POST – This would be used to create a new employee using the RESTful web service
- GET - This would be used to get a list of all employee using the RESTful web service
- PUT - This would be used to update all employee using the RESTful web service
- DELETE - This would be used to delete all employee using the RESTful web service
Let's take a look from a perspective of just a single record. Let's say there was an employee record with the employee number of 1.
The following actions would have their respective meanings.
POST – This would not be applicable since we are fetching data of employee 1 which is already created.
GET - This would be used to get the details of the employee with Employee no as 1 using the RESTful web service
PUT - This would be used to update the details of the employee with Employee no as 1 using the RESTful web service
DELETE - This is used to delete the details of the employee with Employee no as 1
Define the API of RESTful web services using RESTful URLs
A RESTful API is an application program interface (API) that uses HTTP requests to GET, PUT, POST and DELETE data.
A RESTful API -- also referred to as a RESTful web service -- is based on representational state transfer (REST) technology, an architectural style and approach to communications often used in web services development.
REST technology is generally preferred to the more robust Simple Object Access Protocol (SOAP) technology because REST leverages less bandwidth, making it more suitable for internet usage.
An API for a website is code that allows two software programs to communicate with each other.
The API spells out the proper way for a developer to write a program requesting services from an operating system or other application.
The REST used by browsers can be thought of as the language of the internet. With cloud use on the rise, APIs are emerging to expose web services.
REST is a logical choice for building APIs that allow users to connect and interact with cloud services.
RESTful APIs are used by such sites as Amazon, Google, LinkedIn and Twitter.
How RESTful APIs work
A RESTful API breaks down a transaction to create a series of small modules. Each module addresses a particular underlying part of the transaction.
This modularity provides developers with a lot of flexibility, but it can be challenging for developers to design from scratch.
Currently, the models provided by Amazon Simple Storage Service, Cloud Data Management Interface and OpenStack Swift are the most popular.
A RESTful API explicitly takes advantage of HTTP methodologies defined by the RFC 2616 protocol.
They use GET to retrieve a resource; PUT to change the state of or update a resource, which can be an object, file or block; POST to create that resource, and DELETE to remove it.
With REST, networked components are a resource you request access to -- a black box whose implementation details are unclear.
The presumption is that all calls are stateless; nothing can be retained by the RESTful service between executions.
Because the calls are stateless, REST is useful in cloud applications. Stateless components can be freely redeployed if something fails, and they can scale to accommodate load changes.
This is because any request can be directed to any instance of a component; there can be nothing saved that has to be remembered by the next transaction.
That makes REST preferred for web use, but the RESTful model is also helpful in cloud services because binding to a service through an API is a matter of controlling how the URL is decoded.
Cloud computing and microservices are almost certain to make RESTful API design the rule in the future.
Pros and Cons of RESTful architecture
Given those areas, I can give a rough overview, but I can't draw your conclusions for you. There are two chief areas where the two protocols differ:
- Message format
- Service discovery
The message format is the easiest to understand. The SOAP packaging for both requests and responses is fairly heavyweight. There's the SOAP envelope that contains both a header and a body section.
The header can be used by several filters in the request chain to perform some sort of identification, authorization, etc. However, XML is expensive to parse, which yields a certain penalty to the scalability of your system. Just how much depends on the SOAP processing layer in your stack.
Service discovery is where you probably will have the most contention. REST by its very nature provides predictable endpoints, and the content of the request is a simple HTTP request.
The benefit is that there is no additional overhead, and end users can pretty much guess how to do what they need once they understand the URL structure of your site. Of course, naive security conscious people will see that as a weakness.
After all, with SOAP, you have to consume a WSDL to know what the endpoints are. Of course, with SOAP you were given the entire message format so you can make more targeted attacks.
Broken down by the categories you gave:
Security
Neither is inherently more secure than the other. Use good security principles:
Encrypt communications
Make sure you authenticate and authorize users before processing
Good coding habits to avoid direct attacks
And that's just the short list.
Remember obscurity != security.
Performance
Both raw performance and scalability will go to REST due to the request following simple HTTP protocols. Most SOAP stacks use SAX parsing (event-based parsing) which greatly improves the scalability of SOAP stacks, but there is a measurable impact on the overhead. SOAP has the normal HTTP processing overhead in addition to the XML parsing overhead. REST just has the HTTP processing overhead.
Complexity
From the system's perspective, REST wins. There are fewer moving parts, a leaner request chain, etc. That means it's easier to make reliable.
From the programmer's perspective, SOAP can win if the IDE or framework you are using provides good support for it. Essentially, with REST the onus is on you to perform the preprocessing work (authentication/authorization/etc) while with SOAP much of that can be accomplished with a pluggable processing chain.
My Preference
I'm very comfortable with HTTP requests, and I know how the web works. As a result, the REST approach is more preferable for me.
However, I do know that some of my clients are uncomfortable with that. They've read some industry article denouncing the security of REST vs. SOAP, etc.
Bottom line is that neither approach guarantees security. It's on you to make sure the application is as secure as it needs to be.
Obviously, a social web application doesn't demand (or desire) as much security as a bank or government system.
Many SOAP stacks include processors that you can plug in to provide some semblance of security, but it is still your responsibility to search them out and put them in place.
How Spring Supports RESTful Web Services?
As I told you in the first paragraph that we can use Spring MVC to create and consume RESTful web services. Now, let’s see those supports in a little bit more details so that you can make the best use of them and quickly develop the RESTful services you always wanted to.
1. In Spring MVC, a controller can handle requests for all HTTP methods, which is a backbone of RESTful web services. For example, you can handle the GET method to perform read operation, POST method to create resources, PUT method to update resources, and DELETE method to remove resources from the server. From Spring 3.2 onwards, you can also handle PATCH requests.
2. In case of REST, the representation of data is very important and that’s why Spring MVC allows you to bypass View-based rendering altogether by using the @ResponseBody annotation and various HttpMessgeConverter implementations.
By using these two you can directly send a response to client e.g. the resource clients wants and also in the format they want. I’ll write more about @ResponseBody annotations and HttpMessageConverter in this blog in the coming articles.
3. The Spring 4.0 release added a dedicated annotation @RestController to make the development of RESTful web services even easier.
If you annotate your controller class using @RestController instead of @Controller then Spring applied message conversations to all handler methods in the controller.
This means you don’t need to annotate each method with the @ResponseBody annotation. This also makes your code much cleaner. You can read more about it on my post difference between @Conroller and @RestController in Spring.
4. One of the main difference between REST web services and a normal web application is that REST pass resource identifier data in URI itself e.g. /messages/101 while web application normally uses a query parameter e.g. /messages?Id=101.
If you remember, we use @RequestParam to get the value of those query parameter but not to worry, Spring MVC also provides a @PathVariable annotation which can extract data from URL. It allows the controller to handle requests for parameterized URLs.
You can learn more about @PathVariable in my post difference between @RequestParam and @PathVaraible in Spring.
5. Another key aspect of RESTful web services is Representation e.g. the same resource can be represented in different formats e.g. JSON, XML, HTML etc. Thankfully Spring provides several view implementations and views resolvers to render data as JSON, XML, and HTML.
For example, ContentNegotiatingViewResolver can look at the file extension of requests or Accept header to find out the correct representation of a resource for the client.
6. Similar to @ResponseBody annotation, which is used for converting the response to the format client wants (by using HttpMessageConverts), Spring MVC also provides @RequestBody annotation, which uses HTtpMethodConverter implementations to convert inbound HTTP data into Java objects passed into a controller’s handler method.
7. Spring Framework also provides a Template class, RestTemplate, similar to JdbcTemplate, and JmsTemplate, which can consume REST resources. You can use this class to test your RESTful web service or develop REST clients.
I have already talked about this class in my earlier blog posts and you can see this tutorial for a live example of using RestTemplate to consume JSON from a RESTful web service in Java.
These were some of the important features of Spring MVC framework which assist in developing RESTful web services. As I told the most important reason for me to choose Spring for developing RESTful resources is that I can use my existing knowledge of framework, which means no steep learning curve. If you look at the high level, developing RESTful services is not very different from developing a web application.
The fundamental difference is that in the case of former, we mostly deal with human users where in case of REST, you have to deal with non-human users mostly rich JavaScript clients and mobile applications. This key difference then derives other differences e.g. representing data in JSON or XML instead of HTML which is suitable for human users but not for non-human systems.
JAX-RS is just an API
the REST paradigm has been around for quite a few years now and it’s still getting a lot of attention.
A RESTful API can be implemented in Java in a number of ways: you can use Spring, JAX-RS, or you might just write your own bare servlets if you’re good and brave enough. All you need is the ability to expose HTTP methods – the rest is all about how you organize them and how you guide the client when making calls to your API.
As you can make out from the title, this article will cover JAX-RS. But what does “just an API” mean? It means that the focus here is on clarifying the confusion between JAX-RS and its implementations and on offering an example of what a proper JAX-RS web app looks like.
Inclusion in Java EE
JAX-RS is nothing more than a specification, a set of interfaces and annotations offered by Java EE. And then, of course, we have the implementations; some of the more well known are RESTEasy and Jersey.
Also, if you ever decide to build a JEE-compliant application server, the guys from Oracle will tell you that, among many other things, your server should provide a JAX-RS implementation for the deployed apps to use. That’s why it’s called Java Enterprise Edition Platform.
Another good example of specification and implementation is JPA and Hibernate.
Lightweight Wars
So how does all this help us, the developers? The help is in that our deployables can and should be very thin, letting the application server provide the needed libraries. This applies when developing a RESTful API as well: the final artefact should not contain any information about the used JAX-RS implementation.
Sure, we can provide the implementation (here‘s a tutorial for RESTeasy). But then we cannot call our application “Java EE app” anymore. If tomorrow someone comes and says “Ok, time to switch to Glassfish or Payara, JBoss became too expensive!“, we might be able to do it, but it won’t be an easy job.
If we provide our own implementation we have to make sure the server knows to exclude its own – this usually happens by having a proprietary XML file inside the deployable. Needless to say, such a file should contain all sorts of tags and instructions that nobody knows nothing about, except the developers who left the company three years ago.
Always Know your Server
We said so far that we should take advantage of the platform that we’re offered.
Before deciding on a server to use, we should see what JAX-RS implementation (name, vendor, version and known bugs) it provides, at least for Production environments. For instance, Glassfish comes with Jersey, while Wildfly or JBoss comes with RESTEasy.
This, of course, means a little time spent on research, but it’s supposed to be done only once, at the beginning of the project or when migrating it to another server.
Example
If you want to start playing with JAX-RS, the shortest path is: have a Maven web app project with the following dependency in the pom.xml:
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
<scope>provided</scope>
</dependency>
We’re using JavaEE 7 since there are already plenty of application servers implementing it. That API jar contains the annotations that you need to use, located in package javax.ws.rs. Why is the scope “provided”? Because this jar doesn’t need to be in the final build either – we need it at compile time and it is provided by the server for the run time.
After the dependency is added, we first have to write the entry class: an empty class which extends javax.ws.rs.core.Application and is annotated with javax.ws.rs.ApplicationPath:
@ApplicationPath("/api")
public class RestApplication extends Application {
}
We defined the entry path as being /api. Whatever other paths we declare for our resources, they will be prefixed with /api.
Next, let’s see a resource:
@Path("/notifications")
public class NotificationsResource {
@GET
@Path("/ping")
public Response ping() {
return Response.ok().entity("Service online").build();
}
@GET
@Path("/get/{id}")
@Produces(MediaType.APPLICATION_JSON)
public Response getNotification(@PathParam("id") int id) {
return Response.ok()
.entity(new Notification(id, "john", "test notification"))
.build();
}
@POST
@Path("/post/")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response postNotification(Notification notification) {
return Response.status(201).entity(notification).build();
}
}
We have a simple ping endpoint to call and check if our app is running, a GET and a POST for a Notification (this is just a POJO with attributes plus getters and setters).
Deploy this war on any application server implementing JEE7 and the following commands will work:
curl http://localhost:8080/simple-jaxrs-ex/api/notifications/ping/
curl http://localhost:8080/simple-jaxrs-ex/api/notifications/get/1
curl -X POST -d '{"id":23,"text":"lorem ipsum","username":"johana"}'
http://localhost:8080/simple-jaxrs-ex/api/notifications/post/
--header "Content-Type:application/json"
Where simple-jaxrs-ex is the context-root of the webapp.
This was tested with Glassfish 4.1.0 and Wildfly 9.0.1.Final. Please note that the last two commands won’t work with Glassfish 4.1.1, because of this bug. It is apparently a known issue in this Glassfish version, regarding the serialization of JSON (if you have to use this server version, you’ll have to manage JSON marshalling on your own)
Specifications
Following are the most commonly used annotations to map a resource as a web service resource.
A Comparison of JAX-RS Implementations
s someone remarked elsewhere, there's a strange phenomenon regarding buses: you wait for ages for one, then three come along at once! The same seems to be true for JAX-RS implementations. At the moment we have:
- CXF - which is a merger between XFire and Celtix (an Open Source ESB, sponsored by IONA and originally hosted at ObjectWeb).
- Jersey - the JAX-RS Reference Implementation from Sun.
- RESTEasy - JBoss's JAX-RS project.
- Restlet - probably the first REST framework, which existed prior to JAX-RS.
Irrespective of the various debates around REST, it cannot be argued that there is a need for REST support in the Java language and JAX-RS is it. But if you're new to REST, which one of these implementations is the one for you? Well, Solomon Duskis has set out to try to shine a light on that debate. As he also points out on dzone:
JAX-RS Media Types
introduction to @Consumes and @Produces
All resource methods can consume and produce content of almost any type. If you make a POST request to a URI, such as API/books, the REST API expects the HTTP body to contain a payload that represents the resource it should create.
This resource can be represented using any media type. Although typically, it will be represented in either, JSON or XML, but it could be plain text, binary or a custom format. It doesn’t matter, as long as there is a method in the resource class that can consume that media type.
Resource Method Selection
So, the question is: how does the resource class know the payload’s media type and how does it select the right method to deal with it? Well, in the header of the HTTP request, there is a content-type field that specifies the media type and on the other end, the server end, the resource class has a method annotated with the matching type.
So, for example: If a request has the content-type set to application/json the resource method that consumes this request is the method annotated with the same type, and likewise if the content type were application/xml the method annotated with MediaType APPLICATION_XML would handle that request.
Consume and Produce JSON
Just as a method can consume a payload of a given type, it can produce a response payload of a specific media type too. In the case of a POST request, the created resource can be returned back to the client. Conventionally, it is returned back in the same format as it was received. So returns back as JSON, if it was POSTed in JSON format, nevertheless, this does not have to be the case.
There is another HTTP header that specifies the accepted return media-type and there is a matching annotation on the resource method also. Such a method would be annotated with the @Produces annotation and passed the MediaType APPLICATION_JSON.
So a full example would be an HTTP POST request with a content-type of JSON and an accepted type of JSON, and the corresponding resource method would be annotated appropriately with both a @Consumes and @Produces annotation with the MediaType APPLICATION_JSON.
Wrote by Hansi