© 2013 SpringOne 2GX. All rights reserved. Do not distribute without permission. Building Smart Clients with Spring by Josh Long and Roy Clarkson
May 07, 2015
© 2013 SpringOne 2GX. All rights reserved. Do not distribute without permission.
Building Smart Clients with Springby Josh Long and Roy Clarkson
WHAT IS REST?
REST is an architectural constraint based on HTTP 1.1, and created as part of Roy Fielding’s doctoral dissertation in 2000.
It embraces HTTP.
It’s a style, not a standard
http://en.wikipedia.org/wiki/Representational_state_transfer
WHAT IS REST?
REST has no hard and fast rules.REST is an architectural style, not a standard.
REST uses Headers to describe requests & responses
REST embraces HTTP verbs
HTTP VERBS
GET /users/21
GET requests retrieve information.
GET can have side-effects (but it’s unexpected)
GET can be conditional, or partial: If-Modified-Since, Range
HTTP VERBS
DELETE requests that a resource be removed, though the deletion doesn’t have to be immediate.
DELETE /users/21
HTTP VERBS
POST requests that the resource do something with the enclosed entity
POST can be used to create or update.
POST /users { “firstName”: “Juergen” }
HTTP VERBS
PUT requests that the entity be stored at a URI
PUT can be used to create or update.
PUT /users/21{ “firstName”: “Juergen” }
THE MATURITY MODEL
The Richardson Maturity Model is a way to grade your API according to the REST constraints with 4 levels of increasing compliance
http://martinfowler.com/articles/richardsonMaturityModel.html
THE MATURITY MODEL
The Richardson Maturity Model
Level 0: swamp of POX
http://martinfowler.com/articles/richardsonMaturityModel.html
Uses HTTP mainly as a tunnel through one URI e.g., SOAP, XML-RPC
Usually features on HTTP verb (POST)
THE MATURITY MODEL
The Richardson Maturity Model
Level 1: resources
http://martinfowler.com/articles/richardsonMaturityModel.html
Multiple URIs to distinguish related nouns e.g., /articles/1, /articles/2, vs. just /articles
THE MATURITY MODEL
The Richardson Maturity Model
Level 2: HTTP verbs
http://martinfowler.com/articles/richardsonMaturityModel.html
leverage transport-native properties to enhance service e.g., HTTP GET and PUT and DELETE and POST
Uses idiomatic HTTP controls like status codes, headers
HTTP VERBS
GET /users/21
DELETE /users/21
POST /users
PUT /users/21
retrieves a resource from a URI
removes the resource
creates a new record; returns a Location
updates a resource
<filter> <filter-name>hiddenHttpMethodFilter</filter-name> <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class> </filter> <filter-mapping> <filter-name>hiddenHttpMethodFilter</filter-name> <url-pattern>/</url-pattern> <servlet-name>appServlet</servlet-name> </filter-mapping>
STATUS CODES
status codes convey the result of the server’s attempt to satisfy the request.
Categories:
1xx: informational 2xx: success 3xx: redirection 4xx: client error 5xx: server error
REST 101
200 OK - Everything worked
201 Created - Returns a Location header for new resource
202 Accepted - server has accepted the request, but it is not yet complete. Status URI optionally conveyed in Location header
REST DESIGN WITH SPRINGREST 101
ACCEPTABLE406:NOT
REST 101
400 Bad Request - Malformed Syntax. Retry with change.
401 Unauthorized - authentication is required
403 Forbidden - server has understood, but refuses request
404 Not Found - server can’t find a resource for URI
406 Not Found - incompatible Accept headers specified
409 Conflict - resource conflicts with client request
REST 101
Clients and services must agree on a representation media type through content negotiation.
Client specifies what it wants through Accept header
Server specifies what it produces through Content-Type header
REST 101
Spring MVC supports multiple types of content negotiation through its ContentNegotiationStrategy: e.g., Accept header, URL extension, request parameters, or a fixed type
DemonstrationBasic RESTful service, REST shells
HATEOAS
The Richardson Maturity Model
Level 3: Hypermedia Controls (aka, HATEOAS)
http://martinfowler.com/articles/richardsonMaturityModel.html
No a priori knowledge of service requiredNavigation options are provided by service and hypermedia controls
Promotes longevity through a uniform interface
HATEOAS
Links provide possible navigations from a given resource
Links are dynamic, based on resource state.
<link href=“http://...:8080/users/232/customers” rel= “customers”/>
DemonstrationSpring HATEOAS, Rest Shell
SPRING DATA REST
Spring Data REST simplifies the generic data-centric @Controllers
Builds on top of Spring Data Repository support:
@RestResource (path = "users", rel = "users")
public interface UserRepository extends PagingAndSortingRepository<User, Long> {
User findByUsername(@Param ("username") String username);
SPRING DATA REST
Spring Data REST simplifies the generic data-centric @Controllers
Builds on top of Spring Data Repository support:
@RestResource (path = "users", rel = "users")
public interface UserRepository extends PagingAndSortingRepository<User, Long> {
User findByUsername(@Param ("username") String username);
select u from User where u.username = ?
SPRING DATA REST
Spring Data REST simplifies the generic data-centric @Controllers
Builds on top of Spring Data Repository support:
@RestResource (path = "users", rel = "users")
public interface UserRepository extends PagingAndSortingRepository<User, Long> {
List<User> findUsersByFirstNameOrLastNameOrUsername( @Param ("firstName") String firstName, @Param ("lastName") String lastName, @Param ("username") String username);}
SPRING DATA REST
Spring Data REST simplifies the generic data-centric @Controllers
Builds on top of Spring Data Repository support:
@RestResource (path = "users", rel = "users")
public interface UserRepository extends PagingAndSortingRepository<User, Long> {
List<User> findUsersByFirstNameOrLastNameOrUsername( @Param ("firstName") String firstName, @Param ("lastName") String lastName, @Param ("username") String username);}
select u from User u where u.username = ? or u.firstName = ? or u.lastName = ?
DemonstrationSpring Data, Spring Data REST
SECURITY
Security can be as simple, or complex, as you want...
If you can trust the client to keep a secret like a password:
...HTTP Basic if you have TLS ... HTTP Digest if you want extra security
OAUTH
Security can be as simple, or complex, as you want...
Can’t trust the client to keep a secret? (HTML page?)
Application has a user context and you don’t want clients to have a user’s password?
...use OAuth
OAUTH
OAUTH
OAUTH
DemonstrationSpring Security OAuth
SPRING SOCIAL
Spring Social provides an authentication and authorization client for OAuth (1.0, 1.0a, 2.0)
Provides type-safe API bindings for various services
BINDINGS...
...LOTS OF BINDINGS
DemonstrationSpring Social
SPRING ANDROID
Spring Social provides an authentication and authorization client for OAuth (1.0, 1.0a, 2.0)
Provides type-safe API bindings for various services
SPRING ANDROID
Spring Android brings Spring core’s RestTemplate.
Spring Social and Spring HATEOAS work as well.
SPRING ANDROID
More than 500,000 activations every day
More than 500,000 activations every day
DemonstrationSpring Android-powered UI client
USING REST AND OAUTH FROM IOS
REST DESIGN WITH SPRING
iOS provides an HTTP client (NSURLConnection), a JSON processor (NSJSONSerialization), and a rich set of data structures (NSData, NSDictionary, and NSArray)
BASIC HTTP REQUEST
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
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 REQUESTS
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
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
// 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];
• HTTP Client– NSURLConnection
• JSON Processor (iOS 5)– NSJSONSerialization
• Data– NSData– NSDictionary– NSArray
49
• Loading Data Synchronously
+ sendSynchronousRequest:returningResponse:error:
• Loading Data Asynchronously
+ sendAsynchronousRequest:queue:completionHandler:
50
51
NSURL *url = [NSURL URLWithString:@"http://localhost"];NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url];
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
52
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}
53
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}
}
54
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];
55
// 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
Q&A
• 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
• Ben Hale’s presentation at SpringOne 2GXhttp://www.youtube.com/watch?v=wylViAqNiRA
58
• Spring Roo Beginning Guidehttp://static.springsource.org/spring-roo/reference/html/beginning.html#beginning-step-1
59
GREAT RESOURCES
Roy Fielding’s Dissertation introduces REST http://www.ics.uci.edu/~fielding/pubs/dissertation/evaluation.htm#sec_6_1%7C
The Spring REST Shell http://github.com/jbrisbin/rest-shell
Spring Security, Security OAuth, Spring Data REST, HATEOAS, Social http://github.com/SpringSource
Spring MVC Test Framework http://static.springsource.org/spring-framework/docs/current/spring-framework-reference/html/testing.html#spring-mvc-test-framework
GREAT RESOURCES
Oliver Gierke’s talk on Hypermedia from Øredev @ http://vimeo.com/53214577
Lez Hazelwood’s talk on designing a beautiful JSON+REST API
Ben Hale’s talk on REST API design with Spring from SpringOne2GX 2012 @ http://www.youtube.com/watch?v=wylViAqNiRA
My links:
github.com/joshlong/the-spring-rest-stack
slideshare.net/joshlong/rest-apis-with-spring
@starbuxman
REST DESIGN WITH SPRING
Any
Questions?@starbuxman | [email protected] | http://slideshare.net/joshlong@royclarkson | [email protected] |http://www.slideshare.net/royclarkson
github.com/joshlong/the-spring-rest-stack