Presentation introduces to REST HATEOAS Web Services (Maturity Level 3 in Richardson model) and makes some additional proposals:
1) Meta-data can be useful;
2) Meta-data should be dynamically generated (not static);
3) Separation of data and meta-data representations;
4) Meta-data should be dynamically discoverable using hyper links;
5) Separation of Command and Query resource representations.
It is accompanied by 4 demos and hands-on exercises (see last slides) available at:
https://github.com/iproduct/BGJUG-REST-Demo/tree/master/IPT_JAX-RS_2.0_Demos
1. IPT – Intellectual Products & Technologies
Trayan Iliev, http://www.iproduct.org/
BGJUG Meeting – Sofia
November 10, 2014
REST, HATEOAS & Metadata with JAX-RS 2.0
Trayan Iliev
IPT – Intellectual Products & Technologies
e-mail: tiliev@iproduct.org
web: http://www.iproduct.org
Oracle®, Java™ and JavaScript™ are trademarks or registered trademarks of Oracle and/or its affiliates.
Other names may be trademarks of their respective owners.
Licensed under the Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Slide 1
Unported License
2. IPT – Intellectual Products & Technologies
Trayan Iliev, http://www.iproduct.org/
BGJUG Meeting – Sofia
November 10, 2014
Agenda
Service Oriented Architecture (SOA) & REST
REpresentational State Transfer (REST) architectural style – advantages
and main constraints
Hypermedia As The Engine Of Application State (HATEOAS)
Richardson Maturity Model of Web Applications
RESTful services + JSON – lightweight and efficient way for building
platform independent and loosely-coupled applications
RESTful patterns & anti-patterns
Java API for RESTful Web Services – JAX-RS
Proposal: Separation of Query & Command Representations & dynamically
generated meta-data for RESFTUL resources
Let's try it (IPT Course Manager + Polling Demo & hands-on exercises)
Licensed under the Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Slide 2
Unported License
3. IPT – Intellectual Products & Technologies
Trayan Iliev, http://www.iproduct.org/
BGJUG Meeting – Sofia
November 10, 2014
Question 1
How many people know what is
REST?
Licensed under the Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Slide 3
Unported License
4. IPT – Intellectual Products & Technologies
Trayan Iliev, http://www.iproduct.org/
BGJUG Meeting – Sofia
November 10, 2014
Question 2
How many people have
developed at least one RESTful
service with JAX-RS?
Licensed under the Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Slide 4
Unported License
5. IPT – Intellectual Products & Technologies
Trayan Iliev, http://www.iproduct.org/
BGJUG Meeting – Sofia
November 10, 2014
Software Architecture – Definitions [1]
Almost everybody feels at peace with nature: listening to the ocean
waves against the shore, by a still lake, in a field of grass, on a
windblown heath. One day, when we have learned the timeless way
again, we shall feel the same about our towns, and we shall feel as
much at peace in them, as we do today walking by the ocean, or
stretched out in the long grass of a meadow.
— Christopher Alexander, The Timeless Way of Building (1979)
Licensed under the Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Slide 5
Unported License
6. IPT – Intellectual Products & Technologies
Trayan Iliev, http://www.iproduct.org/
BGJUG Meeting – Sofia
November 10, 2014
Software Architecture – Definitions [2]
According to Dr. Roy Thomas Fielding [Architectural Styles and
the Design of Network-based Software Architectures, 2000]:
A software architecture is an abstraction of the run-time
elements of a software system during some phase of its
operation. A system may be composed of many levels of
abstraction and many phases of operation,each with its own
software architecture.
A software architecture is defined by a configuration of
architectural elements - components, connectors, and data -
constrained in their relaionships in order to achieve a desired set
of architectural properties.
Licensed under the Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Slide 6
Unported License
7. IPT – Intellectual Products & Technologies
Trayan Iliev, http://www.iproduct.org/
BGJUG Meeting – Sofia
November 10, 2014
Software Architecture – Definitions [3]
According to Dr. Roy Thomas Fielding [Architectural Styles and
the Design of Network-based Software Architectures, 2000]:
An architectural style is a coordinated set of architectural
constraints that restricts the roles/features of architectural
elements and the allowed relationships among those elements
within any architecture that conforms to that style.
The primary distinction between Network-based architectures
and software architectures in general is that communication
between components is restricted to message passing, or the
equivalent of message passing if a more efficient mechanism can
be selected at runtime based on the location of components.
Licensed under the Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Slide 7
Unported License
8. IPT – Intellectual Products & Technologies
Trayan Iliev, http://www.iproduct.org/
BGJUG Meeting – Sofia
November 10, 2014
Architectural Properties
According to Dr. Roy Thomas Fielding [Architectural Styles and
the Design of Network-based Software Architectures, 2000]:
Performance
Scalability
Reliability
Simplicity
Extensibility
Dynamic evolvability
Cusomizability
Configurability
Visibility
All of them should be present in a desired Web Architecture
and REST architectural style tries to preserve them by
consistently applying several architectural constraints
Licensed under the Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Slide 8
Unported License
9. IPT – Intellectual Products & Technologies
Trayan Iliev, http://www.iproduct.org/
BGJUG Meeting – Sofia
November 10, 2014
Service Oriented Architecture (SOA) –
Definitions
Thomas Erl: SOA represents an open, agile, extensible,
federated, composable architecture comprised of autonomous,
QoS-capable, vendor diverse, interoperable, discoverable, and
potentially reusable services, implemented as Web services. SOA
can establish an abstraction of business logic and technology,
resulting in a loose coupling between these domains. SOA is an
evolution of past platforms, preserving successful characteristics
of traditional architectures, and bringing with it distinct principles
that foster service-orientation in support of a service-oriented
enterprise. SOA is ideally standardized throughout an enterprise,
but achieving this state requires a planned transition and the
support of a still evolving technology set
References: Erl, Thomas. Serviceorientation.org – About the Principles, 2005–06
Licensed under the Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Slide 9
Unported License
10. IPT – Intellectual Products & Technologies
Trayan Iliev, http://www.iproduct.org/
BGJUG Meeting – Sofia
November 10, 2014
SOA == SOAP + WSDL?
Web Services are:
Semantic
Models
components for building distributed
applications in SOA architectural style
communicate using open protocols
are self-descriptive and self-content
can be searched and found using
UDDI or ebXML registries (and more
recent specifications – WSIL &
Semantic Web Services)
Mapping
WSDL
Messages
Source: http://en.wikipedia.org/wiki/File:Webservices.png, Author: H. Voormann
License: Creative Commons Attribution 3.0 Unported
WSDL
Licensed under the Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Slide 10
Unported License
11. IPT – Intellectual Products & Technologies
Trayan Iliev, http://www.iproduct.org/
BGJUG Meeting – Sofia
November 10, 2014
Service Oriented Architecture (SOA)
Java EE 6
Architecture
Source: http://en.wikipedia.org/wiki/File:SO A_Detailed_Diagram.png,
Author: JamesLWilliams2010, License: Creative Commons Attribution 3.0 Unported
Licensed under the Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Slide 11
Unported License
12. IPT – Intellectual Products & Technologies
Trayan Iliev, http://www.iproduct.org/
BGJUG Meeting – Sofia
November 10, 2014
SOA Implemetation - Java SE/EE 6 APIs
According to Java™ EE Specification:
Web Services (SOAP)
Java API for XML Web Services (JAX-WS)
Java Architecture for XML Binding (JAXB)
SOAP with Attachments API for Java (SAAJ)
Java API for XML Registries (JAXR)
RESTful Web Services
Java API for RESTful Web Services - JAX-RS
Licensed under the Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Slide 12
Unported License
13. IPT – Intellectual Products & Technologies
Trayan Iliev, http://www.iproduct.org/
BGJUG Meeting – Sofia
November 10, 2014
Representational State Transfer (REST) [1]
REpresentational State Transfer (REST) is an architecture
for accessing distributed hypermedia web-services
The resources are identified by URIs and are accessed and
manipulated using an HHTP interface base methods (GET,
POST, PUT, DELETE, OPTIONS, HEAD, PATCH)
Information is exchanged using representations of these
resources
Lightweight alternative to SOAP+WSDL -> HTTP + Any
representation format (e.g. JavaScript™ Object Notation –
JSON)
Licensed under the Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Slide 13
Unported License
14. IPT – Intellectual Products & Technologies
Trayan Iliev, http://www.iproduct.org/
BGJUG Meeting – Sofia
November 10, 2014
Representational State Transfer (REST) [2]
Identification of resources – URIs
Representation of resources – e.g. HTML, XML, JSON, etc.
Manipulation of resources through these representations
Self-descriptive messages - Internet media type (MIME type)
provides enough information to describe how to process the
message. Responses also explicitly indicate their cacheability.
Hypermedia as the engine of application state (aka HATEOAS)
Application contracts are expressed as media types and
[semantic] link realtions (rel attribute - RFC5988, "Web Linking")
[Source: http://en.wikipedia.org/wiki/Representational_state_transfer]
Licensed under the Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Slide 14
Unported License
15. IPT – Intellectual Products & Technologies
Trayan Iliev, http://www.iproduct.org/
BGJUG Meeting – Sofia
November 10, 2014
Advantages of REST
Scalability of component interactions – through layering the client
server-communication and enabling load-balancing, shared
caching, security policy enforcement;
Generality of interfaces – allowing simplicity, reliability, security
and improved visibility by intermediaries, easy configuration,
robustness, and greater efficiency by fully utilizing the
capabilities of HTTP protocol;
Independent development and evolution of components,
dynamic evolvability of services, without breaking existing
clients.
Fault tolerat, Recoverable, Secure, Loosely coupled
Licensed under the Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Slide 15
Unported License
16. IPT – Intellectual Products & Technologies
Trayan Iliev, http://www.iproduct.org/
BGJUG Meeting – Sofia
November 10, 2014
Richardson's Maturity Model of Web Services
According to Leonard Richardson [Talk at QCon, 2008 -
http://www.crummy.com/writing/speaking/2008-QCon/act3.html]:
Level 0 – POX: Single URI (XML-RPC, SOAP)
Level 1 – Resources: Many URIs, Single Verb (URI Tunneling)
Level 2 – HTTP Verbs: Many URIs, Many Verbs (CRUD – e.g
Amazon S3)
Level 3 – Hypermedia Links Control the Application State =
HATEOAS (Hypertext As The Engine Of Application State)
=== truely RESTful Services
Licensed under the Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Slide 16
Unported License
17. IPT – Intellectual Products & Technologies
Trayan Iliev, http://www.iproduct.org/
BGJUG Meeting – Sofia
November 10, 2014
Is There A Level 4 for WebApp Maturity?
Considerations:
Command Query Responsibility Segregation (CQRS):
http://martinfowler.com/bliki/CQRS.html (Gentle introduction
by Martin Fowler) & ReportingDatabases:
http://martinfowler.com/bliki/ReportingDatabase.html
A single representation type can not be optimal for both
reading (Query) and updating the application state
(Command)
We may prefer to model Query and Command as separate
resources / representation types
Licensed under the Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Slide 17
Unported License
18. IPT – Intellectual Products & Technologies
Trayan Iliev, http://www.iproduct.org/
BGJUG Meeting – Sofia
November 10, 2014
What About Meta-Data?
Very important for a RESTful applications where resources and
resource states are dynamically discoverable / changeable
But what we have?
For SOAP services there is a WSDL (XML Schema based data
type descriptions)
REST should have the same -> Welcome WADL !
But is it really a good thing to have a static description of
dynamically changeable resources and valid resource state
change transitions?
Static model can be evil in a Live World!
Licensed under the Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Slide 18
Unported License
19. IPT – Intellectual Products & Technologies
Trayan Iliev, http://www.iproduct.org/
BGJUG Meeting – Sofia
November 10, 2014
Web Application Description Language (WADL)
XML-based file format providing machine-readable description
of HTTP-based web application resources – typically RESTful
web services
WADL is a W3C Member Submission
Multiple resources
Inter-connections between resources
HTTP methods that can be applied accessing each resource
Expected inputs, outputs and their data-type formats
XML Schema data-type formats for representing the RESTful
resources
But WADL resource description is static ... let's make it
dynamic!
Източник: http://en.wikipedia.org/wiki/File:Webservices.png, автор: H. Voormann
Лиценз: Creative Commons Attribution 3.0 Unported
Licensed under the Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Slide 19
Unported License
20. IPT – Intellectual Products & Technologies
Trayan Iliev, http://www.iproduct.org/
BGJUG Meeting – Sofia
November 10, 2014
The New Kids on the Block: JSON, JSON Schema &
Hyper Schema, Microformats
There are good use cases for WADL (REST resource metadata
descriptions): automatic generation of client code & functional
REST service tests, client data validation, building of generic
REST clients.
WADL is XML (and relies on XML Schema Definitions) – this is
a limitation for JavaScript Clients
Welcome JSON Schema & JSON Hyper-Schema !
But there are also Microformats (XHTML Meta Data Profiles –
XMDP): e.g. hCard, hReview, hProduct, hCalendar ...
Talking about meta-data: W3C Resource Description
Framework (RDF) and Web Ontology Language (OWL)
Licensed under the Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Slide 20
Unported License
21. IPT – Intellectual Products & Technologies
Trayan Iliev, http://www.iproduct.org/
BGJUG Meeting – Sofia
November 10, 2014
Metadata-Representations Proposal (& Questions)
Meta-data can be very useful for generic REST clients and
agents crawling the Web!
Meta-data should be dynamically generated
... but can be more stable than the data it describes
Separation of data and meta-data representations (different
life-cycles – allows optional retrieval, caching)
Meta-data should be dynamically discoverable using hyper
links in resource representations (rel= type/ describedby/ lrdd?)
Separation of Command and Query representations ->
optimal representations for each task (possibly with separate
MIME types – application/vnd.*+json/xml?)
Licensed under the Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Slide 21
Unported License
22. IPT – Intellectual Products & Technologies
Trayan Iliev, http://www.iproduct.org/
BGJUG Meeting – Sofia
November 10, 2014
RESTful Patterns and Best Practices
According to Cesare Pautasso
[http://www.jopera.org/files/SOA2009-REST-Patterns.pdf]:
Uniform Contract
Content Negotiation
Entity Endpoint
Endpoint Redirection
Distributed Response Caching
Entity Linking
Idempotent Capability
Message-based State Deferral, etc.
Licensed under the Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Slide 22
Unported License
23. IPT – Intellectual Products & Technologies
Trayan Iliev, http://www.iproduct.org/
BGJUG Meeting – Sofia
November 10, 2014
REST Antipatterns and Worst Practices
According to Jacob Kaplan-Moss
[http://jacobian.org/writing/rest-worst-practices/]:
Conflating models and resources
Hardcoded authentication
Resource-specific output formats
Hardcoded output formats
Weak HTTP method support (e.g. tunell everything through
GET/POST)
Improper use of links
Couple the REST API to the application
Licensed under the Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Slide 23
Unported License
24. IPT – Intellectual Products & Technologies
Trayan Iliev, http://www.iproduct.org/
BGJUG Meeting – Sofia
November 10, 2014
Java API for RESTful Web Service (JAX-RS)
Packages: javax.ws.rs, javax.ws.rs.core, javax.ws.rs.ext
Basic annotations:
@Path
@PathParam
@QueryParam
@FormParam
@HeaderParam
@CookieParam
@MatrixParam
@DefaultValue
@Encoded
@Produces
@Consumes,
@HttpMethod
@GET
@POST
@PUT
@DELETE
@Provider
@Context
Източник: http://en.wikipedia.org/wiki/File:Webservices.png, автор: H. Voormann
Лиценз: Creative Commons Attribution 3.0 Unported
Licensed under the Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Slide 24
Unported License
25. IPT – Intellectual Products & Technologies
Trayan Iliev, http://www.iproduct.org/
BGJUG Meeting – Sofia
November 10, 2014
Implementing REST Resources using JAX-RS [1]
@Stateless
@Path("courses")
@TransactionManagement(TransactionManagementType.BEAN)
public class CoursesResource extends
AbstractFacade<Course> {
@PersistenceContext(unitName = "IPTCourseManagerPU")
private EntityManager em;
@Context
private UriInfo context;
@Resource
UserTransaction utx;
Licensed under the Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Slide 25
Unported License
26. IPT – Intellectual Products & Technologies
Trayan Iliev, http://www.iproduct.org/
BGJUG Meeting – Sofia
November 10, 2014
Implementing REST Resources using JAX-RS [2]
@POST
@Consumes({"application/json", "application/xml"})
public Response createCourse(Course entity){
Licensed under the Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Slide 26
Unported License
try {
utx.begin();
super.create(entity);
utx.commit();
return
Response.created(UriBuilder.fromUri(context.getAbsolutePa
th()).path(entity.getId().toString()).build()).build();
} catch (Exception ex) {
throw new WebApplicationException(ex);
}
}
27. IPT – Intellectual Products & Technologies
Trayan Iliev, http://www.iproduct.org/
BGJUG Meeting – Sofia
November 10, 2014
Implementing REST Resources using JAX-RS [3]
@GET
@Produces({"application/xml", "application/json"})
public CoursesRepresentation getAllCourses() {
return new CoursesRepresentation(super.findAll());
Licensed under the Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Slide 27
Unported License
}
@Path("{id}")
public CourseResource getCourseResource(
@PathParam("id") Integer id) {
return new CourseResource(id, em, utx);
}
Sub-resource
28. IPT – Intellectual Products & Technologies
Trayan Iliev, http://www.iproduct.org/
BGJUG Meeting – Sofia
November 10, 2014
Some Open Source WS Implementation Stacks
Glassfish Metro – http://metro.java.net/ – JAX-WS (SOAP
+ WSDL) Reference Implementation
Glassfish Jersey – http://jersey.java.net/ – JAX-RS
(JSR 311) Reference Implementation for building
RESTful Web services
RESTEasy – http://resteasy.jboss.org/ – JBoss JAX-RS
implementation
Apache CXF – http://cxf.apache.org/ – JAX-WS & JAX-RS
Apache Axis 2 – http://axis.apache.org/axis2/java/core/ –
SOAP & REST web services
Licensed under the Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Slide 28
Unported License
29. IPT – Intellectual Products & Technologies
Trayan Iliev, http://www.iproduct.org/
BGJUG Meeting – Sofia
November 10, 2014
Proposed Architecture:
jQuery Client + RESTful Backend
Licensed under the Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Slide 29
Unported License
30. IPT – Intellectual Products & Technologies
Trayan Iliev, http://www.iproduct.org/
BGJUG Meeting – Sofia
November 10, 2014
REST Demo: IPT Course Manager + Generic Client
Licensed under the Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Slide 30
Unported License
31. IPT – Intellectual Products & Technologies
Trayan Iliev, http://www.iproduct.org/
BGJUG Meeting – Sofia
November 10, 2014
Polling Demo + Hands-on Exercises (1)
Licensed under the Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Slide 31
Unported License
32. IPT – Intellectual Products & Technologies
Trayan Iliev, http://www.iproduct.org/
BGJUG Meeting – Sofia
November 10, 2014
Polling Demo + Hands-on Exercises (2)
You can clone (or download) IPT Git repository at:
https://github.com/iproduct/BGJUG-REST-Demo/
Demos & exercises are provided as NetBeans projects – please
follow the setup instructions.
There are four JAX-RS 2 (Jersey) demos in the repository with
corresponding _Exercises (complete methods to satisfy functional tests):
1.RestfulHello – introduction to JAX-RS – simple HelloResource &
StudentResource CRUD
2.PollingDemoBasic – basic version of RESTful poll voting service
3.PollingDemoSubresourceJPA – RESTful CRUD – Alternative & Vote
sub-resources added + JPA persistence (default Apache Derby used)
4.PollingDemoHATEOAS – hypermedia version with navigable state
Licensed under the Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Slide 32
Unported License
33. IPT – Intellectual Products & Technologies
Trayan Iliev, http://www.iproduct.org/
BGJUG Meeting – Sofia
November 10, 2014
Polling Demo Resources
Licensed under the Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Slide 33
Unported License
34. IPT – Intellectual Products & Technologies
Trayan Iliev, http://www.iproduct.org/
BGJUG Meeting – Sofia
November 10, 2014
Polling Demo – Poll Resource States
Licensed under the Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Slide 34
Unported License
35. IPT – Intellectual Products & Technologies
Trayan Iliev, http://www.iproduct.org/
BGJUG Meeting – Sofia
November 10, 2014
Want to Learn More?
Welcome to IPT Java™ trainings [http://www.iproduct.org/]:
Programming in Java Language - 3 modules
Web Programming with Java Technology: Servlet 3.1, JSP, JSTL,
EL, JSF 2.2, Facelets & Templating, AJAX, JSON, WebSocket
Java Enterprise Technologies (Java EE 7) – EJB 3.2, JSF 2.2,
JAX-RS 2.0, Web Services, WebSocket, JMS, CDI, Bean
Validation, JPA, JTA, Batch and Concurrency
Service Oriented Architecture (SOA) & Contemporary Standards
for Business Process Modeling (BPM) - SOAP, WSDL 2.0, REST,
SOA, SCA, SDO, BPMN, WS-BPEL
Java™ Portlet Development with JSR 286: Portlet 2.0 API,
Liferay® 6 & GateIn 3 – JSP™, JSF 2.2 & AJAX Portlet
Oracle®, Java™ and JavaScript™ are trademarks or registered trademarks of Oracle and/or its affiliates.
Liferay® is a registered trademark of Liferay, Inc. Other names may be trademarks of their respective owners.
Licensed under the Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Slide 35
Unported License
36. IPT – Intellectual Products & Technologies
Trayan Iliev, http://www.iproduct.org/
BGJUG Meeting – Sofia
November 10, 2014
References
R. Fielding, Architectural Styles and the Design of Networkbased
Software Architectures, PhD Thesis, University of California, Irvine,
2000
Fielding's blog discussing REST –
http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven
Representational state transfer (REST) in Wikipedia –
http://en.wikipedia.org/wiki/Representational_state_transfer
Hypermedia as the Engine of Application State (HATEOAS) in
Wikipedia – http://en.wikipedia.org/wiki/HATEOAS
JavaScript Object Notation (JSON) – http://www.json.org/
JAX-RS 2.0 (JSR 339) Reference Implementation for building
RESTful Web services – http://jersey.java.net/
Licensed under the Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Slide 36
Unported License
37. IPT – Intellectual Products & Technologies
Trayan Iliev, http://www.iproduct.org/
BGJUG Meeting – Sofia
November 10, 2014
Thanks for Your Attention!
Questions?
Licensed under the Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Slide 37
Unported License