spring mvc to ios and the rest

49
© 2013 SpringSource, by VMware Spring MVC to iOS and the REST Roy Clarkson, Senior Engineer, VMware Twitter/GitHub: @royclarkson Josh Long, Spring Developer Advocate Twitter: @starbuxman GitHub: @joshlong

Upload: roy-clarkson

Post on 07-May-2015

8.004 views

Category:

Technology


7 download

DESCRIPTION

Presented at DevNexus 2013

TRANSCRIPT

Page 1: Spring MVC to iOS and the REST

© 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

Page 2: Spring MVC to iOS and the REST

• 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

Page 3: Spring MVC to iOS and the REST

Spring Developer Advocatetwitter: @starbuxmanweibo: @springsource [email protected]

3

About Josh Long (⻰龙之春)

Page 4: Spring MVC to iOS and the REST

About Josh Long

Spring Developer Advocatetwitter: @[email protected]

Contributor To:

•Spring Integration•Spring Batch •Spring Hadoop•Activiti Workflow Engine

4

Page 5: Spring MVC to iOS and the REST

Agenda

• REST• Spring MVC• iOS• Demos

5

Page 6: Spring MVC to iOS and the REST

6

The term Representational State Transfer was introduced and defined in 2000 by Roy Fielding in his doctoral dissertation.

Page 7: Spring MVC to iOS and the REST

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

Page 8: Spring MVC to iOS and the REST

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

Page 9: Spring MVC to iOS and the REST

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

Page 10: Spring MVC to iOS and the REST

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

Page 11: Spring MVC to iOS and the REST

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

Page 12: Spring MVC to iOS and the REST

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” }

Page 13: Spring MVC to iOS and the REST

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” }

Page 14: Spring MVC to iOS and the REST

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

Page 15: Spring MVC to iOS and the REST

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

Page 16: Spring MVC to iOS and the REST

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

Page 17: Spring MVC to iOS and the REST

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

Page 18: Spring MVC to iOS and the REST

Media Types

• Accept & Content-Type HTTP Headers• Client or server describes the content

18

Page 19: Spring MVC to iOS and the REST
Page 20: Spring MVC to iOS and the REST

Spring Web MVC DispatcherServlet

20

Page 21: Spring MVC to iOS and the REST

Annotations of Spring MVC

• @Controller• @RequestMapping• @RequestParam• @PathVariable• @ResponseBody• @RequestBody• @ResponseStatus

21

Page 22: Spring MVC to iOS and the REST

@Controller

22

@Controllerpublic class PizzaController {...}

Page 23: Spring MVC to iOS and the REST

@RequestMapping

23

@Controller@RequestMapping("/pizzas")public class PizzaController {

// POST /pizzas/bake@RequestMapping(value = "/bake", method = POST)

public void bake() {...

}}

Page 24: Spring MVC to iOS and the REST

@RequestParam

24

@Controller@RequestMapping("/pizzas")public class PizzaController {

// POST /pizzas/bake?temp=400@RequestMapping(value = "/bake", method = POST)

public void bake(@RequestParam Integer temp) { ... }}

Page 25: Spring MVC to iOS and the REST

@PathVariable

25

@Controller@RequestMapping("/pizzas")public class PizzaController {

// POST /pizzas/bake/400 @RequestMapping(value = "/bake/{temp}", method = POST) public void bake(@PathVariable Integer temp) { ... }}

Page 26: Spring MVC to iOS and the REST

@ResponseBody

26

@Controller@RequestMapping("/pizzas")public class PizzaController {

// GET /pizzas @RequestMapping( method = GET, produces = "application/json") public @ResponseBody List<Pizza> list() { ... }}

Page 27: Spring MVC to iOS and the REST

@ResponseBody

27

@Controller@RequestMapping("/pizzas")public class PizzaController {

// GET /pizzas @RequestMapping(method = GET, produces = MediaType.APPLICATION_JSON_VALUE ) public @ResponseBody List<Pizza> list() { ... }}

Page 28: Spring MVC to iOS and the REST

@RequestBody

28

@Controller@RequestMapping("/pizzas")public class PizzaController {

// PUT /pizzas @RequestMapping( method = PUT, consumes = "application/json") public void create(@RequestBody Pizza pizza) { ... }}

Page 29: Spring MVC to iOS and the REST

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

Page 30: Spring MVC to iOS and the REST

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; } }}

Page 31: Spring MVC to iOS and the REST

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.

Page 32: Spring MVC to iOS and the REST

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

Page 33: Spring MVC to iOS and the REST

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

Page 34: Spring MVC to iOS and the REST

Spring MVC Demo

Page 35: Spring MVC to iOS and the REST

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

Page 36: Spring MVC to iOS and the REST

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

Page 37: Spring MVC to iOS and the REST
Page 38: Spring MVC to iOS and the REST

REST on iOS

• HTTP Client– NSURLConnection

• JSON Processor (iOS 5)– NSJSONSerialization

• Data– NSData– NSDictionary– NSArray

38

Page 39: Spring MVC to iOS and the REST

NSURLConnection

• Loading Data Synchronously

+ sendSynchronousRequest:returningResponse:error:

• Loading Data Asynchronously

+ sendAsynchronousRequest:queue:completionHandler:

39

Page 40: Spring MVC to iOS and the REST

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];

Page 41: Spring MVC to iOS and the REST

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}

Page 42: Spring MVC to iOS and the REST

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}

}

Page 43: Spring MVC to iOS and the REST

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];

Page 44: Spring MVC to iOS and the REST

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];

Page 45: Spring MVC to iOS and the REST

iOS Demo

Page 46: Spring MVC to iOS and the REST

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

Page 47: Spring MVC to iOS and the REST

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

Page 48: Spring MVC to iOS and the REST

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

Page 49: Spring MVC to iOS and the REST

Questions?

• All Sample Code:https://github.com/royclarkson/rest-demohttps://github.com/joshlong/the-spring-tutorial

• Presentation:http://www.slideshare.net/royclarkson

49