spring mvc to ios and the rest
DESCRIPTION
Presented at DevNexus 2013TRANSCRIPT
© 2013 SpringSource, by VMware
Spring MVC to iOS and the REST
Roy Clarkson, Senior Engineer, VMwareTwitter/GitHub: @royclarkson
Josh Long, Spring Developer AdvocateTwitter: @starbuxman GitHub: @joshlong
• Georgia Tech Alum• SpringSource Engineer at VMware• Lead on Spring for Android and Spring Mobile• Twitter/GitHub: @royclarkson• [email protected]• http://www.slideshare.net/royclarkson
About Roy Clarkson
2
Spring Developer Advocatetwitter: @starbuxmanweibo: @springsource [email protected]
3
About Josh Long (⻰龙之春)
About Josh Long
Spring Developer Advocatetwitter: @[email protected]
Contributor To:
•Spring Integration•Spring Batch •Spring Hadoop•Activiti Workflow Engine
4
Agenda
• REST• Spring MVC• iOS• Demos
5
6
The term Representational State Transfer was introduced and defined in 2000 by Roy Fielding in his doctoral dissertation.
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 it
7
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 scalability
8
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 relations
9
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
10
GET /pizzas/1
HTTP DELETE
• Request that a resource be removed• The resource doesn’t have to be removed immediately
– Removal may be a long running task
11
DELETE /pizzas/1
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
12
PUT /toppings/1{ “name” : “Cheese” }
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
13
POST /toppings/1{ “name” : “Cheddar Cheese” }
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 Error
14
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 header
15
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 modification
16
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 request
17
Media Types
• Accept & Content-Type HTTP Headers• Client or server describes the content
18
Spring Web MVC DispatcherServlet
20
Annotations of Spring MVC
• @Controller• @RequestMapping• @RequestParam• @PathVariable• @ResponseBody• @RequestBody• @ResponseStatus
21
@Controller
22
@Controllerpublic class PizzaController {...}
@RequestMapping
23
@Controller@RequestMapping("/pizzas")public class PizzaController {
// POST /pizzas/bake@RequestMapping(value = "/bake", method = POST)
public void bake() {...
}}
@RequestParam
24
@Controller@RequestMapping("/pizzas")public class PizzaController {
// POST /pizzas/bake?temp=400@RequestMapping(value = "/bake", method = POST)
public void bake(@RequestParam Integer temp) { ... }}
@PathVariable
25
@Controller@RequestMapping("/pizzas")public class PizzaController {
// POST /pizzas/bake/400 @RequestMapping(value = "/bake/{temp}", method = POST) public void bake(@PathVariable Integer temp) { ... }}
@ResponseBody
26
@Controller@RequestMapping("/pizzas")public class PizzaController {
// GET /pizzas @RequestMapping( method = GET, produces = "application/json") public @ResponseBody List<Pizza> list() { ... }}
@ResponseBody
27
@Controller@RequestMapping("/pizzas")public class PizzaController {
// GET /pizzas @RequestMapping(method = GET, produces = MediaType.APPLICATION_JSON_VALUE ) public @ResponseBody List<Pizza> list() { ... }}
@RequestBody
28
@Controller@RequestMapping("/pizzas")public class PizzaController {
// PUT /pizzas @RequestMapping( method = PUT, consumes = "application/json") public void create(@RequestBody Pizza pizza) { ... }}
29
@Controller@RequestMapping("/pizzas")public class PizzaController {
// PUT /pizzas @ResponseStatus(HttpStatus.CREATED) @RequestMapping( method = PUT, consumes = "application/json") public void create(@RequestBody Pizza pizza) { ... }}
@ResponseStatus
Async MVC Processing: Callable
30
@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; } }}
Async MVC Processing: DeferredResult
31
@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 DeferredResult deferredResult.set(data);
- thread managed outside of Spring MVC- JMS or AMQP message listener, another HTTP request, etc.
Async MVC Processing: AsyncTask
32
@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
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 Snappy
33
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 get
35
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 responses
36
REST on iOS
• HTTP Client– NSURLConnection
• JSON Processor (iOS 5)– NSJSONSerialization
• Data– NSData– NSDictionary– NSArray
38
NSURLConnection
• Loading Data Synchronously
+ sendSynchronousRequest:returningResponse:error:
• Loading Data Asynchronously
+ sendAsynchronousRequest:queue:completionHandler:
39
Basic HTTP Request
40
NSURL *url = [NSURL URLWithString:@"http://localhost"];NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url];
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
Basic HTTP Request... Improved
41
NSURL *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}
Asynchronous HTTP Request
42
NSURL *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}
}
HTTP Headers
43
NSURL *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];
JSON Serialization
44
// 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];
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 stack
46
More Information
• Roy Fielding’s Dissertationhttp://www.ics.uci.edu/~fielding/pubs/dissertation/evaluation.htm#sec_6_1%7C
• Spring MVC Referencehttp://static.springsource.org/spring-framework/docs/current/spring-framework-reference/html/mvc.html
• URL Loading System Programming Guidehttp://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/URLLoadingSystem/URLLoadingSystem.html
47
Related Spring Projects
• REST Shellhttps://github.com/SpringSource/rest-shell
• Spring HATEOAShttps://github.com/SpringSource/spring-hateoas
• Spring MVC Testhttps://github.com/SpringSource/spring-test-mvc
48
Questions?
• All Sample Code:https://github.com/royclarkson/rest-demohttps://github.com/joshlong/the-spring-tutorial
• Presentation:http://www.slideshare.net/royclarkson
49