Intro to REST (Representation State Transfer)
REST in Practice
First 3 chapters: important points
Web tolerance of change, p.4—just live with 404s
Thinking in Resources, pg 4-7, URIs, URLs, etc
Resources and their representations: XML, JSON, text, etc., p. 8-9
REST background, p. 12
Idea of hypermedia, p. 13
Loose coupling, pg. 16
Richardson’s levels: pa2 is level 1, Chap 4 is level 2
(Richardson &Ruby are authors of first important book on REST, RESTful Web Services)
Restbuck’s shop basics pg. 22-24, 28
Can skip Chap. 3, mostly on how not to do things
Except pg. 38: idea that we use GET only to get info, not change anything in the server, and def. of idempotent, operation that can be repeated without changing the result.
Also worth reading: Chap.11
Are Web Services evil?
SOAP, WSDL
Note links at end of class web page: Java EE, REST, JAX-RS, Jersey, JAXB
Chap. 4 Order Service
A CRUD service:
1. Create an order
2. Retrieve the order to check status
3. Update/replace the order
4. Delete the order
Maps into HTTP verbs as shown on pg. 57
First task: write a client for this Chap 4 service, say deployed at http://users2.cs.umb.edu:11600/orderService, with schema for messages available at
http://users2.cs.umb.edu:11600/orderService/OrderService.xsd.
From client viewpoint: Order a coffee:
POST XML for order to http://users2.cs.umb.edu:11600/orderService/rest/order
get back XML for order with id filled in, say order 22, status = PREPARING
This means this order’s resource is /orderService/rest/order/22.
Find out the order status:
GET to /orderService/rest/order/22, to get the current “resource” there, see same old status in the XML response
Separately, the admin sends POST to .../rest/poke: make oldest order ready.
GET to /orderService/rest/order/22, to see if it’s ready, see status=READY in the XML, time to pick it up.
Nifty way: use JAXB to turn provided schema into Java objects for client to use.
The service can also provide JSON if we want.
The idea of REST is to use HTTP directly, rather than reducing it to a carrier of SOAP messages. With REST, we use multiple HTTP verbs:
· GET for reading data (no changes allowed in server!)
· POST for creating new data items
· PUT for replacing old data items
· DELETE for deleting old data items
Flip through Chap. 4 to see these actions in diagrams.
How do we specify the data item to work on?
In REST, we use individual URLs for data items, i.e. “resources”.
Chap. 4 example: pg. 57:
GET /order/1234 read order # 1234 (in XML)
POST /order add a new order (server determines new id).
(also PUT and DELETE)
How does the client find out the new id after a POST?
The HTTP Location header in the response gives this. See pg. 60 for full response: HTTP headers + XML body
Note: in the orderService project, the id is returned also in the XML for the order coming back from the POST.
So we see that REST uses HTTP directly, including its headers. So we don’t have a “REST protocol” or “REST envelope” in the usual sense, although there are strong conventions on how to use HTTP for REST.
We can say it’s a software architectural style for distributed systems. It was created by Roy Fielding, and described in his widely-read PhD thesis. He got a degree in 2000 after doing a lot of important work on the HTTP and URL specs.
REST design Principles (using HTTP. Conceivably, could use something else.)
1. “Stateless” Client/Server Protocol: Each message contains all the information needed by the receiver to understand and process it. Simplest way. Note that SOAP Web services also follow this design point.
2. Use a set of uniquely addressable (by URIs) resources: “everything is a resource”, the RESTful way.
3. Use a set of well-defined operations that can be applied to all resources: HTTP verbs
4. Use “hypermedia”: return a document with links to the client, giving the user or client tool choices of what to do next.
In our current effort, considering Chap. 4, we are not yet doing the hypermedia part. That’s in Chap. 5.
Note the Wikipedia article on REST
Now we’ll look at the big chart from there,
RESTful Web Service HTTP methods[10] |
||||
Resource |
GET |
PUT |
POST |
DELETE |
Collection
URI, such as |
List the URIs and perhaps other details of the collection's members. |
Replace the entire collection with another collection. |
Create a new entry in the collection. The new entry's URL is assigned automatically and is usually returned by the operation. |
Delete the entire collection. |
Element
URI, such as |
Retrieve a representation of the addressed member of the collection, expressed in an appropriate Internet media type. |
Replace the addressed member of the collection, or if it doesn't exist, create it. |
Not generally used. Treat the addressed member as a collection in its own right and create a new entry in it.** |
Delete the addressed member of the collection. |
** or catch-all for miscellaneous services, also possibly appending data
Chap 4 orderService implements POST for /order, GET, PUT, and DELETE for /order/1234.
Online orderService implements DELETE for /order as well, and also another resource: POST to /poke
REST in general, continued.
Last time looked at expected meaning of various actions. One important aspect of these operations is whether or not they can be repeated safely without changing the result—
Idempotent or not? See pg. 38 for definition, also note at top of pg. 72 (or search “idempotent”)
GET retrieve a copy of a resource: YES, and also “safe” / “read-only” (no server-side modifications happen affecting the resource as seen by the client)
POST: create a new resource (plus catch-all): NO
PUT: replace a resource with given new content: YES
DELETE: delete a resource: YES
This property allows retry, important for many things including security.
Of course there’s also SOAP Web services. Later we should come back and do a comparison. Since they only use one URL for a whole service, and POST, they certainly are not idempotent.
We’re using Java with Java EE, but C# with .NET is also a viable option. Our book covers both ways.
Now look at our examples, firstRest and orderService (for Chap 4). They are both use the Jersey implementation of the Java EE JAX-RS, the Java API for RESTful Web Services. What does that mean?
The main Java distributions from Sun: Java EE (EE = enterprise edition) vs. the more basic Java SE (“the JDK”) (SE = standard edition)
Older names still in use: J2EE, JEE, J2SE, JSE.
So far everything we’ve used is in Java SE, except the servlet API: so SAX, DOM/XPath, reflection API, are all in the JDK, i.e., the library of Java SE. So is JDBC for database access, which you probably used in your database class.
Java EE contains the servlet API, and lots of other things, most famously “EJBs” Enterprise Java Beans, (APIs for them, anyway) tomcat can’t execute EJBs on its own, but we don’t need to use them. You need a full feature app server like JBoss or Glassfish to run EJBs.
Java EE also contains JAX-RS, the Java API for RESTful Web Services, AKA JSR 311 (JSR = Java Spec. Request, so 311 is the spec. number). As an API, it’s just a spec of what should be supported, with a spec. doc linked to the class web page. So we need an implementation of this spec to run something. Actually the spec only specifies the server side, I guess on the excuse that anyone should be able to do HTTP requests to certain URIs from the client.
JAX-RS an API in the generalized sense of covering annotations as well as method calls. Also it’s a “framework” in the sense that it specifies calls to our code at appropriate moments. It’s “just an API” in the sense that it doesn’t have implementation of the specified actions.
We’re using the Jersey, the “reference implementation” for this JAX-RS specification. Also tomcat (by Apache) is the reference implementation of Java EE’s servlet container. That means Sun (now Oracle), the Java EE source, has pointed to it as definitive. Jersey is part of project Glassfish, a Sun-sponsored development effort for Sun’s own web app server (Glassfish) and support for it (luckily done in separately usable pieces, so we can use their JAX-RS code with tomcat, our app server).
Building programs that use JAX-RS: we need extra jars over the JDK
In servlet1 and pa2, we needed an extra jar file for the servlet API, part of Java EE, so we used tomcat’s lib/servlet-api.jar (see build.xml). And so did eclipse, because of our setup of tomcat within it (see icon for Apache Tomcat Libraries in Java Build Path>Libraries, click it, see servlet-api.jar).
Then tomcat executed our code, with the help of its implementation of the servlet API and related services.
Now to use JAX-RS as implemented by Jersey, we need two kinds of jars:
· JAX-RS (JSR 311) API: jsr311-api.jar for API, part of Java EE so not in our Java SE JDK
· the Jersey implementation: jersey-bundle-xx.jar (or several separate jars) (and it needs asm-xx.jar for byte-code manipulation) xx= version number.
· For JSON serialization (i.e., instead of XML serialization), we need jettison.jar
The Java EE library is delivered in many jars. Jar files are big, so we don’t want to include ones we don’t need in our projects. We’ll work out from Java SE, which contains JAXB (note that we need at least Java 6 for a decent version of this), the basic capability of transforming Java objects to/from XML.
Jersey offers the JAX-RS server implementation and also a client library to give a complete REST solution framework.
We are also using Eclipse. Eclipse is independent of Sun, which in fact has its own IDE, Netbeans. But even so, eclipse is a very popular IDE for Java EE development, and has a lot of support for Java EE though its “WTP” Web Tools Project (mentioned in the firstRest tutorial). We see its Java EE support via the “Java EE Perspective” inside eclipse. With this perspective selected, we see the Servers View, where we can start and stop tomcat, etc. You can get this Servers view to show in other perspectives too, via Window>Show View .... So more basically, the Java EE support is behind the whole tomcat-handling ability of eclipse.
The firstRest tutorial assumes you want to use Jersey, tomcat, and eclipse, exactly our setup. It uses the Jersey client library, which we will do at least part of the time.
Note that you don’t need to do the Jersey download yourself, as indicated in the tutorial. All the needed jars are in the firstRest project already. Remember not to overwrite web.xml when you set up your eclipse Dynamic Web Project.
Just unzip firstRest.zip, use “ant build”, “ant deploy” as in pa2. This version uses env variables TOMCAT_URL and CATALINA_HOME just like pa2, so everything should work immediately.