Spring MVC to iOS and the REST
Upcoming SlideShare
Loading in...5
×
 

Spring MVC to iOS and the REST

on

  • 7,219 views

Presented at DevNexus 2013

Presented at DevNexus 2013

Statistics

Views

Total Views
7,219
Views on SlideShare
7,123
Embed Views
96

Actions

Likes
13
Downloads
113
Comments
0

3 Embeds 96

http://lanyrd.com 66
https://twitter.com 29
http://biologi3mtsnkra.p.ht 1

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Spring MVC to iOS and the REST Spring MVC to iOS and the REST Presentation Transcript

  • Spring MVC to iOS and the RESTRoy Clarkson, Senior Engineer, VMwareTwitter/GitHub: @royclarksonJosh Long, Spring Developer AdvocateTwitter: @starbuxman GitHub: @joshlong© 2013 SpringSource, by VMware
  • About Roy Clarkson• Georgia Tech Alum• SpringSource Engineer at VMware• Lead on Spring for Android and Spring Mobile• Twitter/GitHub: @royclarkson• rclarkson@vmware.com• http://www.slideshare.net/royclarkson2
  • About Josh Long (⻰龙之春)Spring Developer Advocatetwitter: @starbuxmanweibo: @springsourcejosh.long@springsource.com 3
  • About Josh LongSpring Developer Advocatetwitter: @starbuxmanjosh.long@springsource.comContributor To:•Spring Integration•Spring Batch•Spring Hadoop•Activiti Workflow Engine4
  • Agenda• REST• Spring MVC• iOS• Demos5
  • The term Representational State Transfer was introduced and defined in 2000 by Roy Fielding in his doctoral dissertation.6
  • What is REST?• REpresentational State Transfer• An architectural style for designing distributed systems• Not a standard, but rather a set of constraints – Client/Server, Stateless, Uniform Interface, etc.• Not tied to HTTP, but associated most commonly with it7
  • The Principles of REST• Resources – Expose directory structure-like URIs – URI’s should be easily understood• Representations – Transfer XML, JavaScript Object Notation (JSON), or both – Use XML or JSON to represent data objects or attributes• Messages – Use HTTP methods explicitly (i.e. POST, GET, PUT, DELETE) – CRUD operations can be mapped to these existing methods• Stateless – State dependencies limit or restrict scalability8
  • What is HATEOAS?• Hypermedia As The Engine Of Application State• The client doesn’t have a built in knowledge of how to navigate and manipulate the model• Instead server provides that information dynamically to the user• Implemented by using media types and link relations9
  • HTTP GET• Retrieve information – Must be safe and idempotent• Can have side effects, but since the user doesn’t expect them, they shouldn’t be critical to the operation of the system• GET can be conditional or partial – If-Modified-Since – Range GET /pizzas/110
  • HTTP DELETE• Request that a resource be removed• The resource doesn’t have to be removed immediately – Removal may be a long running task DELETE /pizzas/111
  • HTTP PUT• Requests that the entity passed be stored at the URI• Can be used to create a new entity or modify an existing one – Creation of new entities is uncommon as it allows the client to select the id of the new entity PUT /toppings/1 { “name” : “Cheese” }12
  • HTTP POST• Requests that the resource at a URI do something with the enclosed entity• The major difference between POST and PUT are what resource the request URI identifies• For example, use PUT to create and POST to modify POST /toppings/1 { “name” : “Cheddar Cheese” }13
  • HTTP Status Codes• Status codes are an indicator the result of the server’s attempt to satisfy the request• Broadly divided in categories – 1XX: Informational – 2XX: Success – 3XX: Redirection – 4XX: Client Error – 5XX: Server Error14
  • Success Status Codes• 200 OK – Everything worked• 201 Created – The server has successfully created a new resource – Newly created resource’s location returned in the Location header• 202 Accepted – The server has accepted the request, but it is not yet complete – A location to determine the request’s current status can be returned in the Location header15
  • Client Error Status Codes• 400 Bad Request – Malformed Syntax – Should not be repeated without modification• 401 Unauthorized – Authentication is required – Includes a WWW-Authenticate header• 403 Forbidden – Server has understood, but refuses to honor the request – Should not be repeated without modification16
  • Client Error Status Codes• 404 Not Found – The server cannot find a resource matching a URI• 406 Not Acceptable – The server can only return response entities that do not match the client’s Accept header• 409 Conflict – The resource is in a state that is in conflict with the request – Client should attempt to rectify the conflict and then resubmit the request17
  • Media Types• Accept & Content-Type HTTP Headers• Client or server describes the content18
  • Spring Web MVC DispatcherServlet20
  • Annotations of Spring MVC• @Controller• @RequestMapping• @RequestParam• @PathVariable• @ResponseBody• @RequestBody• @ResponseStatus21
  • @Controller@Controllerpublic class PizzaController {...}22
  • @RequestMapping@Controller@RequestMapping("/pizzas")public class PizzaController { // POST /pizzas/bake @RequestMapping(value = "/bake", method = POST) public void bake() { ... }}23
  • @RequestParam@Controller@RequestMapping("/pizzas")public class PizzaController { // POST /pizzas/bake?temp=400 @RequestMapping(value = "/bake", method = POST) public void bake(@RequestParam Integer temp) { ... }}24
  • @PathVariable@Controller@RequestMapping("/pizzas")public class PizzaController { // POST /pizzas/bake/400 @RequestMapping(value = "/bake/{temp}", method = POST) public void bake(@PathVariable Integer temp) { ... }}25
  • @ResponseBody@Controller@RequestMapping("/pizzas")public class PizzaController { // GET /pizzas @RequestMapping( method = GET, produces = "application/json") public @ResponseBody List<Pizza> list() { ... }}26
  • @ResponseBody@Controller@RequestMapping("/pizzas")public class PizzaController { // GET /pizzas @RequestMapping(method = GET, produces = MediaType.APPLICATION_JSON_VALUE ) public @ResponseBody List<Pizza> list() { ... }}27
  • @RequestBody@Controller@RequestMapping("/pizzas")public class PizzaController { // PUT /pizzas @RequestMapping( method = PUT, consumes = "application/json") public void create(@RequestBody Pizza pizza) { ... }}28
  • @ResponseStatus@Controller@RequestMapping("/pizzas")public class PizzaController { // PUT /pizzas @ResponseStatus(HttpStatus.CREATED) @RequestMapping( method = PUT, consumes = "application/json") public void create(@RequestBody Pizza pizza) { ... }}29
  • Async MVC Processing: Callable@Controller@RequestMapping("/pizzas")public class PizzaController { @RequestMapping(value = "/orders", method = POST) @ResponseBody public Callable<String> upload(MultipartFile file) { return new Callable<Pizza>() { public Pizza call() throws Exception // ... return pizza; } }}30
  • Async MVC Processing: DeferredResult @RequestMapping("/quotes") @ResponseBody public DeferredResult quotes() { DeferredResult deferredResult = new DeferredResult(); // Add deferredResult to a Queue or a Map... return deferredResult;}// In some other thread:// Set the return value on the DeferredResultdeferredResult.set(data); - thread managed outside of Spring MVC - JMS or AMQP message listener, another HTTP request, etc. 31
  • Async MVC Processing: AsyncTask@RequestMapping(name =“/upload”,method=RequestMethod.POST) public AsyncTask<Foo> processUpload(MultipartFile file) { TaskExecutor asyncTaskExecutor = new AsyncTaskExecutor(...); return new AsyncTask<Foo>( 1000L, // timeout asyncTaskExecutor, // thread pool new Callable<Foo>(){ ..} // thread );} - same as Callable, with extra features - override timeout value for async processing - lets you specify a specific AsyncTaskExecutor 32
  • Message Converters• RSS/ATOM• java.awt.BufferedImage• JSON• JAXB• Write your own! – iCal – GSON• Third Party: • https://github.com/joshlong/spring-advanced-marhshallers-and-service-exporters – supports Google PB, Avro, Thrift, MessagePack, Google Snappy33
  • Spring MVC Demo
  • Testing• Testing of web APIs isn’t easy – In container, end-to-end, string comparison, etc. – Out of container, Java objects, bypassing much of Spring’s magic• What we want is out of container, but with as much of Spring as we can get35
  • Spring MVC Testing• Available in Spring 3.2• Bootstraps most of Spring’s MVC infrastructure so that you unit and integration test your web application end-to- end• Provides APIs for testing interesting parts of requests and responses36
  • REST on iOS• HTTP Client – NSURLConnection• JSON Processor (iOS 5) – NSJSONSerialization• Data – NSData – NSDictionary – NSArray38
  • NSURLConnection• Loading Data Synchronously + sendSynchronousRequest:returningResponse:error:• Loading Data Asynchronously + sendAsynchronousRequest:queue:completionHandler:39
  • Basic HTTP RequestNSURL *url = [NSURL URLWithString:@"http://localhost"];NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url];NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];40
  • Basic HTTP Request... ImprovedNSURL *url = [NSURL URLWithString:@"http://localhost"];NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url];NSURLResponse *response;NSError *error;NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];NSInteger status = [(NSHTTPURLResponse *)response statusCode];if (status == 200 && data.length > 0 && error == nil){ // do something with data}41
  • Asynchronous HTTP RequestNSURL *url = [NSURL URLWithString:@"http://localhost"];NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url];[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error){ NSInteger status = [(NSHTTPURLResponse *)response statusCode]; if (status == 200 && data.length > 0 && error == nil) { // do something with data }}42
  • HTTP HeadersNSURL *url = [NSURL URLWithString:@"http://localhost"];NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];[request setHTTPMethod:@"PUT"];[request setValue:@"application/json" forHTTPHeaderField:@"Accept"];[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];[request setValue:contentLength forHTTPHeaderField:@"Content-Length"];[request setHTTPBody:postData];43
  • JSON Serialization// deserialize JSON dataNSError *error;NSDictionary *d = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];// serialize JSON dataNSError *error;NSData *data = [NSJSONSerialization dataWithJSONObject:dictionary options:0 error:&error];44
  • iOS Demo
  • Conclusion• API Design Matters – URIs represent resources, not actions – HTTP verbs are general, but can be used in ways that make anything possible• Implementation isn’t rocket science – Spring MVC – Spring HATEOAS• Easy testing – Out-of-container, but full Spring stack46
  • More Information• Roy Fielding’s Dissertation http://www.ics.uci.edu/~fielding/pubs/dissertation/ evaluation.htm#sec_6_1%7C• Spring MVC Reference http://static.springsource.org/spring-framework/docs/ current/spring-framework-reference/html/mvc.html• URL Loading System Programming Guide http://developer.apple.com/library/ios/#documentation/ Cocoa/Conceptual/URLLoadingSystem/ URLLoadingSystem.html47
  • Related Spring Projects• REST Shell https://github.com/SpringSource/rest-shell• Spring HATEOAS https://github.com/SpringSource/spring-hateoas• Spring MVC Test https://github.com/SpringSource/spring-test-mvc48
  • Questions?• All Sample Code: https://github.com/royclarkson/rest-demo https://github.com/joshlong/the-spring-tutorial• Presentation: http://www.slideshare.net/royclarkson49