O slideshow foi denunciado.
Utilizamos seu perfil e dados de atividades no LinkedIn para personalizar e exibir anúncios mais relevantes. Altere suas preferências de anúncios quando desejar.

Type-Safe Evolution of 
Web Services

115 visualizações

Publicada em

Presentation at thee VACE workshop (http://vaquita-workshop.org/vace2017/index.html) at ICSE 2017 (http://icse2017.gatech.edu). The paper is available at http://docentes.fct.unl.pt/jmc-cunha/publications.

Applications based on micro or web services have had significant growth due to the exponential increase in the use of mobile devices. However, using such kind of loosely coupled interfaces provides almost no guarantees to the developer in terms of evolution. Changes to service interfaces can be introduced at any moment, which may cause the system to fail due to mismatches between communicating parts.
In this paper, we present a programming model that allows the development of web service applications, server end-points and their clients, in such a way that the evolution of services’ implementation does not cause the disruption of the client. Our approach is based on a type based code slicing technique that ensures that each version only refers to type compatible code, of the same version or of a compatible version, and that each client request is redirected to the most recent type compatible version implemented by the server.
We abstract the notion of version and parametrize type compatibility on the relation between versions. The relation between versions is tagged with compatibility levels, so to capture the common conventions used in software development. Our implementation allows multiple versions of a service to be deployed simultaneously, while reusing code between versions in a type safe way. We describe a prototype framework, based on code transformation, for server-side JavaScript code, and using Flow as verification tool.

Publicada em: Ciências
  • Entre para ver os comentários

  • Seja a primeira pessoa a gostar disto

Type-Safe Evolution of 
Web Services

  1. 1. Type-Safe Evolution of 
 Web Services João Campinhos, João Costa Seco, Jácome Cunha
 NOVA LINCS, Universidade NOVA de Lisboa, Portugal j.campinhos@campus.fct.unl.pt, joao.seco@fct.unl.pt, jacome@fct.unl.pt Second International Workshop on Variability and Complexity in Software Design VACE @ ICSE 2017 27 May, 2017 - Buenos Aires, Argentina
  2. 2. Problem • Mobile/Web apps based on micro or web services have had significant growth (smartphones explosion) • Client and server are loosely coupled • Using such kind of interfaces provides almost no guarantees to the (client) developer in terms of evolution • Changes to service interfaces can be introduced at any moment, causing the clients to fail • All of us now this evolution happens all the time 2
  3. 3. An Example of a Web Service for Users - v1.0 server implementation – version 1.0 user() => { name: “John Doe” } client implementation – version 1.0 user().name.trim() 3
  4. 4. Server Evolution server implementation – version 2.0 user() => { name:{ first: “John”, last: “Doe” }} client implementation – version 1.0 user().name.trim() 4
  5. 5. Clients Need to Go Along… server implementation – version 2.0 user() => { name:{ first: “John”, last: "Doe" }} client implementation – version 2.0 user().name.first + “ “ + user().name.last 5
  6. 6. Several Issues • It is probably not feasible to update all clients to the latest version at the same time • It is probably not possible to keep all service interfaces and maintain them all • If the client moves from version A to version B, then all the code needs to move (not incremental) 6
  7. 7. How can we help server and client developers cope with evolution? ? 7
  8. 8. Towards a Solution •Coexistence Principle •Compatibility Principle •Safety Principle •Modularity Principle 8
  9. 9. Coexistence Principle • Coexistence Principle: to make all the existing versions available as a complete application, as a unique code base • Making use of annotations in the client requests and in the server code to identify which version(s) to use to attend a request • Both versions 1.0 and 2.0 of the server should coexist at the same time and should be usable by a client, both at the same time 9
  10. 10. Coexistence Principle { (version = ’1.0’) => { var currentuser = {name: “John Doe”}; function user() : {name: string} { return currentuser; } } (version = ’2.0’) => { var currentuser = {name: {first:”John”, last: ”Doe”}}; function user() : {name: {first: string, last: string}} {
 return currentuser; } } } 10
  11. 11. Reuse •The coexistence of versions only makes sense if it is possible to reuse code across versions •We introduce a language construct that allows the annotation of an expression e with a version v where it should be evaluated
 
 (version = ‘v’) => e 11
  12. 12. 12 (version = ’1.0’) => { var currentuser = {name: “John Doe”}; function user() : {name: string} { return (version ‘2.0’) => { name: user().first + “ “ + user().last }; } } (version = ’2.0’) => { var currentuser = {name: {first:”John”, last: ”Doe”}}; function user() : {name: {first: string, last: string}} {
 return currentuser; } }
  13. 13. Small Change to v2.0 … (version = ’2.0’) => { var currentuser = {name: {first:”John”, last: ”Doe”}}; function user() : {name: {first: string, last: string}} {
 return currentuser; } } (version = ’2.1’) => { function user(): {name:{first: string, last: string}, age:int} { return (version = ’2.0’) => {user(), age: 42}; } } 13
  14. 14. 14 • In this case, the type of the response in version 2.1 is a subtype of the response in version 2.0 • In many cases, it is still possible for clients to interact with the new version • This makes it possible for version 2.1 to be used whenever version 2.0 is requested
  15. 15. Compatibility Principle • Compatibility Principle: a system should serve its clients with (type) compatible versions at all times • Our solution is to use a relation on versions that embeds the notion of compatibility between versions • We introduce version patterns which define the base version for searching the correct implementation 15
  16. 16. 16 … (version = ’2.0’) => { var currentuser = {name: {first:”John”, last: ”Doe”}}; function user() : {name: {first: string, last: string}} {
 return currentuser; } } (version = ’2.1’) => { function user(): {name:{first: string, last: string}, age:int} { return (version = ’2.0’) => {user(), age: 42}; return (version = ’2.*’) => {user(), age: 42}; } }
  17. 17. An Example of a Relation 17 1.0 2.0 2.1 1.0-A user():{name:string} user():{name:{first: string, last: string}} user():{name:{first: string, last: string}, age:int} strictfree subtyping
  18. 18. Compatibility Modes •Strict: all the changes from one version to another preserve the types of all declared identifiers (functions and variables) •Subtyping: all changes from one version to another follow the subtype relation •Free: does not constraint the changes on the type signatures, as to allow the developer to arbitrarily change the source code 18
  19. 19. An Example of a Relation 19 1.0 2.0 2.1 1.0-A user():{name:string} user():{name:{first: string, last: string}} user():{name:{first: string, last: string}, age:int} strictfree subtyping
  20. 20. Back to the Client Code - Subtyping Mode second client implementation – version 2.0 (version = ’2.*’) => { user().name.first } • Client code maybe still be in version 2.0, but if it requests the most updated version of the service, version 2.1 will be served 20
  21. 21. Type Checker and Dispatching System • The static type checker considers all versions and the compatibility modes between them to typecheck the code base • The runtime dispatching system also takes into consideration the relation between the different version to serve the appropriate one 21
  22. 22. Safety Principle •A third (and more general) principle becomes essential to reach a sound solution •Safety Principle: all possible entry points of the system should be type safe, in all versions, and considering all possible version redirections given by the version compatibility relation 22
  23. 23. Modularity Principle •Modularity Principle: the static verification of code and the dynamic dispatching of requests and execution should be decoupled from the actual definition of what a version is and how versions relate •This implies the relation is defined by the server developer to relate any versions using any compatibility mode 23
  24. 24. Open-Source Prototype Implementation 24 Annotated JavaScript Code Syntactic Analysis Version Type Checker Flow Transpiler JavaScript Code Router Request (version, mode) Function Relation AST http://github.com/niverso Babel Ours Flow Syntax Type Checker
  25. 25. Conclusions & Future Work •We introduced a new programming model to develop and evolve software with multiple versions at the same time •It copes with evolution using version compatibility modes •Our approach is flexible as it is parametric on any version control system developers may use •The type system we developed can typecheck programs with several versions at the same time •The dispatching function dynamically decides what is the best version of a particular component for each request 25
  26. 26. Conclusions & Future Work •As a proof of concept we have implemented our programming model as a prototype using the Flow typechecker and JavaScript •As future work, we want to formally certify the soundness of the approach •Also, experimental work must be performed with larger case-studies •We would also like to develop an IDE with this programming model built-in 26

×