Biblio
Remote Application Programming Interfaces (APIs) are technology enablers for major distributed system trends such as mobile and cloud computing and the Internet of Things. In such settings, message-based APIs dominate over procedural and object-oriented ones. It is hard to design such APIs so that they are easy and efficient to use for client developers. Maintaining their runtime qualities while preserving backward compatibility is equally challenging for API providers. For instance, finding a well suited granularity for services and their operations is a particularly important design concern in APIs that realize service-oriented software architectures. Due to the fallacies of distributed computing, the forces for message-based APIs and service interfaces differ from those for local APIs – for instance, network latency and security concerns deserve special attention. Existing pattern languages have dealt with local APIs in object-oriented programming, with remote objects, with queue-based messaging and with service-oriented computing platforms. However, patterns or equivalent guidance for the structural design of request and response messages in message-based remote APIs is still missing. In this paper, we outline such a pattern language and introduce five basic interface representation patterns to promote platform-independent design advice for common remote API technologies such as RESTful HTTP and Web services (WSDL/SOAP). Known uses and examples of the patterns are drawn from public Web APIs, as well as application development and software integration projects the authors have been involved in.
During software evolution, it is important to evolve not only the source code, but also its architecture to prevent architecture drift and architecture erosion. This is a complex activity, especially for large software projects, with multiple development teams that might be located in different countries or on different continents. To ease this kind of evolution, we have developed a domain-specific language for making decisions about the evolution. It supports the definition of architectural changes based on multiple implementation tasks that can have temporal dependencies among each other. Then, by means of a model-to-model transformation, we automatically create a constraint model that we use to generate, by means of the Alloy model analyzer, the possible alternative decisions for executing the implementation tasks. The tight integration with architecture abstractions enables architects to automatically check the changes related to an implementation task in relation to the architecture description. This helps keeping architecture and code in sync, avoiding drift and erosion.