SlideShare ist ein Scribd-Unternehmen logo
1 von 61
Downloaden Sie, um offline zu lesen
Modelling RESTful applications – Why
should I not use verbs in REST url
Anirudh Bhatnagar
Xebia India IT Architects Pvt Ltd
REST
Representational state transfer ??
Specification ???
Guidelines ???
Architecture style??
Its Just a STYLE!
The REST architectural style was developed by W3C
Technical Architecture Group (TAG) in parallel with
HTTP/1.1, based on the existing design of HTTP/1.0.
Roy Fielding’s paper on REST architectural style
Architectural Styles and the Design of Network-based Software
Architectures
DISSERTATION
submitted in partial satisfaction of the requirements for the degree of
DOCTOR OF PHILOSOPHY
in Information and Computer Science
by
Roy Thomas Fielding
2000
REST, HTTP and Web
HTTP Specification
GET ../foods/1 would get you the food with id 1.
PUT ../foods/2 would update the food with id 2.
POST ../foods will add a new food.
DELETE ../foods/1 will delete the food resource with
id 1.
But what about other verbs???
--- approve
-- reject
-- cancel
-- search
-- increase
-- decrease
…..
…..
Can I just put them in my URL??
what would go wrong?
Lets see a video
http://www.youtube.com/watch?v=65ilZ8esAUs
Improper handling of method and no safeguard
Result : Disaster!!!
How do we solve this?
HTTP Specifications
1. Safe and Unsafe Methods
excerpt from w3 HTTP Specification…
…..GET and HEAD methods SHOULD NOT have the significance of
taking an action other than retrieval.
These methods ought to be considered "safe". This allows user agents to
represent other methods, such as POST, PUT and DELETE, in a special
way, so that the user is made aware of the fact that a possibly unsafe
action is being requested....
GET and HEAD should have no side-effects : They
should not change the state.
Clearly we can not use GET in our API..
2.Idempotency
An idempotent HTTP method can be called many times
without different outcomes.
a = 4 ->idempotent
a++ -> non idempotent
...Methods can also have the property of "idempotence" in that (aside from
error or expiration issues) the side-effects of N > 0 identical requests is
the same as for a single request. The methods GET, HEAD, PUT and
DELETE share this property…
..POST is non-idempotent..
Fault Tolerant - Idempotent Methods
- if request timed out - can you safely retry?
- no need to worry if idempotent
Browser Support
Confirm Form submission
On refresh of Unsafe Method (POST form)
Caching
Non-safe and non-idempotent methods will never be
cached by any middleware proxies.
Safe Methods like GET and HEAD are candidate for
caching.
caching with GET
Every GET call is a candidate for caching..
If you have method :
HTTP/1.1 GET …./users/1/update
This might not actually update and return you the
cached result.
Bad Urls hamper caching!
HTTP 1.1 GET
http://myTestApp/page4.do?dau22.
oid=5199&UserCtxParam=0&GroupCtxParam=0&dctx
1=25&ctx1=US&crc=712082047
HTTP Caching
Browser Caches
Proxy Cache
example : Squid
Gateway Cache : Reverse Proxy
Benefits of HTTP Caching
- Server side caching is expensive..
- Reduce latency
- Reduce network traffic
-CDNs can leverage proxy caches.
Leverage Caching effectively
With great power comes great responsibility...
How to control caching effectively?
Invalidations?
Cache expiry?
Stale cache?
Volatile data?
- expires
- cache control
-Etags
-last modified
- validation headers
HTTP headers
Expires Header
● HTTP 1.0
So, if we made an API call to retrieve data
……….. GET /users/1
The response header would be:
HTTP/1.1 200 OK
Content-Type: application/xml
Expires: Tue, 25 Aug 2013 16:00 GMT
-----
<user id="1">...</users>
JAX-RS support for expires..
@Path("{id}")
@GET
@Produces(MediaType.APPLICATION_XML)
public Response getUserXML(@PathParam("id") Long id){
User user = userDB.get(id);
ResponseBuilder builder = Response.ok(user,MediaType.
APPLICATION_XML);
//Putting expires header for HTTP browser caching.
Calendar cal = Calendar.getInstance();
cal.set(2013,7,25,16,0);
builder.expires(cal.getTime());
return builder.build();
}
HTTP 1.1
support CDNs, proxy caches and revalidations there
was a need for more enhanced headers with richer set of
features, having more explicit controls.
Cache-Control
Cache-Control has a variable set of comma-delimited
directives that define who,how and for how long it can
be cached. Lets explore few of them:
-private/public : these are accessibility directives,
private means a browser can cache the object but the
proxies or CDNs can not and public makes it cachable
by all.
-no-cache,no-store,max-age are few others where
name tells the story.
JAX-RS support for Cache-Control
@Path("{id}")
@GET
@Produces(MediaType.APPLICATION_XML)
public Response getUserXMLwithCacheControl(@PathParam("id")
Long id){
User user = userDB.get(id);
CacheControl cc = new CacheControl();
cc.setMaxAge(300);
cc.setNoStore(true);
cc.setPrivate(true);
ResponseBuilder builder = Response.ok(user,MediaType.
APPLICATION_XML);
builder.cacheControl(cc);
return builder.build();
}
Validation Headers and Conditional GETs
When cache is stale, client can ask server if cache still valid
To be able to revalidate client needs additional headers
beyond Cache-Control from a server response
•Last-Modified - a date when the resource was last modified
•ETag - a unique hash-like key that identifies a version of the
resource
Client should cache these headers along with response body
To revalidate client sends conditional GETs using values of these
header tags.
Last-Modified and If-Modified-Since
Server sends in response header
HTTP/1.1 200 OK
....
Cache-Control: max-age=1000
Last-Modified: Mon, 19 aug 2013 16:00 IST
Client revalidates using conditional GET
GET /users/23 HTTP/1.1
If-Modified-Since: Mon, 19 aug 2013 16:00 IST
in case it is modified after this date; a response code 200 (OK) with
current value of resource will be sent.
And if the data is not modified a response code of “304″
Etag and If-None-Match
● an MD5 hash value.
● generated from resource is sent by server in
response.
● client caches it and uses this to revalidate using If-
None-Match tag in request header.
GET /users/23 HTTP/1.1
If-None-Match: "23432423423454654667444"
Server verifies the hash, if it matches sends “304” else
sends current value with response code 200 and resets
the etag.
JAX-RS support Validation
JAX-RS also provided one injectable helper class Request, which has methods
like…
....
ResponseBuilder evalutatePostConditions(EntityTag eTag);
ResponseBuilder evaluatePreConditions(Date isLastModified);
.....
And...
JAX-RS provides us with javax.ws.rs.core.EntityTag for the same
The values sent by client (which they have cached) are compared with latest
values at the server.
JAX-RS and Validation
@Path("{id}")
@GET
@Produces(MediaType.APPLICATION_XML)
public Response getUserWithEtagSupport(@PathParam("id") Long id,
@Context Request request){
User user = userDB.get(id);
//generating Etag out of hashCode of user
EntityTag tag = new EntityTag(Integer.toString(user.hashCode()));
CacheControl cc = new CacheControl();
cc.setMaxAge(1000);
ResponseBuilder builder = request.evaluatePreconditions(tag);
if(builder!=null){
//means the preconditions have been met and the cache is valid
//we just need to reset the cachecontrol max age (optional)
builder.cacheControl(cc);
return builder.build();
}
//preconditions are not met and the cache is invalid
//need to send new value with response code 200 (OK)
builder = Response.ok(user,MediaType.APPLICATION_XML);
//reset cache control and eTag (mandatory)
builder.cacheControl(cc);
builder.tag(tag);
return builder.build();
}
HTTP PURGE
HTTP has an unofficial PURGE method that is used for
purging caches.
When an API receives a call with an unsafe method on
a resource, it should fire a PURGE request on that
resource so that the reverse proxy knows that the
cached resource should be expired.
We dont need to perform explicit revalidations in this
case.
GET /article/1234 HTTP/1.1 -
- The resource is not cached yet
- Send request to the API
- Store response in cache and return
GET /article/1234 HTTP/1.1
- The resource is cached
- Return response from cache
PUT /article/1234 HTTP/1.1
- Unsafe method, send to API
PURGE /article/1234 HTTP/1.1
- API sends PURGE method to the cache
- The resources is removed from the cache
GET /article/1234 HTTP/1.1
- The resource is not cached yet
- Send request to the API -
- Store response in cache and return
Let’s complete our “pitaji ki patloon” problem
GET
-No side effects- should not change the state
-idempotent
HTTP1.1 GET /pitaji/patloon/12/length?
method=decrease&size=1b
Caching will not work!
PUT
- idempotent
- HTTP1.1 PUT /pitaji/patloon/12/length
{“decrease” : “1 bilaank” }
This will result in disaster, as the browser can call the
PUT multiple times, in case of timeouts/network
latency etc.
DELETE
HTTP/1.1 DELETE /pitaji/patloon/12/length
{“decrease” : “1 bilaank” }
this API does not make sense, it will confuse the client!
moreover again performing unsafe operation with safe
method.
POST
Unsafe method
HTTP1.1 POST /pitaji/patloon/length
{“decrease” : “1 bilaank” }
Use Case
An example of a social Site :
1.) Add friend
2.) Remove Friend
3.) Approve Friend Request
4.) Reject Friend Request
5.) Make a new account
6.) Delete account.
7.) Search Users.
…...
Approach 1 : userFriendMapping table
@Entity
@Table(name = "userFriendMapping")
public class UserFriendMapping {
private long id;
private User user;
private User friend;
private String status;
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "id", unique = true, nullable = false)
public long getId() {
return id;
}
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name="userId")
public User getUser() {
……
Add and Approve friend request
1. Add a friend (send friendRequest)
POST ../userfriendmapping
{userId: 1,
friendId : 2,
status:pending}
2. Approve friend Request
POST ../userfriendmapping
{userId: 1,
friendId : 2,
status:approved}
reject friend, get pending requests
3. Reject friend Request
DELETE ../userfriendmapping/1
4.Get pending friends
GET ../userfriendmapping/users/1?status=pending
5. Delete existing Friend
DELETE ../userfriendmapping/2
More extensions
List all friend requests
List all pending friends..
List all friends..
List all rejected requests..
Do not allow a user to resend the friend request..
BlackList Users
Ignore a friend request
Problems
Single domain catering to responsibilty of two states :
1.) FriendRequest
2.) UserFriendRelation
Increases complexity, more effort, tightly coupled,
separation of concern?
1. Separate domains give more flexibility and ease for
extensibility.
2. As we have states and resources as domains, making
RESTful urls is easy.
3. Querying is easy.
example :
- to find friends need 2 calls to DB, or put a UNION
API : Find all myfriends
@Override
public List<User> findFriends(Long userId,String status) {
List<UserFriendMapping> allFriends =
userFriendMappingPersistence.getAllFriends(userId,status);
List<UserFriendMapping> friendsWhoAddedMe =
userFriendMappingPersistence.getByFriendId(userId,status);
List<User> friends = new ArrayList<User>();
for (UserFriendMapping userFriendMapping : allFriends) {
friends.add(userFriendMapping.getFriend());
}
for (UserFriendMapping userFriendMapping : friendsWhoAddedMe)
{
friends.add(userFriendMapping.getUser());
}
return friends;
}
Resource Oriented Architecture
A resource-oriented architecture is the structural design
supporting the internetworking of resources.
A resource, in this context, is any entity that can be
identified and assigned a uniform resource identifier (URI).
any states , verbs which acts as a resource
can be made model like FriendRequest or
BookOrder.
Alternate Approach
Model driven Architecture and Resource Driven Architecture.
provides intuitive way of designing APIs in RESTful manner.
Add 2 domain classes
● FriendRequest
● UserFriend or FriendShip or Relation
The RESTful APIs :
1. add Friend
POST ../users/1/friendrequests?friendid=2
@Path("/users/{id}/friendrequests")
@POST
public String createFriendRequest(@PathParam("id") Long userId,
@QueryParam(value="friendid")Long friendId){
…...
Approve and Reject friendRequest
2. Approve:
POST .. /userfriends/friendrequests/22 -> creating a new friend from
friendRequest with id22
3.Reject
DELETE ../friendrequests/22
4.Remove a friend
DELETE ../userfriends/3
5. GET on ..users/2/friendrequests will give all pending friend requests
6. GET on ..users/1/userfriends/ will give all friends of user
Search Users
Search is GET
USE GET with QUERY PARAMS
HTTP1.1 GET ../users?firstname=abc&age=25
Versioning APIs in REST
Add version in URL
GET ../version/users/1
Example twitter:
GET https://api.twitter.com/1/statuses/user_timeline.
json
Use HTTP Redirection Response codes for versioning
● 301 Moved permanently - point to new URL
● 302 Found indicating that the requested resource temporarily is located
at another location, while requested URI may still supported.
Model Driven Design produces RESTful Urls
RAD tools which generate code like Spring ROO or
Rails/Grails.
These are made on top of domains and models.
Take business domains from framework to other.
More extensibility and portability.
and of course they provide RESTful URLs.
Finally, Is it Just to avoid verbs and have better
Urls?
The approach should be the other way :
Better modelling and better design gives way to better
URLs and cleaner approach.
Conclusion
REST is no specification, its a style which adheres to
HTTP specification.
So, in order to make full use of HTTP and REST
--- Better modelling will automatically avoid verbs.
--- Take care of idempotent and safe/unsafe methods.
--- Use cache-control headers to make best use of
caching.
Thanks!!!
Questions and Feedback.
twitter : anirudh_bh
blog : http://anirudhbhatnagar.com
mail : anirudh.bh@gmail.com
github: https://github.com/anirudh83
References
www.w3.org/Protocols/rfc2616/rfc2616-sec13.html
http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html
http://javasymposium.techtarget.com/html/images/BBurke_Scaling_JAX-
RS.pdf
http://restcookbook.com/Basics/caching/
http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html
http://www.squid-cache.org/
http://odino.org/rest-better-http-cache/

Weitere ähnliche Inhalte

Was ist angesagt?

Ruby On Rails Seminar Basis Softexpo Feb2010
Ruby On Rails Seminar Basis Softexpo Feb2010Ruby On Rails Seminar Basis Softexpo Feb2010
Ruby On Rails Seminar Basis Softexpo Feb2010
arif44
 
Mobicents JSLEE progress and roadmap - Mobicents Summit 2011
Mobicents JSLEE progress and roadmap - Mobicents Summit 2011Mobicents JSLEE progress and roadmap - Mobicents Summit 2011
Mobicents JSLEE progress and roadmap - Mobicents Summit 2011
telestax
 

Was ist angesagt? (17)

Java EE 7: Whats New in the Java EE Platform @ Devoxx 2013
Java EE 7: Whats New in the Java EE Platform @ Devoxx 2013Java EE 7: Whats New in the Java EE Platform @ Devoxx 2013
Java EE 7: Whats New in the Java EE Platform @ Devoxx 2013
 
JAX-RS 2.0: RESTful Web Services
JAX-RS 2.0: RESTful Web ServicesJAX-RS 2.0: RESTful Web Services
JAX-RS 2.0: RESTful Web Services
 
JEE Programming - 04 Java Servlets
JEE Programming - 04 Java ServletsJEE Programming - 04 Java Servlets
JEE Programming - 04 Java Servlets
 
REST Architecture with use case and example
REST Architecture with use case and exampleREST Architecture with use case and example
REST Architecture with use case and example
 
Sherlock Homepage - A detective story about running large web services (VISUG...
Sherlock Homepage - A detective story about running large web services (VISUG...Sherlock Homepage - A detective story about running large web services (VISUG...
Sherlock Homepage - A detective story about running large web services (VISUG...
 
RESTing with JAX-RS
RESTing with JAX-RSRESTing with JAX-RS
RESTing with JAX-RS
 
Ruby On Rails Seminar Basis Softexpo Feb2010
Ruby On Rails Seminar Basis Softexpo Feb2010Ruby On Rails Seminar Basis Softexpo Feb2010
Ruby On Rails Seminar Basis Softexpo Feb2010
 
Intoduction to Play Framework
Intoduction to Play FrameworkIntoduction to Play Framework
Intoduction to Play Framework
 
Java Web Programming [5/9] : EL, JSTL and Custom Tags
Java Web Programming [5/9] : EL, JSTL and Custom TagsJava Web Programming [5/9] : EL, JSTL and Custom Tags
Java Web Programming [5/9] : EL, JSTL and Custom Tags
 
Java Web Programming [2/9] : Servlet Basic
Java Web Programming [2/9] : Servlet BasicJava Web Programming [2/9] : Servlet Basic
Java Web Programming [2/9] : Servlet Basic
 
The Play Framework at LinkedIn
The Play Framework at LinkedInThe Play Framework at LinkedIn
The Play Framework at LinkedIn
 
Java Web Programming [8/9] : JSF and AJAX
Java Web Programming [8/9] : JSF and AJAXJava Web Programming [8/9] : JSF and AJAX
Java Web Programming [8/9] : JSF and AJAX
 
Java EE 8 Recipes
Java EE 8 RecipesJava EE 8 Recipes
Java EE 8 Recipes
 
OCM Java 開發人員認證與設計模式
OCM Java 開發人員認證與設計模式OCM Java 開發人員認證與設計模式
OCM Java 開發人員認證與設計模式
 
Java Web Programming on Google Cloud Platform [1/3] : Google App Engine
Java Web Programming on Google Cloud Platform [1/3] : Google App EngineJava Web Programming on Google Cloud Platform [1/3] : Google App Engine
Java Web Programming on Google Cloud Platform [1/3] : Google App Engine
 
Working with Servlets
Working with ServletsWorking with Servlets
Working with Servlets
 
Mobicents JSLEE progress and roadmap - Mobicents Summit 2011
Mobicents JSLEE progress and roadmap - Mobicents Summit 2011Mobicents JSLEE progress and roadmap - Mobicents Summit 2011
Mobicents JSLEE progress and roadmap - Mobicents Summit 2011
 

Ähnlich wie Indic threads delhi13-rest-anirudh

Web Site Optimization
Web Site OptimizationWeb Site Optimization
Web Site Optimization
Sunil Patil
 
Web site optimization
Web site optimizationWeb site optimization
Web site optimization
Sunil Patil
 
12 core technologies you should learn, love, and hate to be a 'real' technocrat
12 core technologies you should learn, love, and hate to be a 'real' technocrat12 core technologies you should learn, love, and hate to be a 'real' technocrat
12 core technologies you should learn, love, and hate to be a 'real' technocrat
Jonathan Linowes
 
RESTful SOA - 中科院暑期讲座
RESTful SOA - 中科院暑期讲座RESTful SOA - 中科院暑期讲座
RESTful SOA - 中科院暑期讲座
Li Yi
 

Ähnlich wie Indic threads delhi13-rest-anirudh (20)

Service approach for development Rest API in Symfony2
Service approach for development Rest API in Symfony2Service approach for development Rest API in Symfony2
Service approach for development Rest API in Symfony2
 
Web Site Optimization
Web Site OptimizationWeb Site Optimization
Web Site Optimization
 
Web site optimization
Web site optimizationWeb site optimization
Web site optimization
 
12 core technologies you should learn, love, and hate to be a 'real' technocrat
12 core technologies you should learn, love, and hate to be a 'real' technocrat12 core technologies you should learn, love, and hate to be a 'real' technocrat
12 core technologies you should learn, love, and hate to be a 'real' technocrat
 
Web Scraping with PHP
Web Scraping with PHPWeb Scraping with PHP
Web Scraping with PHP
 
REST in ( a mobile ) peace @ WHYMCA 05-21-2011
REST in ( a mobile ) peace @ WHYMCA 05-21-2011REST in ( a mobile ) peace @ WHYMCA 05-21-2011
REST in ( a mobile ) peace @ WHYMCA 05-21-2011
 
Best Practices for Architecting a Pragmatic Web API.
Best Practices for Architecting a Pragmatic Web API.Best Practices for Architecting a Pragmatic Web API.
Best Practices for Architecting a Pragmatic Web API.
 
ASP.NET Mvc 4 web api
ASP.NET Mvc 4 web apiASP.NET Mvc 4 web api
ASP.NET Mvc 4 web api
 
Building RESTful applications using Spring MVC
Building RESTful applications using Spring MVCBuilding RESTful applications using Spring MVC
Building RESTful applications using Spring MVC
 
Creating Great REST and gRPC API Experiences (in Swift)
Creating Great REST and gRPC API Experiences (in Swift)Creating Great REST and gRPC API Experiences (in Swift)
Creating Great REST and gRPC API Experiences (in Swift)
 
Resource-Oriented Web Services
Resource-Oriented Web ServicesResource-Oriented Web Services
Resource-Oriented Web Services
 
RESTful SOA - 中科院暑期讲座
RESTful SOA - 中科院暑期讲座RESTful SOA - 中科院暑期讲座
RESTful SOA - 中科院暑期讲座
 
Designing CakePHP plugins for consuming APIs
Designing CakePHP plugins for consuming APIsDesigning CakePHP plugins for consuming APIs
Designing CakePHP plugins for consuming APIs
 
Http pipeline
Http pipelineHttp pipeline
Http pipeline
 
Http pipeline
Http pipelineHttp pipeline
Http pipeline
 
Day02 a pi.
Day02   a pi.Day02   a pi.
Day02 a pi.
 
Bt0083 server side programing
Bt0083 server side programing Bt0083 server side programing
Bt0083 server side programing
 
Boost Your Content Strategy for REST APIs with Gururaj BS
Boost Your Content Strategy for REST APIs with Gururaj BSBoost Your Content Strategy for REST APIs with Gururaj BS
Boost Your Content Strategy for REST APIs with Gururaj BS
 
SOAP vs REST
SOAP vs RESTSOAP vs REST
SOAP vs REST
 
Super simple introduction to REST-APIs (2nd version)
Super simple introduction to REST-APIs (2nd version)Super simple introduction to REST-APIs (2nd version)
Super simple introduction to REST-APIs (2nd version)
 

Kürzlich hochgeladen

Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
vu2urc
 

Kürzlich hochgeladen (20)

Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 

Indic threads delhi13-rest-anirudh

  • 1. Modelling RESTful applications – Why should I not use verbs in REST url Anirudh Bhatnagar Xebia India IT Architects Pvt Ltd
  • 2. REST Representational state transfer ?? Specification ??? Guidelines ??? Architecture style??
  • 3. Its Just a STYLE! The REST architectural style was developed by W3C Technical Architecture Group (TAG) in parallel with HTTP/1.1, based on the existing design of HTTP/1.0.
  • 4. Roy Fielding’s paper on REST architectural style Architectural Styles and the Design of Network-based Software Architectures DISSERTATION submitted in partial satisfaction of the requirements for the degree of DOCTOR OF PHILOSOPHY in Information and Computer Science by Roy Thomas Fielding 2000
  • 6. HTTP Specification GET ../foods/1 would get you the food with id 1. PUT ../foods/2 would update the food with id 2. POST ../foods will add a new food. DELETE ../foods/1 will delete the food resource with id 1.
  • 7. But what about other verbs??? --- approve -- reject -- cancel -- search -- increase -- decrease ….. …..
  • 8. Can I just put them in my URL?? what would go wrong? Lets see a video http://www.youtube.com/watch?v=65ilZ8esAUs
  • 9. Improper handling of method and no safeguard
  • 11. How do we solve this? HTTP Specifications
  • 12. 1. Safe and Unsafe Methods excerpt from w3 HTTP Specification… …..GET and HEAD methods SHOULD NOT have the significance of taking an action other than retrieval. These methods ought to be considered "safe". This allows user agents to represent other methods, such as POST, PUT and DELETE, in a special way, so that the user is made aware of the fact that a possibly unsafe action is being requested.... GET and HEAD should have no side-effects : They should not change the state. Clearly we can not use GET in our API..
  • 13. 2.Idempotency An idempotent HTTP method can be called many times without different outcomes. a = 4 ->idempotent a++ -> non idempotent ...Methods can also have the property of "idempotence" in that (aside from error or expiration issues) the side-effects of N > 0 identical requests is the same as for a single request. The methods GET, HEAD, PUT and DELETE share this property… ..POST is non-idempotent..
  • 14. Fault Tolerant - Idempotent Methods - if request timed out - can you safely retry? - no need to worry if idempotent
  • 15. Browser Support Confirm Form submission On refresh of Unsafe Method (POST form)
  • 16. Caching Non-safe and non-idempotent methods will never be cached by any middleware proxies. Safe Methods like GET and HEAD are candidate for caching.
  • 17. caching with GET Every GET call is a candidate for caching.. If you have method : HTTP/1.1 GET …./users/1/update This might not actually update and return you the cached result.
  • 18. Bad Urls hamper caching! HTTP 1.1 GET http://myTestApp/page4.do?dau22. oid=5199&UserCtxParam=0&GroupCtxParam=0&dctx 1=25&ctx1=US&crc=712082047
  • 22. Gateway Cache : Reverse Proxy
  • 23. Benefits of HTTP Caching - Server side caching is expensive.. - Reduce latency - Reduce network traffic -CDNs can leverage proxy caches.
  • 24. Leverage Caching effectively With great power comes great responsibility... How to control caching effectively? Invalidations? Cache expiry? Stale cache? Volatile data?
  • 25. - expires - cache control -Etags -last modified - validation headers HTTP headers
  • 26. Expires Header ● HTTP 1.0 So, if we made an API call to retrieve data ……….. GET /users/1 The response header would be: HTTP/1.1 200 OK Content-Type: application/xml Expires: Tue, 25 Aug 2013 16:00 GMT ----- <user id="1">...</users>
  • 27. JAX-RS support for expires.. @Path("{id}") @GET @Produces(MediaType.APPLICATION_XML) public Response getUserXML(@PathParam("id") Long id){ User user = userDB.get(id); ResponseBuilder builder = Response.ok(user,MediaType. APPLICATION_XML); //Putting expires header for HTTP browser caching. Calendar cal = Calendar.getInstance(); cal.set(2013,7,25,16,0); builder.expires(cal.getTime()); return builder.build(); }
  • 28. HTTP 1.1 support CDNs, proxy caches and revalidations there was a need for more enhanced headers with richer set of features, having more explicit controls.
  • 29. Cache-Control Cache-Control has a variable set of comma-delimited directives that define who,how and for how long it can be cached. Lets explore few of them: -private/public : these are accessibility directives, private means a browser can cache the object but the proxies or CDNs can not and public makes it cachable by all. -no-cache,no-store,max-age are few others where name tells the story.
  • 30. JAX-RS support for Cache-Control @Path("{id}") @GET @Produces(MediaType.APPLICATION_XML) public Response getUserXMLwithCacheControl(@PathParam("id") Long id){ User user = userDB.get(id); CacheControl cc = new CacheControl(); cc.setMaxAge(300); cc.setNoStore(true); cc.setPrivate(true); ResponseBuilder builder = Response.ok(user,MediaType. APPLICATION_XML); builder.cacheControl(cc); return builder.build(); }
  • 31. Validation Headers and Conditional GETs When cache is stale, client can ask server if cache still valid To be able to revalidate client needs additional headers beyond Cache-Control from a server response •Last-Modified - a date when the resource was last modified •ETag - a unique hash-like key that identifies a version of the resource Client should cache these headers along with response body To revalidate client sends conditional GETs using values of these header tags.
  • 32. Last-Modified and If-Modified-Since Server sends in response header HTTP/1.1 200 OK .... Cache-Control: max-age=1000 Last-Modified: Mon, 19 aug 2013 16:00 IST Client revalidates using conditional GET GET /users/23 HTTP/1.1 If-Modified-Since: Mon, 19 aug 2013 16:00 IST in case it is modified after this date; a response code 200 (OK) with current value of resource will be sent. And if the data is not modified a response code of “304″
  • 33. Etag and If-None-Match ● an MD5 hash value. ● generated from resource is sent by server in response. ● client caches it and uses this to revalidate using If- None-Match tag in request header. GET /users/23 HTTP/1.1 If-None-Match: "23432423423454654667444" Server verifies the hash, if it matches sends “304” else sends current value with response code 200 and resets the etag.
  • 34. JAX-RS support Validation JAX-RS also provided one injectable helper class Request, which has methods like… .... ResponseBuilder evalutatePostConditions(EntityTag eTag); ResponseBuilder evaluatePreConditions(Date isLastModified); ..... And... JAX-RS provides us with javax.ws.rs.core.EntityTag for the same The values sent by client (which they have cached) are compared with latest values at the server.
  • 35. JAX-RS and Validation @Path("{id}") @GET @Produces(MediaType.APPLICATION_XML) public Response getUserWithEtagSupport(@PathParam("id") Long id, @Context Request request){ User user = userDB.get(id); //generating Etag out of hashCode of user EntityTag tag = new EntityTag(Integer.toString(user.hashCode())); CacheControl cc = new CacheControl(); cc.setMaxAge(1000); ResponseBuilder builder = request.evaluatePreconditions(tag); if(builder!=null){ //means the preconditions have been met and the cache is valid //we just need to reset the cachecontrol max age (optional) builder.cacheControl(cc); return builder.build(); } //preconditions are not met and the cache is invalid //need to send new value with response code 200 (OK) builder = Response.ok(user,MediaType.APPLICATION_XML); //reset cache control and eTag (mandatory) builder.cacheControl(cc); builder.tag(tag); return builder.build(); }
  • 36. HTTP PURGE HTTP has an unofficial PURGE method that is used for purging caches. When an API receives a call with an unsafe method on a resource, it should fire a PURGE request on that resource so that the reverse proxy knows that the cached resource should be expired. We dont need to perform explicit revalidations in this case.
  • 37. GET /article/1234 HTTP/1.1 - - The resource is not cached yet - Send request to the API - Store response in cache and return GET /article/1234 HTTP/1.1 - The resource is cached - Return response from cache PUT /article/1234 HTTP/1.1 - Unsafe method, send to API PURGE /article/1234 HTTP/1.1 - API sends PURGE method to the cache - The resources is removed from the cache GET /article/1234 HTTP/1.1 - The resource is not cached yet - Send request to the API - - Store response in cache and return
  • 38. Let’s complete our “pitaji ki patloon” problem
  • 39. GET -No side effects- should not change the state -idempotent HTTP1.1 GET /pitaji/patloon/12/length? method=decrease&size=1b Caching will not work!
  • 40. PUT - idempotent - HTTP1.1 PUT /pitaji/patloon/12/length {“decrease” : “1 bilaank” } This will result in disaster, as the browser can call the PUT multiple times, in case of timeouts/network latency etc.
  • 41. DELETE HTTP/1.1 DELETE /pitaji/patloon/12/length {“decrease” : “1 bilaank” } this API does not make sense, it will confuse the client! moreover again performing unsafe operation with safe method.
  • 42. POST Unsafe method HTTP1.1 POST /pitaji/patloon/length {“decrease” : “1 bilaank” }
  • 43. Use Case An example of a social Site : 1.) Add friend 2.) Remove Friend 3.) Approve Friend Request 4.) Reject Friend Request 5.) Make a new account 6.) Delete account. 7.) Search Users. …...
  • 44. Approach 1 : userFriendMapping table @Entity @Table(name = "userFriendMapping") public class UserFriendMapping { private long id; private User user; private User friend; private String status; @Id @GeneratedValue(strategy = IDENTITY) @Column(name = "id", unique = true, nullable = false) public long getId() { return id; } @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name="userId") public User getUser() { ……
  • 45. Add and Approve friend request 1. Add a friend (send friendRequest) POST ../userfriendmapping {userId: 1, friendId : 2, status:pending} 2. Approve friend Request POST ../userfriendmapping {userId: 1, friendId : 2, status:approved}
  • 46. reject friend, get pending requests 3. Reject friend Request DELETE ../userfriendmapping/1 4.Get pending friends GET ../userfriendmapping/users/1?status=pending 5. Delete existing Friend DELETE ../userfriendmapping/2
  • 47. More extensions List all friend requests List all pending friends.. List all friends.. List all rejected requests.. Do not allow a user to resend the friend request.. BlackList Users Ignore a friend request
  • 48. Problems Single domain catering to responsibilty of two states : 1.) FriendRequest 2.) UserFriendRelation Increases complexity, more effort, tightly coupled, separation of concern?
  • 49. 1. Separate domains give more flexibility and ease for extensibility. 2. As we have states and resources as domains, making RESTful urls is easy. 3. Querying is easy. example : - to find friends need 2 calls to DB, or put a UNION
  • 50. API : Find all myfriends @Override public List<User> findFriends(Long userId,String status) { List<UserFriendMapping> allFriends = userFriendMappingPersistence.getAllFriends(userId,status); List<UserFriendMapping> friendsWhoAddedMe = userFriendMappingPersistence.getByFriendId(userId,status); List<User> friends = new ArrayList<User>(); for (UserFriendMapping userFriendMapping : allFriends) { friends.add(userFriendMapping.getFriend()); } for (UserFriendMapping userFriendMapping : friendsWhoAddedMe) { friends.add(userFriendMapping.getUser()); } return friends; }
  • 51. Resource Oriented Architecture A resource-oriented architecture is the structural design supporting the internetworking of resources. A resource, in this context, is any entity that can be identified and assigned a uniform resource identifier (URI). any states , verbs which acts as a resource can be made model like FriendRequest or BookOrder.
  • 52. Alternate Approach Model driven Architecture and Resource Driven Architecture. provides intuitive way of designing APIs in RESTful manner. Add 2 domain classes ● FriendRequest ● UserFriend or FriendShip or Relation The RESTful APIs : 1. add Friend POST ../users/1/friendrequests?friendid=2 @Path("/users/{id}/friendrequests") @POST public String createFriendRequest(@PathParam("id") Long userId, @QueryParam(value="friendid")Long friendId){ …...
  • 53. Approve and Reject friendRequest 2. Approve: POST .. /userfriends/friendrequests/22 -> creating a new friend from friendRequest with id22 3.Reject DELETE ../friendrequests/22 4.Remove a friend DELETE ../userfriends/3 5. GET on ..users/2/friendrequests will give all pending friend requests 6. GET on ..users/1/userfriends/ will give all friends of user
  • 54. Search Users Search is GET USE GET with QUERY PARAMS HTTP1.1 GET ../users?firstname=abc&age=25
  • 55. Versioning APIs in REST Add version in URL GET ../version/users/1 Example twitter: GET https://api.twitter.com/1/statuses/user_timeline. json
  • 56. Use HTTP Redirection Response codes for versioning ● 301 Moved permanently - point to new URL ● 302 Found indicating that the requested resource temporarily is located at another location, while requested URI may still supported.
  • 57. Model Driven Design produces RESTful Urls RAD tools which generate code like Spring ROO or Rails/Grails. These are made on top of domains and models. Take business domains from framework to other. More extensibility and portability. and of course they provide RESTful URLs.
  • 58. Finally, Is it Just to avoid verbs and have better Urls? The approach should be the other way : Better modelling and better design gives way to better URLs and cleaner approach.
  • 59. Conclusion REST is no specification, its a style which adheres to HTTP specification. So, in order to make full use of HTTP and REST --- Better modelling will automatically avoid verbs. --- Take care of idempotent and safe/unsafe methods. --- Use cache-control headers to make best use of caching.
  • 60. Thanks!!! Questions and Feedback. twitter : anirudh_bh blog : http://anirudhbhatnagar.com mail : anirudh.bh@gmail.com github: https://github.com/anirudh83