Rest with Spring


Published on

Published in: Technology
  • Be the first to comment

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide

Rest with Spring

  1. 1. REST with Spring BJUG 6 @IBM Eugen Paraschiv
  2. 2. Overview● Why REST?● RESTful Constraints and Guidelines● REST via Spring MVC● Persistence with Spring Data● Testing of a RESTful Service● Q&A
  3. 3. Why REST● REST is a set of Constraints (its not the only one)● Minimize Coupling between Client and Server● Update the Server frequently without updating the Clients (no control over them)● Support for many different types of Clients● Scaling becomes easy(er)
  4. 4. The Four Levels of HTTP APIs - I, IILevel I. SOAP (Flickr SOAP API, Google AdSense API)- WSDL describes the interface at design time- no Resources are identified by URI - only Service Endpoints- no difference between Resource and Representation- HTTP treated as transport - no use of HTTP semanticsLevel II. RPC (Amazon SimpleDB, Flickr REST API)+ the API exposes Resources (often corresponding to the application models)- operations are done via actions in the URIs - the URI space is known atdesign time (ex. /post/make_new)- operations, failure codes are application specific- HTTP treated as transport - no use of HTTP semantics
  5. 5. The Four Levels of HTTP APIs - IIILevel III. HTTP (Twitter API)+ Resources are exposed and identified by URIs+ Resources are manipulated via Representations+ HTTP semantics used correctly, use of generic media types (e.g.application/xml)- message semantics only known to Client and Server but not intermediaries -Client and Server are coupled by original design- application state machine is known at design time - assumptions aboutavailable representations and transitions are hard-coded
  6. 6. The Four Levels of HTTP APIs - IVLevel IV. REST (Atom Pub, OpenSearch)+ service description comes in the form of media type (and link relations)specifications+ Client only knows entry bookmark (the Root URI) and media types and nospecifics about the particular service+ Client proceeds through application by looking at one response at a time,each time evaluating how best to proceed given its overall goal and theavailable transitions+ Methods to use are known from media type (and link relations) specificationsor selected at runtime based on forms (form semantics known from media typespecifications)
  7. 7. REST SEC projectWHERE- @github - Reference Spring implementation of a REST Service- Identity Management Solution as a ServiceHOW- REST/web: Spring 3.1.x- Marshalling: Jackson 2.x (for JSON) and XStream (for XML)- Persistence: Spring Data JPA and Hibernate 4.1.x- Testing: Junit, Hamcrest, Mockito, rest-assured, RestTemplate (ApacheHTTP Client)
  8. 8. RESTful Constraints - I. Stateless"Each request from client to server must contain all of the informationnecessary to understand the request, and cannot take advantage of any storedcontext on the server. Session state is therefore kept entirely on the client"In Short- no sessions, no cookies- each request should contain its authentication credentialsWith Spring Security<http create-session="stateless" ... >
  9. 9. RESTful Constraints - II. Cache● Caching is on the Client side● Goal of Client side Caching - partially or completely eliminate interactions with the Server● HTTP Caching options: ● ETag/If-None-Match ● Last-Modified/If-Modified-Since
  10. 10. III. Caching - ETag - example- ex: first, retrieve a Privilege resource:curl -H "Accept: application/json" -i http://localhost:8080/rest-sec/api/privileges/1HTTP/1.1 200 OKServer: Apache-Coyote/1.1Link: <http://localhost:8080/rest-sec/api/privileges>;rel="collection"ETag: "f88dd058fe004909615a64f01be66a7"Last-Modified: Fri, 05 Oct 2012 11:36:33 GMTContent-Type: application/json;charset=UTF-8Content-Length: 52Date: Fri, 05 Oct 2012 11:36:33 GMT
  11. 11. III. Caching - ETags - example (cont)- next, use the etag value from the previous response toretrieve the Privilege resource again:curl -H "Accept: application/json" -H If-None-Match:"f88dd058fe004909615a64f01be66a7" -i http://localhost:8080/rest-sec/api/privileges/1HTTP/1.1 304 Not ModifiedServer: Apache-Coyote/1.1Link: <http://localhost:8080/rest-sec/api/privileges>;rel="collection"ETag: "f88dd058fe004909615a64f01be66a7"Date: Fri, 05 Oct 2012 11:37:55 GMT
  12. 12. REST Constraint - III. UniformInterfaceUniform Interface Constraints1. Identification of Resources2. Manipulation of Resources through Representations3. Self-descriptive Messages4. Hypermedia As The Engine Of Application State(HATEOAS)
  13. 13. III.1. Identification of Resources -Spring MVCFor a sample foo resource:- the Controller@Controller@RequestMapping(value = "foos")public class FooController{ ... }- retrieve by id: GET api/foos/id@RequestMapping(value = "/{id}", method = RequestMethod.GET)public Foo findOne(@PathVariable("id") Long id){...}- search: GET api/foos?q=query@RequestMapping(params = {"q"}, method = RequestMethod.GET)public List<Foo> search(@RequestParam("q") String query){...}
  14. 14. III.1. Identification of Resources -Spring MVC (cont)- create single (update the collection): POST api/foos@RequestMapping(method = RequestMethod.POST)@ResponseStatus(HttpStatus.CREATED)public void create(@RequestBody Foo resource) {...}- update/override PUT api/foos/id@RequestMapping(method = RequestMethod.PUT)@ResponseStatus(HttpStatus.OK)public void update(@RequestBody Foo resource) { ... }- delete: DELETE api/foos/id@RequestMapping(value = "/{id}", method = RequestMethod.DELETE)@ResponseStatus(HttpStatus.NO_CONTENT)public void delete(@PathVariable("id") Long id) { ... }
  15. 15. REST Constraint - III. UniformInterfaceSupported Representations:- JSON - application/json- XML - application/xml- future: ATOMAll read operations will perform ContentNegotiation when the Accept header is set onthe requestAll write operations supports the Content-Typeheader to be set on the request
  16. 16. Spring MVC - the Controller/WebLayerSimple Responsibilities:- mapping of URIs- Marshalling/Unmarshalling of ResourceRepresentations (implicit)- Translation of Exceptions to HTTP StatusCodes
  17. 17. REST Constraint - III. UniformInterface - HATEOAS- Discoverability at the root- the Create operation- making use of `rel`- Advanced Topics: custom Mime Types, HAL
  18. 18. Persistence Layer - Spring Data- DAO only with interfaces - no implementationspublic interface IUserJpaDAO extends JpaRepository<User,Long> { … }- define a new, simple method:List<User> findByLastname(String lastname);List<User> findByEmailAddressAndLastname(StringemailAddress, String lastname);- flexibility to use @Query@Query("select u from User u where u.emailAddress = ?1")User findByEmailAddress(String emailAddress);
  19. 19. Persistence Layer - Spring Data● PaginationPage<User> findByFirstname(String firstname, Pageablepageable);● SortingList<User> findByLastname(String lastname, Sort sort);
  20. 20. Persistence Layer - Spring DataOther out of the box features - support for:● Audit: create date, created by, last update date, last updated by● Advanced Persistence APIs: QueryDSL, JPA 2 Specifications
  21. 21. Transactional Semantics- the API Layer Strategy● the Controller layer is the transactional owner● the Service layer contains no transactional semantics● there are no self-invocations or inter- invocations in the Controller layer - each invocation is a client call
  22. 22. Testing of a REST Service● Live Tests: testing the deployed RESTful service ○ each RESTful service has a corresponding production API and a testing API ○ high level testing is done via the production API ○ lower level testing is done via the testing API● Integration tests: business, persistence● Unit tests
  23. 23. Testing - High Level Live Test (overREST)@Testpublic voidgivenResourceExists_whenResourceIsRetrievedByName_thenResourceIsFound() { // Given T existingResource = api.create(createNewEntity()); // When T resourceByName = api.findByName(existingResource.getName()); // Then assertNotNull(resourceByName);}
  24. 24. Testing - Low Level Live Test (overREST)@Testpublic voidgivenInvalidResource_whenResourceIsUpdated_then409ConflictIsReceived() { // Given User existingUser = RestAssured.given().auth().preemptive().basic(username, password).contentType("application/json").body(resourceAsJson).post(uri).as(User.class); existingUser.setName(null); // When Response updateResponse = RestAssured.given().auth().preemptive().basic(username, password).contentType("application/json").body(existingUser).put(uri); // Then assertThat(updateResponse.getStatusCode(), is(409));}
  25. 25. Security Concerns- Basic and Digest Authentication with SpringSecurity ON THE SAME URI (similar toContent Negotiation):● Authorization: Basic ...● Authorization: Digest ...
  26. 26. ConclusionQuestions:-?-?-?-?
  27. 27. THANKS