Bruno Rossi PA165 Enterprise Java System Integration I: Web Services & REpresentational State Transfer (REST) 2/73 Integration, SOC/SOA & Webservices 3/73 System Integration  System integration (SI) is a software engineering process that aims at putting together different subsystems within an overall application.  SI ensures that each integrated system functions and potentially can also add value by interconnecting different sub-systems/components 4/73 Enterprise Integration Bringing interoperability between the different systems within an enterprise infrastructure Integrating different business processes Integrating different subsystems / components Integrating different applications Enterprise Service Bus (ESB) Business Process Execution Language (BPEL) Common Object Request Broker Architecture (CORBA) COM (Component Object Model) 5/73 Distributed Computing Evolution Client-Server(C/S) silos Web-based computing Web Services/Peer-to-Peer Servers Clients Clients Servers Internet PDA Cell Phone Server LaptopKiosk Workstation 6/73 Evolution of software development /programming Procedural computing Service oriented computing (SOC) Object oriented computing (OOC) “Instructive” computing Hardware logic Execution logic Entity/object logic Value/servic e logic 7/73 Code / script execution XML Browsing HTML TCP/IP File access Technology Applications Text Hypertext Applications File transfer, E-mail Web pages Web services Internet Evolution 8/73 Service Oriented Computing (SOC)  SOC is an emerging cross-disciplinary paradigm for distributed computing that is changing the way software applications are designed, architected, delivered and consumed  SOC is a new computing paradigm that utilizes services as the basic constructs to support the development of rapid, low-cost and easy composition of distributed applications even in heterogeneous environments S. Dustdar and B. J. Krämer, Eds., “Introduction to Special Issue on Service Oriented Computing (SOC),” ACM Trans. Web, vol. 2, no. 2, pp. 10:1–10:2, May 2008. 9/73 Services Execution Data storage Client Brows er Applicati on client container Applicati on client Server Service orchestration and choreography Web container Servlet JSP EJB container EJB EJB 10/73 Some SOA definitions (1/2) A Service-Oriented Architecture (SOA) facilitates the creation of flexible, re-usable assets for enabling end-to-end business solutions. (Open Group Standard: SOA Reference Architecture, 2011) Contemporary SOA represents an open, agile extensible, federated, composable architecture comprised of autonomous, QoS-capable, vendor diverse, interoperable, discoverable, and potentially reusable services, implemented as Web services. (Erl, T., Service-oriented Architecture: Concepts, Technology and Design, 2005) Service-Oriented Architecture is an IT strategy that organizes the discrete functions contained in enterprise applications into interoperable, standards-based services that can be combined and reused quickly to meet business needs. (BEA white paper, 2005 -> 2008 Oracle) SOA is a conceptual business architecture where business functionality, or application logic, is made available to SOA users, or consumers, as shared, reusable services on an IT network. “Services” in an SOA are modules of business or application functionality with exposed interfaces, and are invoked by messages. (Marks, E.A., Bell, M., Service Oriented Architecture (SOA): A Planning and Implementation Guide for Business and Technology, 2006) 11/73 Some SOA definitions (2/2) Service-oriented architecture (SOA) is a set of principles and methodologies for designing and developing software in the form of interoperable services. These services are well-defined business functionalities that are built as software components (discrete pieces of code and/or data structures) that can be reused for different purposes. SOA design principles are used during the phases of systems development and integration. (Wikipedia) SOA is an architectural style whose goal is to achieve loose coupling among interacting software agents. A service is a unit of work done by a service provider to achieve desired end results for a service consumer. Both provider and consumer are roles played by software agents on behalf of their owners. (O’Reilly XML.COM) There is no unique definition: some refer to SOA as an architectural style, others as a paradigm, principles and methodologies, IT strategy, etc... 12/73 What is SOA SOA is an architectural style, realized as a collection of collaborating agents, each called a service, whose goal is to manage complexity and achieve architectural resilience and robustness through ideas such as loose coupling, location transparency, and protocol independence. (IBM definition of SOA) 13/73 Service  A service is an entity that has a description, and that is made available for use through a published interface that allows it to be invoked by a service consumer.  A service in SOA is an exposed piece of functionality with three properties:  The interface contract to the service is platform-independent.  The service can be dynamically located and invoked.  The service is self-contained. That is, the service maintains its own state. 14/73 What is a WebService  A Web service is a software system designed to support interoperable machine-to-machine interaction over a network. It has an interface described in a machine processable format (usually WSDL).  Other systems interact with the Web service in a manner prescribed by its description using SOAP messages, typically conveyed using HTTP with an XML serialization in conjunction with other Web-related standards 15/73 Principles of SOA  Services  Share a formal contract  Are loosely coupled  Abstract underlying logic  Are composable  Are reusable  Are autonomous  Are stateless  Are discoverable 16/73 A SOA Characterization 17/73 REpresentational State Transfer (REST) PA165 Enterprise Java 2014-2015 18/73 Distributed Systems Distributed systems …. CORBA Broker ArchitectureWeb Services Peer-to-Peer Systems Service-Oriented Systems …. RESTful Web Services WS*Web Services REST=Representational State Transfer 18 19/73 REST REpresentational State Transfer  Named by Roy Fielding in his Ph.D thesis from 2000 “Architectural Styles and the Design of Network-based Software Architectures” http://ics.uci.edu/~fielding/pubs/dissertation/top.htm  it is an architectural style: REST is a sort of reverse-engineering of how the Web works. HTTP and URIs were written with the REST principles in mind before they were formalized  The original idea behind Representational State Transfer is to mimic the behaviour of Web applications : as a net of Web pages and links, resulting in the next page (state change)  REST was born in the context of HTTP, but it is not limited to that protocol. 19 20/73 WS* vs. RESTful Web services WS*Web Services Middleware Interoperability Standards RESTful Web Services Architectural style for the Web 20 21/73 REST & SOA 21  How does REST fit in the SOA characterization?  What about the SOA principles? Services Share a formal contract Are loosely coupled Abstract underlying logic Are composable Are reusable Are autonomous Are stateless Are discoverable 22/73 HTTP Request/Response as REST Request GET /customer/{id}/items HTTP/1.1 Host: localhost Accept: application/xml Response HTTP/1.1 200 OK Date: Fri, 22 Jun 2013 17:21:35 GMT Server: Apache/1.3.6 Content-Type: application/xml; charset=UTF-8 Method Representation State transfer Resource 22 23/73 URI, example http://localhost/customers/123 Resource Collection name Primary key 23 24/73 HTTP Methods, for both collection and single item GET  to retrieve information  Retrieves a given URI idempotent, should not initiate a state  Cacheable POST  to add new information  Add the entity as a subordinate/append to the POSTed resource PUT  to update information  Full entity create/replace used when you know the “id” DELETE  to remove (logically) an entity 24 25/73 An Example HTTP Client (Web Browser) Web Server (Application server) Database GET /books/222 POST /order PUT /order/12 301 Location: /order/12 SELECT FROM books WHERE id=222 INSERT INTO orders UPDATE orders WHERE id=12 25 26/73 REST Methods 26 Method Collection of resources, e.g. //resources Single item, e.g. //resources/1 @GET Get a list of all the resources Retrieve data for resource with id 1 @PUT Update the collection with a new one Update the resource with id 1 @POST Create a new member resource Create a sub-resource under resource with id 1 @DELETE Delete the whole collection Delete the resource with id 1 @HEAD Retrieve meta-data information according to HTTP head request Retrieve data for resource with id 1 @OPTIONS Retrieved allowed operations, e.g. Allow: GET, OPTIONS Retrieved allowed operations, e.g. Allow: HEAD,GET,PUT,DELETE,OPTIONS @PATCH Partial modification of the collection Partial modification of some attributes of resource with id 1 27/73 REST Maturity Models 28/73 REST Maturity Model 28 Explains different levels at which REST can be implemented See http://martinfowler.com/articles/richardsonMaturityModel.html 29/73 Level 0 – The Swamp of POX*  Looks more as a Remote Procedure Call system  We post to an endpoint asking for different services  There is no knowledge about resources, rather messages that are sent to the endpoints (and back responses) 29 * Plain Old XML POST /appointmentService HTTP/1.1 [various other headers] 30/73 Level 1 – Resources  At this level we introduce Resources  We contact resources, not endpoints  Instead of passing parameters, now we contact the specific resource 30 POST /doctors/mjones HTTP/1.1 [various other headers] 31/73 Level 2 – HTTP Verbs  At this level we start using HTTP verbs  We start differentiating between POST and GET  We also start using HTTP response codes  We start differentiating “safe” vs “unsafe” operations 31 GET /doctors/mjones/slots?date=20100104&status=open HTTP/1.1 32/73 Level 3 – Hypermedia Controls (1/2)  We introduce HATEOAS (Hypertext As The Engine Of Application State) 32 GET /doctors/mjones/slots?date=20100104&status=open HTTP/1.1 This time the response contains link to URI: ... 33/73 Level 3 – Hypermedia Controls (2/2)  This allows to create a more fluent flow of resources: 33 ... ... 34/73 REST Principles PA165 Enterprise Java 2014-2015 35/73 REST Principles (1/4)  REST services are stateless. From Fieldings' thesis: “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”  So, server sessions should not be used → all needed to process a request should be available in the request  Messages are self-describing  No need to start negotiation to understand how to communicate with a service  Specific to HTTP, URI have semantics 35 36/73 REST Principles (2/4)  In REST, resources are manipulated through the exchange of representations of the resources  The components in the system exchange data (usually XML documents) → this represents a resource  REST-based architectures communicate primarily through the transfer of representations of resources  Resources have multiple representations (e.g. XML, JSON, XHTML, JPEG img) 36 37/73 REST Principles (3/4)  RESTful services have a uniform interface  No WSDL in REST  Standard HTTP methods GET, POST, PUT, DELETE, etc...  Protocol independence (although by default HTTP is relied on)  REST-based architectures are built with resources → Resources are uniquely identified by URIs 37 38/73 REST Principles (4/4)  Hypermedia as the engine of application state (HATEOS)  Fielding defines hypertext as: “the simultaneous presentation of information and controls such that the information becomes the affordance through which the user (or automaton) obtains choices and selects actions”  This is important because the implication is that: every resource returned by a server will allow to follow the URIs to any next step See http://spring.io/understanding/HATEOAS http://spring.io/guides/tutorials/bookmarks/#_building_a_hateoas_rest_service 38 39/73 Safety and Idempotence  The term "safe" means that if a given method is called, the resource state on the server remains unchanged  By specifications, GET and HEAD should always be safe – clearly it is up to the developers not to violate this hidden specification  PUT, DELETE are considered unsafe, while for POST generally depends 39 40/73 Safety and Idempotence  The word "idempotent" means that, independently from how many times a given method is invoked, the end result is the same.  GET and HEAD are an example of an idempotent operation  PUT is as well idempotent: if you add several times the same resource, it should be only inserted once DELETE is as well idempotent: issuing delete several times should yield the same result – the resource is gone (but what about DELETE /items/last ?)  POST is generally not considered an idempotent operation 40 41/73 Safety and Idempotence 41 Method Safety Idempotence @GET YES YES @PUT NO YES @POST NO NO @DELETE NO YES @HEAD YES YES @OPTIONS YES YES @PATCH NO NO 42/73 REST Best Practices PA165 Enterprise Java 2014-2015 43/73 REST Best Practices (1/6)  Have consistent usage of resource names, e.g. plural for resources → /users/1, orders/1  Use URIs to deal with relationships → GET /users/1/orders to get all orders for a user  Thinking in terms of CRUD operations – Example: using PUT and DELETE to set flags, rather than /users/1/enable /users/1/disable – If not possible (e.g. retrieval of multiple resources) then also /find or similar action might be appropriate  Filtering and sorting options should be provided as parameters in the API, e.g. GET /users/1/orders? state=active&sorting=by-name 43 44/73 REST Best Practices (2/6)  Might decide to use some parameter to limit “response-heavy” queries – GET /users?fields=id,name,desc – The Github API takes an interesting approach: collections return only the basic information (id, name, desc,...). If you need more → need to query the specific resource  Versioning: it is important to version the API – the requested version can be given in the header (preferred) or as a parameter. – See how the GitHub REST API manages versioning: https://developer.github.com/v3/media/#request-specific-version  Might use some aliases for common queries → GET /users/most_popular 44 45/73 REST Best Practices (3/6)  Create and Update methods should return the resource that has been created or modified  Usage of HATEOAS is a design decision, in some cases it might add more overhead to what it is really necessary  JSON is nowadays much more popular than XML in REST APIs* 45 * Pragmatic Best Practice about REST APIs http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api 46/73 REST Best Practices (4/6)  Some API prefer to always wrap all responses so that there is a standard way of returning data even in case of errors: { "data" : { "id" : “1”, "name" : "Joseph" }, "state" : { "name" : “OK”, "desc" : "no error" } } This depends on the case, as it introduces overhead for every response. Good idea is to return some structured information, e.g. validation errors { "code" : 1024, "message" : "Validation Failed", "errors" : [ { "field" : "first_name", "message" : "First name cannot be empty" }, { "field" : "price_change", "message" : "Price cannot be changed by over 10%" } ] } 46 47/73 REST Best Practices (5/6)  When returning paginated results, you can use the link header: – https://developer.github.com/v3/#pagination  It can be a good idea to think about limiting access to the API implementing some limiting counter returning 429 Too Many Requests – https://developer.github.com/v3/#rate-limiting  Implementing a limiter for access will also “force” clients to use conditional requests 47 48/73 REST Best Practices (6/6)  Most used return codes in REST APIs:  200 OK → successful GET, PUT, PATCH, DELETE, POST (no creation)  201 Created → After a POST (creation). Location header might give location of new resource  204 No Content → Successful but no body (e.g DELETE)  304 Not Modified → HTTP caching  400 Bad Request → error in the request body  404 Not Found → non-existent resource requested  409 Conflict → a resource conflict, e.g. duplicate entities  410 Gone → old API method?  415 Unsupported Media Type → incorrect content type in part of the request  422 Unprocessable Entity → Validation errors  429 Too Many Requests → limiting requests 48 5xx HTTP codes are used to indicate some server-error – might decide in these cases to always return 500 Internal Server Error 49/73 Github REST API  Let's look at GitHub REST API  https://developer.github.com/v3/  Also a wrapper of such API: http://github-api.kohsuke.org 49 50/73 REST in Spring 51/73 A Spring REST Controller 51 Spring @RestController @RequestMapping("/customers") public class CustomersController { @RequestMapping(value="customers", method=RequestMethod.GET, headers="Accept=text/plain") public String getCustomers() { .... } ... } or produces={MediaType.TEXT_PLAIN} http://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html 52/73 Multiple Representations  Data in a variety of formats  XML  JSON (JavaScript Object Notation)  XHTML  Content negotiation  Accept header GET /customers Accept: application/json  URI-based GET /customers.json  parameter-based http://localhost/customers?type=json 52 produces={MediaType.TEX T_PLAIN [, more-types ]} Specifies the type of data that is returned, for example, "text/plain" consumes={type [, moretypes ]} The type of data that is consumed by the method, for example, "text/plain" Which is the order in which these are considered in Spring? 53/73 Multiple Representations  Content negotiation  Accept header GET /customers Accept: application/json  URI-based GET /customers.json  parameter-based http://localhost/customers?type=json 53 Why is 'accept header' the last option? 3 1 2 54/73 Content Negotiation  Example @RestController @RequestMapping(value=ApiUris.ROOT_URI_ORDERS, consumes=MediaType.TEXT_PLAIN_VALUE) public class CustomerController { @RequestMapping(method = RequestMethod.POST, consumes = MediaType.TEXT_XML_VALUE, produces = MediaType.TEXT_XML_VALUE) public CustomerDTO createCustomer(NewCustomerDTO customer) {...} } 54 POST /customers content-type: text/xml 55/73 Content Negotiation  Example @RestController @RequestMapping(value=ApiUris.ROOT_URI_ORDERS, produces=MediaType.TEXT_PLAIN_VALUE) public class CustomersController { @RequestMapping(method = RequestMethod.GET) public List getCustomersPlain() {...} @RequestMapping(method = RequestMethod.GET, produces = MediaType.TEXT_XML_VALUE) public List getCustomersXML() {...} } 55 GET /customer Accept: text/xml 56/73 Content Negotiation 56 Configuration example in Spring @Configuration @EnableWebMvc public class WebConfig extends WebMvcConfigurerAdapter { @Override public void configureContentNegotiation(ContentNegotiation Configurer configurer) { configurer.favorPathExtension(false).favorParameter(true). parameterName("mediaType").ignoreAcceptHeader(true). defaultContentType(MediaType.APPLICATION_JSON).mediaType("txt",MediaType.TE XT_PLAIN).mediaType("xml",MediaType.APPLICATION_XML). mediaType("json",MediaType.APPLICATION_JSON); } } We are favouring parameter based requests, ignoring accept headers 57/73 Content Negotiation 57 Configuring the ObjectMapper See http://docs.spring.io/spring-boot/docs/current/reference/html/howto-spring-mvc.html @Bean public MappingJackson2HttpMessageConverter customJackson2HttpMessageConverter() { MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter(); ObjectMapper objectMapper = new ObjectMapper(); objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); jsonConverter.setObjectMapper(objectMapper); return jsonConverter; } @Override public void configureMessageConverters(List> converters) { converters.add(customJackson2HttpMessageConverter()); } 58/73 Managing Exceptions & Return Codes  It is responsibility of the developer to provide consistent behaviour of their REST API:  Successful HTTP response code numbers go from 200 to 399. The creation will return 200, “OK” if the object returned is not null. 204, “No Content” is returned when a null object was retrieved. As well as if the return is of type void 204, “No Content” is returned.  HTTP error response code numbers go from 400 to 599. A 404 “Not Found” response code will be sent back to the client if the resource requested is not found. A bad request "400" is sent back in case of bad parameters. All the codes in the range 5xx indicate internal errors of the application. 58 59/73 Testing the REST API (1/2)  Very often it is useful also for documentation (see later)  Using org.springframework.test.web.servlet.MockMvc 59 mockMvc = standaloneSetup(productsController).setMessageConverters(new MappingJackson2HttpMessageConverter()).build(); [...] // mocking some facade/service operation doReturn(Collections.unmodifiableList(this.createProducts())).when( productFacade).getAllProducts(); mockMvc.perform(get(ApiUris.ROOT_URI_PRODUCTS)) .andExpect(status().isOk()) .andExpect( content().contentType(MediaType.APPLICATION_JSON_VALUE)); 60/73 Testing the REST API (2/2)  Using JSONPath to check the JSON request/response  https://github.com/jayway/JsonPath 60 mockMvc.perform(get(ApiUris.ROOT_URI_ORDERS).param("status", "ALL")).andDo(print()) .andExpect(status().isOk()) .andExpect( content().contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(jsonPath("$.[?(@.id==1)].state").value("DONE")); Filtering expression, '@' stands for the current node 61/73 Managing Exceptions (1/5)  Any unhandled exception will cause an HTTP 500 response  However, you can annotate exceptions with @ResponseStatus to return the appropriate HTTP error code & message 61 @ResponseStatus(value=HttpStatus.NOT_FOUND, reason="the resource was not found") public class ResourceNotFoundException extends RuntimeException{ [...] } 62/73 Managing Exceptions (2/5) 62 @ResponseStatus(value=HttpStatus.NOT_FOUND, reason="The customer was not found") public class CustomerNotFoundException extends RuntimeException { // ... } @RequestMapping(value="customers/{id}", method=RequestMethod.GET, headers="Accept=text/plain") public String getCustomer(@PathVariable("id") long id) { .... customer = customersFacade.getCustomerById(id); if (customer == null) throw new CustomerNotFoundException(id); .... } 63/73 Managing Exceptions (3/5) See org.springframework.http.HttpStatus http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/http/HttpStatus.html 63 64/73 Managing Exceptions (4/5)  Methods annotated with @ExceptionHandler are handling exceptions  You do not need to add @ResponseStatus to the Exceptions  Gives you more freedom in returning a custom error data structure 64 @RestController public class MyController { ... @ExceptionHandler @ResponseStatus(HttpStatus.UNPROCESSABLE_ENTITY) @ResponseBody ApiError handleException(ResourceAlreadyExistingException ex) { ApiError apiError = new ApiError(); apiError.setErrors(Arrays.asList("the requested resource already exists")); return apiError; } } 65/73 Managing Exceptions (5/5)  Another way is to have a global advice using @ControllerAdvice that will manage exceptions for all controllers 65 @ControllerAdvice class GlobalControllerExceptionHandler { @ResponseStatus(HttpStatus.NOT_FOUND) @ExceptionHandler(CustomerNotFoundException.class) public void handleCustomerNotFound() { ... } } 66/73 Caching Client Server Basic setup Caching: Server Caching: client Server Client Caching: client Caching: Server Caching options 66 67/73 Caching Example in Spring 67 public String myHandleMethod(WebRequest request, Model model) { String eTag = // application-specific calculation if (request.checkNotModified(eTag)) { // shortcut exit - no further processing necessary return null; } // further request processing, actually building content model.addAttribute(...); return "myViewName"; } From http://docs.spring.io/spring/docs/current/javadoc- api/org/springframework/web/context/request/WebRequest.html#checkNotModified- java.lang.String- 68/73 Caching Example in Spring 68 > curl -X GET -i http://localhost:8080/eshop-rest/users/1 HTTP/1.1 200 OK Server: Apache-Coyote/1.1 ETag: "3242771" Cache-Control: no-transform, max-age=86400 Content-Type: text/plain Content-Length: 4 > curl -i -X GET http://localhost:8080/eshop-rest/users/1 --header 'If-None-Match: "3242771"' -Match: "3242771"' HTTP/1.1 304 Not Modified Server: Apache-Coyote/1.1 ETag: "3242771" 69/73 Documentation  Several ways to document a Spring REST API  More design-oriented – Example, Apiary https://apiary.io/  By test invocation – REST Docs, http://projects.spring.io/spring-restdocs/  By annotating controller methods – Swagger, http://swagger.io 69 70/73 Documentation - Apiary 70 71/73 Documentation – REST Docs  Official Spring project  Uses expected testing behaviour to describe the API 71 In a test class: @Rule public final RestDocumentation restDocumentation = new RestDocumentation("build/generated-snippets"); @Before public void setUp() { this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context) .apply(documentationConfiguration(this.restDocumentation)) .build(); } Later on in a @Test method: this.mockMvc.perform(get("/customers").accept(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) .andDo(document("customers")); 72/73 Documentation – Swagger  Very popular documentation project for REST API, not officially endorsed by the Spring community  Based on additional annotations on the controllers to describe the API 72 @RestController @Api(value=ApiUris.ROOT_URI_CUSTOMERS, description="All operations related to customer resources") @RequestMapping(ApiUris.ROOT_URI_CUSTOMERS) public class CustomersController { @ApiOperation(value = "Get information about one customer", note="additional notes") @RequestMapping(value="/{id}", method=RequestMethod.GET) public String getCustomer(@ApiParam(name="id", value="the id of the customer resource to be retrieved", required=true) @PathVariable String productid) { .... } ... } See https://github.com/swagger-api/swagger-core/wiki/Annotations-1.5.X 73/73 References  Roy Fielding PhD Thesis: https://www.ics.uci.edu/~fielding/pubs/dissertation/fielding_dissertation.pdf  Review of REST API documentation tools: https://www.opencredo.com/2015/07/28/rest-api-tooling-review/  Richardson Maturity model from Martin Fowler's website: See http://martinfowler.com/articles/richardsonMaturityModel.html  Webber, Jim, Savas Parastatidis, and Ian Robinson. REST in practice: Hypermedia and systems architecture. " O'Reilly Media, Inc.", 2010.  Pragmatic Best Practice about REST APIs http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api  RESTful best practices http://www.restapitutorial.com/media/RESTful_Best_Practices-v1_1.pdf 73