REST
Thinking RESTfully
Stelios Gkorilas

JHUG 17 Dec 2011
Contents
1.  Types of services
2.  What is REST?
3.  Web services and the REST way
4.  Example: S3
5.  Security
6.  Jersey/JAX-RS
7.  CTR

JHUG 17 Dec 2011
Distributed services
•  The everlasting need to (re-)use logic as black box
•  Even across different machines and platforms
•  Gave birth to distributed objects and several protocols for

remoting (e.g. CORBA, DCOM, RMI)
•  Web services prevailed because the web is ubiquitous and
scalable
•  Web services provide the means to integrate disparate systems
and expose reusable business functions over HTTP
•  Mostly SOAP services up to now in RPC style
•  Some serve HTML, JSON, plain text, or binary documents, but most

use XML
•  WSDL and the WS-* specs
•  HTTP is used as the transport service not the application protocol
JHUG 17 Dec 2011
Service styles
•  RPC services
•  Message oriented services
•  Resource oriented services

JHUG 17 Dec 2011
RPC style
•  The request message identifies the procedure to be

executed, and the fixed set of parameters that map
directly to the parameters of the remote procedure

•  XML-RPC and later the WS-* stack
•  Procedure arguments are tightly coupled messages
•  Usually flat APIs
•  Communication through proxies that have to be

regenerated in case of change
•  e.g. JAX-WS

JHUG 17 Dec 2011
Message oriented
•  Services that have Message APIs (a.k.a. Document APIs)

receive one or more self-descriptive message types at a
given URI
•  They are not coupled to procedure names hence they can
easier change
•  They can constitute commands, events or just documents
•  They contain values that identify their type and/or
handling

JHUG 17 Dec 2011
making a Google search the SOAP way
POST search/beta2
HTTP/1.1 Host: api.google.com
Content-Type: application/soap+xml
SOAPAction: urn:GoogleSearchAction
<?xml version="1.0" encoding="UTF-8"?>	
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">	
	<soap:Body>	
	
	<gs:doGoogleSearch xmlns:gs="urn:GoogleSearch">	
	
	
	<key>00000000000000000000000000000000</key>	
	
	
	<q>jhug user group</q>	
	
	
	<start>0</start>	
	
	
	<maxResults>10</maxResults>	
	
	
	<filter>true</filter>	
	
	
	<restrict />	
	
	
	<safeSearch>false</safeSearch>	
	
	
	<lr />	
	
	
	<ie>latin1</ie>	
	
	
	<oe>latin1</oe>	
	
	</gs:doGoogleSearch>	
	</soap:Body>	
</soap:Envelope>
JHUG 17 Dec 2011
Resource oriented
•  It’s like object oriented – Resources are objects
•  Resource is the design of data; what we perceive data to

be; it is what we think others might find interesting about
our data
•  Everything can be a resource
•  Resources are accessed through a Uniform Interface
•  Resources are interconnected
•  Resources have multiple representations
•  Communication is stateless

JHUG 17 Dec 2011
Resources
•  Everything can be a resource (like everything can be an object)
•  A procedure, instances of domain data, files
•  Examples:
•  A list of search results about ‘Mullus barbatus’
•  An article
•  The jhug meeting on Dec 17
•  The latest jhug meeting
•  The software version release 1.1.2.3
•  The latest release
•  The list of unresolved issues of type ‘bug’ and component ‘Launcher’
•  Every resource should have a unique identifier, a URI
•  http://www.jhug.gr/meetings/meet-up/17-dec-2011
JHUG 17 Dec 2011
What is REST?
•  Architectural style
•  Architectural constraints
•  A way to evaluate architectures
•  Design principles
•  Key properties of a simple (not simplistic) application
•  The null style: Start with system needs as a whole,

without constraints, and then incrementally identifies and
applies constraints to elements of the system in order to
differentiate the design space
•  Representational State Transfer
•  You request a resource and a representation of its state is

returned

JHUG 17 Dec 2011
HTTP Example
Request
GET /meetups/latest HTTP/1.1
Host: www.jhug.gr
Accept: application/xml
Response
HTTP/1.1. 200 OK
Date: Sat, 17 Dec 2011 13:45:34 GMT
Server: Apache/1.3.6
Content-Type: application/xml; charset=UTF-8
<?xml version="1.0" encoding="UTF-8"?>
<meetup xmlns="...">
<occurred date=".."/>
<presentations>
...
</presentations>
<next uri=".."/>
</meetup>
JHUG 17 Dec 2011
HTTP, URIs & XML define the web
•  Operations: GET, PUT, DELETE, POST
•  And the less known HEAD, OPTIONS
•  Headers
•  content-type
•  Accept-Language
•  Media types
•  text/plain
•  text/xml
•  application/atom+xml
•  Response codes
•  2xx Success
•  3xx Redirect
•  4xx Client Error
•  5xx Server Error
•  URIs and URLs define the web
•  XML: content attributes and structure

An Application protocol for service logic
JHUG 17 Dec 2011
REST constraints (Fielding dissertation)
•  Client/server
•  Uniform Interface
•  Layered System
•  Stateless
•  Cache
•  Code on Demand

JHUG 17 Dec 2011
Resources and the uniform interface
•  HTTP standard methods: GET, PUT, POST, DELETE
•  HEAD and GET should not modify anything
•  Idempotent: PUT DELETE GET HEAD
•  HTTP is the application protocol defining service

behaviors
•  GET /meetups/latest instead of getLatestMeetup()
•  RPC verbs become REST nouns
•  GET the more recent state of the resource
•  PUT/POST a representation that alters the state of the

resource

JHUG 17 Dec 2011
Representations
•  Representations have media types
•  Multiple formats for different needs
•  Content negotiation
•  Accept: application/json (request)
•  Content-Type: application/json (response)

•  URI
•  /meetups/latest.json

JHUG 17 Dec 2011
Addressability
•  Representations should be addressable
•  Increase the surface of the service
•  Client can enter the application where convenient
•  A URI can never point to more than one resource

JHUG 17 Dec 2011
Interconnected Resources
• 
• 
• 
• 
• 
• 

Resources are not just data but hypermedia
Hypermedia as the engine of state
Representations contain links to other resources
A representation may contain links ot other states of the resource
Paths a client can follow
Makes clients more resilient to changes

<?xml version="1.0" encoding="UTF-8"?>
<meetup xmlns="...">
<occurred date="17-12-2011"/>
<presentations>
<presentation ref="/presentations/title/disruptor"/>
<presentation ref="/presentations/title/rest"/>
<presentation ref="/presentations/title/sw-dev-practices"/>
</presentations>
<next ref="/meetings/date/17-01-2011"/>
</meetup>

JHUG 17 Dec 2011
Stateless
•  HTTP is stateless
•  All information needed for processing part of the request
•  No session on the server
•  No session ids exchanged (jsessionId, phpSessionId, etc. )
•  Application state belongs to the client
•  Resource state alone belongs to the server
•  Simplifies server and client logic, allows scalability

e.g. http://www.google.gr/search?q=jhug&start=20
JHUG 17 Dec 2011
Cacheability
•  Conditional queries
•  Cacheable when last-modified and etag are used (response
headers)
•  If- Modified-Since and If-None-Match (request headers)
•  304 Response Code when not modified with no entity body
•  Cache proxies and other commodity caching technologies

JHUG 17 Dec 2011
REST Patterns
•  Paths for hierarchy
•  jhug/discussions/april
•  Post for not owned URIs
•  Container items
•  Jhug/discussions/1342
•  PUT for URIs defined by the client
•  Jhug/presentations/rest
•  Semicolon (;) or comma (,) for name/value or matrix

values
•  jhug/presentations/author,gkorilas/rest

•  Query string for algorithmic resources
•  Jhug/search?q=“rest”
JHUG 17 Dec 2011
Think Resource Oriented
•  Define the data set
•  Expose data as resources
•  Assign URIs to resources
•  Decide the UI commands accepted
•  Decide the representations accepted
•  Decide the representations served
•  Add hypermedia links between them

JHUG 17 Dec 2011
REST +
•  Serve representations suitable for many clients
•  The uniform interface allows all http clients to easily consume a
suitable representation
•  Content negotiation can allow a single URL to serve content to a
browser, a JS client that is interested in JSON or a mobile phone client
interested in an XML representation
•  Cacheable by commodity technologies
•  Scalable
•  Fail over
•  Clients:
•  Browser friendly
•  Easy support by many languages
•  Bookmarkable
•  Data formats
•  It is the natural way of the web!
JHUG 17 Dec 2011
REST Security standards

JHUG 17 Dec 2011
The Amazon S3 Service
•  S3 “buckets” and S3 “objects”
•  Bucket can only contain objects
•  Bucket names are unique in S3
•  Object has a name (key) and content (value)
•  Object has a reference to the parent bucket
•  Object has metadata key-value pairs; can also be http headers like
content-type or content-disposition
•  Three types of resources
•  List of your buckets (https://s3.amazonaws.com/)
•  A particular bucket (https://s3.amazonaws.com/{name-of-bucket}/). There
can be up to 100 resources of this type.
•  A particular S3 object inside a bucket (https://s3.amazonaws.com/
{name-of- bucket}/{name-of-object}
JHUG 17 Dec 2011
S3 resources and methods
GET

HEAD

PUT

DELETE

(/)

List your
buckets

-

-

-

/{bucket}

List objects of
bucket

-

Create the
bucket

Delete the
bucket

/{bucket}/
{object}

Object’s value Object’s
and metadata metadata

Set the
object’s value
and metadata

Delete the
object

JHUG 17 Dec 2011
S3 Security
•  Message digest of the canonical string of the request with a

secret key (amazon knows it too)
•  {http method}{content-type}{date}{amazon headers}{path}

•  Add it to http Authorization: header
•  Add it to query string together with expires date to make

bookmarkable (https://s3.amazonaws.com/stelinio/rest.pdf# ?
Signature=J%2Qu6krT3j0zaaFXjsLbowdfzExQ%3D #
&Expires=1162156788&AWSAccessKeyId=0F9RBCLB5274NK
TJ4DA3")
•  Access policies
•  Private, public-read, public-write, authenticated read
JHUG 17 Dec 2011
HTTP security, OAuth
•  http basic
•  http digest
•  http client certificate
•  OAuth
•  Delegated user authentication solution - Valet key principle
•  Client, server, resource owner (OAuth love triangle)
•  client credentials, temporary credentials, and token credentials

JHUG 17 Dec 2011
Java REST Services
•  Java EE 6 specification: JAX-RS
•  Jersey: Reference implementation of JSR 311
•  Available as standalone and enterprise

JHUG 17 Dec 2011
Standalone example setup
<servlet>
<servlet-name>jersey</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>eu.ema.eudract.rest</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-server</artifactId>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-json</artifactId>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-atom</artifactId>
</dependency>
JHUG 17 Dec 2011
JAX-RS Resources
Annotate POJOs
@Path("/meetups")	
@Singleton()	
public class MeetUpsResource {	
		
	@GET()	
	@Path("/latest")	
	@Produces("text/plain")	
	public String getLatestMeetUp() {	
	
	return getDataService().getLatestMeetUp().toString();	
	}	
	
	@GET()	
	@Path("/next")	
	@Produces("text/plain")	
	public String getNextMeetUp() {	
	
	return getDataService().getNextMeetUp().toString();	
	}	
		
	@GET()	
	@Produces(MediaType.APPLICATION_JSON)	
	public MeetUps getAllMeetUps() {	
	
	return getDataService().getAllMeetUps();	
	}	
}	
	
	

JHUG 17 Dec 2011
Methods & Paths
•  @javax.ws.rs.GET
•  @javax.ws.rs.PUT
•  @javax.ws.rs.POST
•  @javax.ws.rs.DELETE
•  @javax.ws.rs.HEAD
•  Paths: Most specific match wins

JHUG 17 Dec 2011
JAX-RS Injection
•  @javax.ws.rs.PathParam
•  values from URI template parameters
•  @javax.ws.rs.MatrixParam
•  URI’s matrix parameters.
•  @javax.ws.rs.QueryParam
•  Query String parameters
•  @javax.ws.rs.FormParam
•  form-encoded key-value pairs
•  @javax.ws.rs.HeaderParam
•  HTTP request headers
•  @javax.ws.rs.CookieParam
•  HTTP cookies set by the client
•  @javax.ws.rs.core.Context
•  All-purpose injection annotation. It allows you to inject various helper and
informational objects that are provided by the JAX-RS API e.g.
•  @Context final HttpServletRequest request	
•  @Context final SecurityContext secCtx
JHUG 17 Dec 2011
JAX-RS Content Handling
•  MIME types
•  Automatic content negotiation
•  Automatic content serialization
•  Jaxb representation → XML, JSON
•  Byte[] → Binary or */*
•  String → text/*
•  MultiValuedMap<String, String> → application/x-www-formurlencoded
•  StreamingOutput
•  @Providers

JHUG 17 Dec 2011
JAX-RS Error Handling
•  HTTP Error Codes
•  WebApplicationException
•  ExceptionMapper

throw new WebApplicationException(new RuntimeException 	(“Timeframe
not an Integer"),	
	Response.Status.NOT_ACCEPTABLE);	
	
	
	
@Provider 	
public class EntityNotFoundMapper implements
ExceptionMapper<EntityNotFoundException>	
{	
	public Response toResponse(EntityNotFoundException e){	
	return Response.status(Response.Status.NOT_FOUND).build(); 	
	}	
}	
JHUG 17 Dec 2011
Enforcing security
•  @RolesAllowed({“admin”,”client-admin”})
•  @PermitAll
•  Any authenticated user
•  @SecurityContext
public interface SecurityContext	
{	
public static final String BASIC_AUTH = "BASIC";	
	
public static final String CLIENT_CERT_AUTH = "CLIENT_CERT";	
	
public static final String DIGEST_AUTH = "DIGEST";	
	
public static final String FORM_AUTH = "FORM";	
	
public Principal getUserPrincipal();	
	
public boolean isUserInRole(String role);	
	
public boolean isSecure();	
	
public String getAuthenticationScheme();	
}

JHUG 17 Dec 2011
Example
@Path(”/presentations")	
@Singleton()	
public class PresentationsResource {	
		
	@PUT()	
	@Path(”/presentation/{name}”)	
	@RolesAllowed(”admin”)	
	public void addPresentation(@PathParam name, InputStream is){	
	
	return getDataService().addPresentation(is);	
	}	
	
	@GET()	
	@Path(”/presentation/{name}")	
	public StreamingOutput getPresentation(@PathParam name) {	
	
		
	
	return new StreamingOutput() {	
	
	
		
	
	
	@Override	
	
	
	public void write(OutputStream output) throws 	
	
	
	IOException {	
	
	
	
	
	stream(	
	
	
	
	getDataService().getPresentation(name)	
	
	
	
	, output	
	
	
	
	);	
	
	
	}	
	
	}	
	
	}	
}	

	

JHUG 17 Dec 2011
CTR
•  Clinical Trials Register
•  (https://www.clinicaltrialsregister.eu/)
•  Rest services
•  Data to other agency html pages
•  Content to the World Health Organization
•  Data to the web application users
•  Rest clients
•  JS code as the client
•  Controller servlet
•  JSP <c:import url=“/trial/2010-022009-16/GB”/>
•  A guy at World Health Organization every Tuesday at 19:00
JHUG 17 Dec 2011
Data consumed by html pages (1/3)
@Path("/trials")	
@Singleton()	
public class TrialsMetaDataResource {	
		
	@GET()	
	@Path("/count/public")	
	@Produces("text/plain")	
	public String countPublicTrials() {	
	
	return getDataService().countPublicClinicalTrials().toString();	
	}	
	
	@GET()	
	@Path("/count/public/under18")	
	@Produces("text/plain")	
	public String countUnder18PublicTrials() {	
	
	return getDataService().countPublicClinicalTrialsWithSubjectsUnder18().toString();	
	}	
		
	@GET()	
	@Path("/landing")	
	@Produces(MediaType.APPLICATION_JSON)	
	public LandingPageMetadata landingPageMetadata() {	
	
	Integer total = getDataService().countPublicClinicalTrials();	
	
	Integer under18 = getDataService().countPublicClinicalTrialsWithSubjectsUnder18();	
	
	
	}	
…	
}	
		

	LandingPageMetadata metadata = new LandingPageMetadata(total, under18);	
	return metadata;	

JHUG 17 Dec 2011
Data consumed by html pages (2/3)
	
@XmlRootElement()	
@XmlAccessorType(value = XmlAccessType.PROPERTY)	
public class LandingPageMetadata implements Serializable {	
	
	private static final long serialVersionUID = -8784258618018188874L;	
	
	private Integer numberOfPublicClinicalTrials;	
	private Integer numberOfPublicClinicalTrialsWithSubjectsUnder18;	
	
	public LandingPageMetadata() {…}	
	
	public LandingPageMetadata(Integer numberOfPublicClinicalTrials,	
	
	
	Integer numberOfPublicClinicalTrialsWithSubjectsUnder18) {…}	
	@XmlElement(name="total")	
	public Integer getNumberOfPublicClinicalTrials() {…}	
	public void setNumberOfPublicClinicalTrials(Integer numberOfPublicClinicalTrials) {…}	
	
	
	@XmlElement(name="under18")	
	public Integer getNumberOfPublicClinicalTrialsWithSubjectsUnder18() {…}	
	
	public void setNumberOfPublicClinicalTrialsWithSubjectsUnder18(Integer
numberOfPublicClinicalTrialsWithSubjectsUnder18) {…}	
	
		
	@Override	
	public String toString() {…}
		
}	

JHUG 17 Dec 2011
Data consumed by html pages (3/3)
function showNumbers() {	
	$.getJSON('api/trials/landing', function(data) {	
	
	var total = data['total'];	
	
	var under18 = data['under18'];	
	
	$("#total").text(total);	
	
	$("#under18").text(under18);	
	});	
}

JHUG 17 Dec 2011
Streaming Content (1/2)
@Path("/download")	
public class DownloadResource {	
		
	@GET	
	@Path("/summary")	
	public Response downloadSummaryTrials(@Context final HttpServletRequest request, @QueryParam
	
	("mode") final String mode) {	
		
	return Response.ok(new SummaryStreamingOutput(request, mode),MediaType.APPLICATION_OCTET_STREAM)	
	
	.header("content-disposition","attachment; filename = trials-summary.txt").build();	
	}	
		
	@GET	
	@Path("/full")	
	public Response downloadFullTrials(@Context final HttpServletRequest request, @QueryParam
	
	("mode") final String mode) {	
		
	return Response.ok(new FullStreamingOutput(request, mode),MediaType.APPLICATION_OCTET_STREAM)	
	
	.header("content-disposition","attachment; filename = trials-full.txt").build();	
	}	
		
	@GET	
	@Path("/trial/{eudractnumber}/{nca}")	
	public Response downloadFullCta(@Context final HttpServletRequest req, @PathParam
	
	("eudractnumber") String eudractnumber, @PathParam("nca") String nca) {	
		
	return Response.ok(new CtaStreamingOutput(req, eudractnumber, nca),MediaType.APPLICATION_OCTET_STREAM)	
	
	.header("content-disposition","attachment; filename = trial.txt").build();	
	}	
}

JHUG 17 Dec 2011
Streaming Content (2/2)
public class CtaStreamingOutput implements StreamingOutput	
{	
	public CtaStreamingOutput(HttpServletRequest
	
	
	request, String euNumber, String nca) {…}	

}

		
	public void write(OutputStream output) throws
	
	
	IOException {	
	
	TextSerializer ser = new TextSerializer();	
	
	ser.setOutputStream(output);	
	
	CtaIdentification pubCta = mapper.map	
	
	(eudractNumber, nca);	
	
	ser.serializeCtaFull(pubCta);	
	}	

JHUG 17 Dec 2011
RSS 2.0 instead of built in Atom (1/2)
	
@GET	
@Path("/bydates”)	
@Produces("application/rss+xml")	
public SyndFeed getFeed(@Context final HttpServletRequest request) {	
	String feedType = "rss_2.0”;	
	SyndFeed feed = new SyndFeedImpl();	
	feed.setFeedType(feedType);	
	String url = request.getRequestURL().toString().replaceFirst("/rest/
	
	feed/bydates", ”/search") + "?" + request.getQueryString();	
	feed.setLink(url);	
	feed.setTitle("EU Clinical Trials Register RSS Feed");	
	feed.setDescription("This provides a regular feed of new or updated
	
	clinical trial information published on the EU
	
	Clinical Trial Register and matching the search
	
	subscribed to.");	
		
	List<CtrDocument> docs = search(request);	
	
	for(CtrDocument doc: docs){	
	
	SyndEntry entry = buildEntry(doc, entryBasicUrl, countryUrl);	
	
	feed.getEntries().add(entry);	
	}	
	LOG.info("Generated RSS feed {}", feed.getLink());	
	return feed;	
}
JHUG 17 Dec 2011
RSS 2.0 instead of built in Atom (2/2)
@Provider	
@Produces("application/rss+xml")	
@Consumes("application/rss+xml")	
public class RomeRssSupport implements MessageBodyWriter<Object>{	
		
public boolean isWriteable(Class<?> type, Type genericType,	
	
	Annotation[] annotations, MediaType mediaType) {	
	return (SyndFeed.class.isAssignableFrom(type));	
}	
public long getSize(Object t, Class<?> type, Type genericType,	
	
	Annotation[] annotations, MediaType mediaType) {	
	return -1;	
}	

}

public void writeTo(Object feedOrEntry, Class<?> type, Type genericType,	
	
	Annotation[] annotations, MediaType mediaType,	
	
	MultivaluedMap<String, Object> httpHeaders, OutputStream outputStream)	
	
	throws IOException {	
	if (feedOrEntry instanceof SyndFeed) {	
	
	SyndFeed feed = (SyndFeed)feedOrEntry;	
	
	SyndFeedOutput output = new SyndFeedOutput();	
	
	doc = output.outputW3CDom(feed);	
	
	Source source = new DOMSource(doc);	
	
	Result result = new StreamResult(outputStream);	
	
	TransformerFactory factory = TransformerFactory.newInstance();	
	
	Transformer transformer = factory.newTransformer();	
	
	transformer.transform(source, result);	
	
} 	
}	

JHUG 17 Dec 2011
Resources
•  Restful Web Services - Leonard Richardson and Sam
Ruby
•  Service Design Patterns - Robert Daigneau
•  Restful Java - Bill Burke
•  www.amazon.com
•  http://icondrawer.com
•  http://www.iconeden.com
•  http://www.iconshock.com

JHUG 17 Dec 2011

Thinking restfully

  • 1.
  • 2.
    Contents 1.  Types ofservices 2.  What is REST? 3.  Web services and the REST way 4.  Example: S3 5.  Security 6.  Jersey/JAX-RS 7.  CTR JHUG 17 Dec 2011
  • 3.
    Distributed services •  Theeverlasting need to (re-)use logic as black box •  Even across different machines and platforms •  Gave birth to distributed objects and several protocols for remoting (e.g. CORBA, DCOM, RMI) •  Web services prevailed because the web is ubiquitous and scalable •  Web services provide the means to integrate disparate systems and expose reusable business functions over HTTP •  Mostly SOAP services up to now in RPC style •  Some serve HTML, JSON, plain text, or binary documents, but most use XML •  WSDL and the WS-* specs •  HTTP is used as the transport service not the application protocol JHUG 17 Dec 2011
  • 4.
    Service styles •  RPCservices •  Message oriented services •  Resource oriented services JHUG 17 Dec 2011
  • 5.
    RPC style •  Therequest message identifies the procedure to be executed, and the fixed set of parameters that map directly to the parameters of the remote procedure •  XML-RPC and later the WS-* stack •  Procedure arguments are tightly coupled messages •  Usually flat APIs •  Communication through proxies that have to be regenerated in case of change •  e.g. JAX-WS JHUG 17 Dec 2011
  • 6.
    Message oriented •  Servicesthat have Message APIs (a.k.a. Document APIs) receive one or more self-descriptive message types at a given URI •  They are not coupled to procedure names hence they can easier change •  They can constitute commands, events or just documents •  They contain values that identify their type and/or handling JHUG 17 Dec 2011
  • 7.
    making a Googlesearch the SOAP way POST search/beta2 HTTP/1.1 Host: api.google.com Content-Type: application/soap+xml SOAPAction: urn:GoogleSearchAction <?xml version="1.0" encoding="UTF-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Body> <gs:doGoogleSearch xmlns:gs="urn:GoogleSearch"> <key>00000000000000000000000000000000</key> <q>jhug user group</q> <start>0</start> <maxResults>10</maxResults> <filter>true</filter> <restrict /> <safeSearch>false</safeSearch> <lr /> <ie>latin1</ie> <oe>latin1</oe> </gs:doGoogleSearch> </soap:Body> </soap:Envelope> JHUG 17 Dec 2011
  • 8.
    Resource oriented •  It’slike object oriented – Resources are objects •  Resource is the design of data; what we perceive data to be; it is what we think others might find interesting about our data •  Everything can be a resource •  Resources are accessed through a Uniform Interface •  Resources are interconnected •  Resources have multiple representations •  Communication is stateless JHUG 17 Dec 2011
  • 9.
    Resources •  Everything canbe a resource (like everything can be an object) •  A procedure, instances of domain data, files •  Examples: •  A list of search results about ‘Mullus barbatus’ •  An article •  The jhug meeting on Dec 17 •  The latest jhug meeting •  The software version release 1.1.2.3 •  The latest release •  The list of unresolved issues of type ‘bug’ and component ‘Launcher’ •  Every resource should have a unique identifier, a URI •  http://www.jhug.gr/meetings/meet-up/17-dec-2011 JHUG 17 Dec 2011
  • 10.
    What is REST? • Architectural style •  Architectural constraints •  A way to evaluate architectures •  Design principles •  Key properties of a simple (not simplistic) application •  The null style: Start with system needs as a whole, without constraints, and then incrementally identifies and applies constraints to elements of the system in order to differentiate the design space •  Representational State Transfer •  You request a resource and a representation of its state is returned JHUG 17 Dec 2011
  • 11.
    HTTP Example Request GET /meetups/latestHTTP/1.1 Host: www.jhug.gr Accept: application/xml Response HTTP/1.1. 200 OK Date: Sat, 17 Dec 2011 13:45:34 GMT Server: Apache/1.3.6 Content-Type: application/xml; charset=UTF-8 <?xml version="1.0" encoding="UTF-8"?> <meetup xmlns="..."> <occurred date=".."/> <presentations> ... </presentations> <next uri=".."/> </meetup> JHUG 17 Dec 2011
  • 12.
    HTTP, URIs &XML define the web •  Operations: GET, PUT, DELETE, POST •  And the less known HEAD, OPTIONS •  Headers •  content-type •  Accept-Language •  Media types •  text/plain •  text/xml •  application/atom+xml •  Response codes •  2xx Success •  3xx Redirect •  4xx Client Error •  5xx Server Error •  URIs and URLs define the web •  XML: content attributes and structure An Application protocol for service logic JHUG 17 Dec 2011
  • 13.
    REST constraints (Fieldingdissertation) •  Client/server •  Uniform Interface •  Layered System •  Stateless •  Cache •  Code on Demand JHUG 17 Dec 2011
  • 14.
    Resources and theuniform interface •  HTTP standard methods: GET, PUT, POST, DELETE •  HEAD and GET should not modify anything •  Idempotent: PUT DELETE GET HEAD •  HTTP is the application protocol defining service behaviors •  GET /meetups/latest instead of getLatestMeetup() •  RPC verbs become REST nouns •  GET the more recent state of the resource •  PUT/POST a representation that alters the state of the resource JHUG 17 Dec 2011
  • 15.
    Representations •  Representations havemedia types •  Multiple formats for different needs •  Content negotiation •  Accept: application/json (request) •  Content-Type: application/json (response) •  URI •  /meetups/latest.json JHUG 17 Dec 2011
  • 16.
    Addressability •  Representations shouldbe addressable •  Increase the surface of the service •  Client can enter the application where convenient •  A URI can never point to more than one resource JHUG 17 Dec 2011
  • 17.
    Interconnected Resources •  •  •  •  •  •  Resources arenot just data but hypermedia Hypermedia as the engine of state Representations contain links to other resources A representation may contain links ot other states of the resource Paths a client can follow Makes clients more resilient to changes <?xml version="1.0" encoding="UTF-8"?> <meetup xmlns="..."> <occurred date="17-12-2011"/> <presentations> <presentation ref="/presentations/title/disruptor"/> <presentation ref="/presentations/title/rest"/> <presentation ref="/presentations/title/sw-dev-practices"/> </presentations> <next ref="/meetings/date/17-01-2011"/> </meetup> JHUG 17 Dec 2011
  • 18.
    Stateless •  HTTP isstateless •  All information needed for processing part of the request •  No session on the server •  No session ids exchanged (jsessionId, phpSessionId, etc. ) •  Application state belongs to the client •  Resource state alone belongs to the server •  Simplifies server and client logic, allows scalability e.g. http://www.google.gr/search?q=jhug&start=20 JHUG 17 Dec 2011
  • 19.
    Cacheability •  Conditional queries • Cacheable when last-modified and etag are used (response headers) •  If- Modified-Since and If-None-Match (request headers) •  304 Response Code when not modified with no entity body •  Cache proxies and other commodity caching technologies JHUG 17 Dec 2011
  • 20.
    REST Patterns •  Pathsfor hierarchy •  jhug/discussions/april •  Post for not owned URIs •  Container items •  Jhug/discussions/1342 •  PUT for URIs defined by the client •  Jhug/presentations/rest •  Semicolon (;) or comma (,) for name/value or matrix values •  jhug/presentations/author,gkorilas/rest •  Query string for algorithmic resources •  Jhug/search?q=“rest” JHUG 17 Dec 2011
  • 21.
    Think Resource Oriented • Define the data set •  Expose data as resources •  Assign URIs to resources •  Decide the UI commands accepted •  Decide the representations accepted •  Decide the representations served •  Add hypermedia links between them JHUG 17 Dec 2011
  • 22.
    REST + •  Serverepresentations suitable for many clients •  The uniform interface allows all http clients to easily consume a suitable representation •  Content negotiation can allow a single URL to serve content to a browser, a JS client that is interested in JSON or a mobile phone client interested in an XML representation •  Cacheable by commodity technologies •  Scalable •  Fail over •  Clients: •  Browser friendly •  Easy support by many languages •  Bookmarkable •  Data formats •  It is the natural way of the web! JHUG 17 Dec 2011
  • 23.
  • 24.
    The Amazon S3Service •  S3 “buckets” and S3 “objects” •  Bucket can only contain objects •  Bucket names are unique in S3 •  Object has a name (key) and content (value) •  Object has a reference to the parent bucket •  Object has metadata key-value pairs; can also be http headers like content-type or content-disposition •  Three types of resources •  List of your buckets (https://s3.amazonaws.com/) •  A particular bucket (https://s3.amazonaws.com/{name-of-bucket}/). There can be up to 100 resources of this type. •  A particular S3 object inside a bucket (https://s3.amazonaws.com/ {name-of- bucket}/{name-of-object} JHUG 17 Dec 2011
  • 25.
    S3 resources andmethods GET HEAD PUT DELETE (/) List your buckets - - - /{bucket} List objects of bucket - Create the bucket Delete the bucket /{bucket}/ {object} Object’s value Object’s and metadata metadata Set the object’s value and metadata Delete the object JHUG 17 Dec 2011
  • 26.
    S3 Security •  Messagedigest of the canonical string of the request with a secret key (amazon knows it too) •  {http method}{content-type}{date}{amazon headers}{path} •  Add it to http Authorization: header •  Add it to query string together with expires date to make bookmarkable (https://s3.amazonaws.com/stelinio/rest.pdf# ? Signature=J%2Qu6krT3j0zaaFXjsLbowdfzExQ%3D # &Expires=1162156788&AWSAccessKeyId=0F9RBCLB5274NK TJ4DA3") •  Access policies •  Private, public-read, public-write, authenticated read JHUG 17 Dec 2011
  • 27.
    HTTP security, OAuth • http basic •  http digest •  http client certificate •  OAuth •  Delegated user authentication solution - Valet key principle •  Client, server, resource owner (OAuth love triangle) •  client credentials, temporary credentials, and token credentials JHUG 17 Dec 2011
  • 28.
    Java REST Services • Java EE 6 specification: JAX-RS •  Jersey: Reference implementation of JSR 311 •  Available as standalone and enterprise JHUG 17 Dec 2011
  • 29.
  • 30.
    JAX-RS Resources Annotate POJOs @Path("/meetups") @Singleton() publicclass MeetUpsResource { @GET() @Path("/latest") @Produces("text/plain") public String getLatestMeetUp() { return getDataService().getLatestMeetUp().toString(); } @GET() @Path("/next") @Produces("text/plain") public String getNextMeetUp() { return getDataService().getNextMeetUp().toString(); } @GET() @Produces(MediaType.APPLICATION_JSON) public MeetUps getAllMeetUps() { return getDataService().getAllMeetUps(); } } JHUG 17 Dec 2011
  • 31.
    Methods & Paths • @javax.ws.rs.GET •  @javax.ws.rs.PUT •  @javax.ws.rs.POST •  @javax.ws.rs.DELETE •  @javax.ws.rs.HEAD •  Paths: Most specific match wins JHUG 17 Dec 2011
  • 32.
    JAX-RS Injection •  @javax.ws.rs.PathParam • values from URI template parameters •  @javax.ws.rs.MatrixParam •  URI’s matrix parameters. •  @javax.ws.rs.QueryParam •  Query String parameters •  @javax.ws.rs.FormParam •  form-encoded key-value pairs •  @javax.ws.rs.HeaderParam •  HTTP request headers •  @javax.ws.rs.CookieParam •  HTTP cookies set by the client •  @javax.ws.rs.core.Context •  All-purpose injection annotation. It allows you to inject various helper and informational objects that are provided by the JAX-RS API e.g. •  @Context final HttpServletRequest request •  @Context final SecurityContext secCtx JHUG 17 Dec 2011
  • 33.
    JAX-RS Content Handling • MIME types •  Automatic content negotiation •  Automatic content serialization •  Jaxb representation → XML, JSON •  Byte[] → Binary or */* •  String → text/* •  MultiValuedMap<String, String> → application/x-www-formurlencoded •  StreamingOutput •  @Providers JHUG 17 Dec 2011
  • 34.
    JAX-RS Error Handling • HTTP Error Codes •  WebApplicationException •  ExceptionMapper throw new WebApplicationException(new RuntimeException (“Timeframe not an Integer"), Response.Status.NOT_ACCEPTABLE); @Provider public class EntityNotFoundMapper implements ExceptionMapper<EntityNotFoundException> { public Response toResponse(EntityNotFoundException e){ return Response.status(Response.Status.NOT_FOUND).build(); } } JHUG 17 Dec 2011
  • 35.
    Enforcing security •  @RolesAllowed({“admin”,”client-admin”}) • @PermitAll •  Any authenticated user •  @SecurityContext public interface SecurityContext { public static final String BASIC_AUTH = "BASIC"; public static final String CLIENT_CERT_AUTH = "CLIENT_CERT"; public static final String DIGEST_AUTH = "DIGEST"; public static final String FORM_AUTH = "FORM"; public Principal getUserPrincipal(); public boolean isUserInRole(String role); public boolean isSecure(); public String getAuthenticationScheme(); } JHUG 17 Dec 2011
  • 36.
    Example @Path(”/presentations") @Singleton() public class PresentationsResource{ @PUT() @Path(”/presentation/{name}”) @RolesAllowed(”admin”) public void addPresentation(@PathParam name, InputStream is){ return getDataService().addPresentation(is); } @GET() @Path(”/presentation/{name}") public StreamingOutput getPresentation(@PathParam name) { return new StreamingOutput() { @Override public void write(OutputStream output) throws IOException { stream( getDataService().getPresentation(name) , output ); } } } } JHUG 17 Dec 2011
  • 37.
    CTR •  Clinical TrialsRegister •  (https://www.clinicaltrialsregister.eu/) •  Rest services •  Data to other agency html pages •  Content to the World Health Organization •  Data to the web application users •  Rest clients •  JS code as the client •  Controller servlet •  JSP <c:import url=“/trial/2010-022009-16/GB”/> •  A guy at World Health Organization every Tuesday at 19:00 JHUG 17 Dec 2011
  • 38.
    Data consumed byhtml pages (1/3) @Path("/trials") @Singleton() public class TrialsMetaDataResource { @GET() @Path("/count/public") @Produces("text/plain") public String countPublicTrials() { return getDataService().countPublicClinicalTrials().toString(); } @GET() @Path("/count/public/under18") @Produces("text/plain") public String countUnder18PublicTrials() { return getDataService().countPublicClinicalTrialsWithSubjectsUnder18().toString(); } @GET() @Path("/landing") @Produces(MediaType.APPLICATION_JSON) public LandingPageMetadata landingPageMetadata() { Integer total = getDataService().countPublicClinicalTrials(); Integer under18 = getDataService().countPublicClinicalTrialsWithSubjectsUnder18(); } … } LandingPageMetadata metadata = new LandingPageMetadata(total, under18); return metadata; JHUG 17 Dec 2011
  • 39.
    Data consumed byhtml pages (2/3) @XmlRootElement() @XmlAccessorType(value = XmlAccessType.PROPERTY) public class LandingPageMetadata implements Serializable { private static final long serialVersionUID = -8784258618018188874L; private Integer numberOfPublicClinicalTrials; private Integer numberOfPublicClinicalTrialsWithSubjectsUnder18; public LandingPageMetadata() {…} public LandingPageMetadata(Integer numberOfPublicClinicalTrials, Integer numberOfPublicClinicalTrialsWithSubjectsUnder18) {…} @XmlElement(name="total") public Integer getNumberOfPublicClinicalTrials() {…} public void setNumberOfPublicClinicalTrials(Integer numberOfPublicClinicalTrials) {…} @XmlElement(name="under18") public Integer getNumberOfPublicClinicalTrialsWithSubjectsUnder18() {…} public void setNumberOfPublicClinicalTrialsWithSubjectsUnder18(Integer numberOfPublicClinicalTrialsWithSubjectsUnder18) {…} @Override public String toString() {…} } JHUG 17 Dec 2011
  • 40.
    Data consumed byhtml pages (3/3) function showNumbers() { $.getJSON('api/trials/landing', function(data) { var total = data['total']; var under18 = data['under18']; $("#total").text(total); $("#under18").text(under18); }); } JHUG 17 Dec 2011
  • 41.
    Streaming Content (1/2) @Path("/download") publicclass DownloadResource { @GET @Path("/summary") public Response downloadSummaryTrials(@Context final HttpServletRequest request, @QueryParam ("mode") final String mode) { return Response.ok(new SummaryStreamingOutput(request, mode),MediaType.APPLICATION_OCTET_STREAM) .header("content-disposition","attachment; filename = trials-summary.txt").build(); } @GET @Path("/full") public Response downloadFullTrials(@Context final HttpServletRequest request, @QueryParam ("mode") final String mode) { return Response.ok(new FullStreamingOutput(request, mode),MediaType.APPLICATION_OCTET_STREAM) .header("content-disposition","attachment; filename = trials-full.txt").build(); } @GET @Path("/trial/{eudractnumber}/{nca}") public Response downloadFullCta(@Context final HttpServletRequest req, @PathParam ("eudractnumber") String eudractnumber, @PathParam("nca") String nca) { return Response.ok(new CtaStreamingOutput(req, eudractnumber, nca),MediaType.APPLICATION_OCTET_STREAM) .header("content-disposition","attachment; filename = trial.txt").build(); } } JHUG 17 Dec 2011
  • 42.
    Streaming Content (2/2) publicclass CtaStreamingOutput implements StreamingOutput { public CtaStreamingOutput(HttpServletRequest request, String euNumber, String nca) {…} } public void write(OutputStream output) throws IOException { TextSerializer ser = new TextSerializer(); ser.setOutputStream(output); CtaIdentification pubCta = mapper.map (eudractNumber, nca); ser.serializeCtaFull(pubCta); } JHUG 17 Dec 2011
  • 43.
    RSS 2.0 insteadof built in Atom (1/2) @GET @Path("/bydates”) @Produces("application/rss+xml") public SyndFeed getFeed(@Context final HttpServletRequest request) { String feedType = "rss_2.0”; SyndFeed feed = new SyndFeedImpl(); feed.setFeedType(feedType); String url = request.getRequestURL().toString().replaceFirst("/rest/ feed/bydates", ”/search") + "?" + request.getQueryString(); feed.setLink(url); feed.setTitle("EU Clinical Trials Register RSS Feed"); feed.setDescription("This provides a regular feed of new or updated clinical trial information published on the EU Clinical Trial Register and matching the search subscribed to."); List<CtrDocument> docs = search(request); for(CtrDocument doc: docs){ SyndEntry entry = buildEntry(doc, entryBasicUrl, countryUrl); feed.getEntries().add(entry); } LOG.info("Generated RSS feed {}", feed.getLink()); return feed; } JHUG 17 Dec 2011
  • 44.
    RSS 2.0 insteadof built in Atom (2/2) @Provider @Produces("application/rss+xml") @Consumes("application/rss+xml") public class RomeRssSupport implements MessageBodyWriter<Object>{ public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) { return (SyndFeed.class.isAssignableFrom(type)); } public long getSize(Object t, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) { return -1; } } public void writeTo(Object feedOrEntry, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, Object> httpHeaders, OutputStream outputStream) throws IOException { if (feedOrEntry instanceof SyndFeed) { SyndFeed feed = (SyndFeed)feedOrEntry; SyndFeedOutput output = new SyndFeedOutput(); doc = output.outputW3CDom(feed); Source source = new DOMSource(doc); Result result = new StreamResult(outputStream); TransformerFactory factory = TransformerFactory.newInstance(); Transformer transformer = factory.newTransformer(); transformer.transform(source, result); } } JHUG 17 Dec 2011
  • 45.
    Resources •  Restful WebServices - Leonard Richardson and Sam Ruby •  Service Design Patterns - Robert Daigneau •  Restful Java - Bill Burke •  www.amazon.com •  http://icondrawer.com •  http://www.iconeden.com •  http://www.iconshock.com JHUG 17 Dec 2011