Each application is different. Applications do not work with each other “out of the box”. Unless an application is stand-alone, effort is needed to integrate it into a system. The degree of interoperability of an application can be measured as its cost of integration.
A cloud application component typically comprises a set of operations with shared process, semantics, and access control. End users or other components invoke multiple operations in particular ways to obtain results. They construct information to send to the component, and interpret the responses, in a consistent way across all the operations. User roles are defined with different access rights to operations and information.
For example, a virtual meetings service might classify users as “attendee”, “moderator”, and “manager”. The sequence of operations to set up a meeting might be that a manager allocates a “meeting room” to a moderator, the moderator “prepares” a “meeting” in the meeting room, and each attendee “enters” the meeting room. The service has an API that includes “meeting room allocation”, “meeting preparation”, and “meeting attendance” operations, each of which is implemented as an HTTP request and response. The terms “attendee”, “enters”, “manager”, “meeting”, “meeting room”, “moderator”, “prepares”, etc. are used consistently in the product documentation, and in the API.
Such terms and procedures are, however, not consistent across applications. A different virtual meetings service might classify users as “participant” and “host”, with each host having a dedicated “conference bridge”. The sequence of operations might be that the host “starts” a “conference” and the participants then “join” it. The terminology and process is completely different.
Such an application is much more open and interoperable than a traditional silo application, and can be integrated with other products. For example, an enterprise could integrate both of the example virtual meetings services with a single calendar service to provide an enterprise virtual meeting scheduling capability. The effort required for such integration can be significant, because of the semantic and procedural variations.
It does not in general make sense to try to define standard functional interfaces for applications. Different virtual meeting service providers, for example, will have different procedures and terminology for their services, and these will be reflected in different interface definitions. There are, however, some application design principles that reduce the cost of integration, though this cannot be completely eliminated.
This chapter describes a number of application design principles that will reduce the cost of application integration for cloud computing.
Cloud application components should be loosely coupled with the application components that interact with them.
An application component should as far as possible be self-contained, with functions that are logically separate from those of other components. Interactions with other components should be simple, few, and not time-critical.
This final characteristic – that interactions are not time-critical – is particularly important for cloud computing, as communication with components that are “in the cloud” can be slow and their speed cannot be guaranteed.
Cloud applications should be service-oriented.
Service-orientation is a way of thinking in terms of services and service-based development and the outcomes of services [SOA].
A cloud application should be organized as a service, or a set of services, that may be a user of other services.
Low bandwidth, high-latency connections may mean that protocols commonly used in SOA are impractical, because of their high overheads. The principles of the service-oriented approach should nevertheless be followed whenever this is feasible.
Cloud application components should have interfaces that do not change over time, or are such that any changes are backwards-compatible.
The cost of integration of a component should be considered over its lifetime, not just at its point of first use. A change to a component interface implies a need to re-integrate it with other components. The lifetime cost of a component whose interfaces change will be considerably more than its initial cost.
The interfaces to cloud application components should be clearly described.
The descriptions should be human-readable and may also be machine-readable.
Clear human-readable descriptions are essential for the acquisition of an application component and for its subsequent integration by developers.
Machine-readable descriptions enable dynamic discovery and composition.
Cloud products and services should be made available through marketplaces.
The marketplace (or app store) concept is becoming established in the world of cloud computing. A marketplace enables an enterprise or group of enterprises to ensure that the products and services that users need are available to them, and to exercise some control over the quality of those products and their suitability within the context of the enterprise or ecosystem architecture, while allowing users to choose between competing products.
The ability to restrict users to products and services that fit within an overall architecture will help to ensure portability and interoperability.
While many REST APIs do use raw HTTP, the two concepts are by no means the same. In particular, use of raw HTTP does not guarantee that the service will not store user state information, as required by a truly “RESTful” approach.
For example, in a true REST system, each request from client to server must contain all of the information necessary to understand the request, and cannot take advantage of any stored context on the server. If this is followed strictly, when the user of an Internet shopping service requests to see his “shopping cart”, the client must have remembered what is in the cart, and tell the server, rather than the server storing this information. Not all “RESTful” Internet shopping services actually work this way.
In fact, it is now normal practice for servers to store the identity of the individual using a client, and whether that client is logged in, as session information, rather than having the client authenticate itself for each interaction. Session information can also include such things as the user’s time-zone and preferred language. Not taking advantage of stored context on the server is interpreted as a guideline rather than an absolute prohibition.
The REST approach, though not necessarily applied with full rigor, is being increasingly used in cloud computing. It enables implementation of robust and scalable services. More than that, it is a simplifying principle that leads to the creation of loosely-coupled services with stable interfaces that are easy to describe.
Cloud applications should be designed as far as possible to perform transactions with the so-called BASE properties: Basically Available, Soft State, and Eventual Consistency.
Traditional transaction processing is based on the so-called ACID properties: Atomicity, Consistency, Isolation, and Durability. This approach means that transactions are reliable, but the required consistency cannot be obtained in distributed systems without sacrificing availability or robustness. (This proposition is known as the CAP Theorem [CAP].)
The BASE approach allows for replicated resources, so that at least one copy is always available, with different copies in slightly different states, but with synchronization between them so that there is eventual consistency as regards any particular piece of information.
Transactions in distributed systems that follow the BASE approach are not 100% reliable. For example, a purchaser may find, at check out, that an item that is “in the shopping cart” is unavailable because another user has purchased it meanwhile. This is a consequence that is generally accepted by today's Internet vendors and cloud service providers, in order to achieve robust, scalable systems.
There are some applications for which ACID transactionality is essential and, for those applications, it must be provided. For other applications, components providing parts of the transaction should be designed with BASE transactionality for interoperability with other components.