Web Services : two types : old SOAP and more recent REST, now more important, and simpler.
REST design Principles (assumes HTTP transport)
More advanced : use “hypermedia”: return a document with links to the user, giving the user choices of what to do next
Can we recycle our webapp code for Web Services?
Yes! Our whole architecture works for supporting web services (SOAP or REST) : just stop using sessions. Use the database for all data that lives more than one request cycle.
Example: Pizza Project:
Turn the project into web services for pizzas: Drop the session variable.
Example: Music Project. Here we use a much bigger session variable for the Cart, which belongs to the user.
Turn the project into web services for selling guitars: We can put the cart in the database under an id and return the id, and provide an API for examining and changing the cart contents. There's actually a whole standard protocol for handling carts, part of cXML, discussed in cs637.
But for a more complete example, let's start with a simple CRUD service.
Example: Order Service
A CRUD service:
Maps into HTTP verbs as follows:
Verb URI Use
POST /orders Create new order, response header Location gives new URI
GET /orders/1234 Request state of order 1234
PUT /orders/1234 Update order 1234 in entirety
DELETE /orders/1234 Delete order 1234
From client viewpoint: Order a product:
POST XML or JSON for order to http://topcat.cs.umb.edu/orderService/rest/order
get back XML or JSON for order with id filled in, say order 22, status = PREPARING
This means this order’s resource is /orderService/rest/orders/22.
Find out the order status:
GET to /orderService/rest/orders/22, to get the current “resource” there, see same old status in the XML response.
GET to /orderService/rest/orders/22, to see if it’s ready, see status=READY in the XML, time to pick it up.
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:
How do we specify the data item to work on?
In REST, we use individual URLs for data items, i.e. “resources”.
GET /orders/1234 read order # 1234 (in XML or JSON)
POST /orders 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 it in typewriter font in the official RFC
Below, the client sends a POST request containing an Atom Entry representation using the URI of the Collection:
POST /edit/ HTTP/1.1 Host: example.org User-Agent: Thingio/1.0 Authorization: Basic ZGFmZnk6c2VjZXJldA== Content-Type: application/atom+xml;type=entry Content-Length: nnn Slug: First Post <?xml version="1.0"?> <entry xmlns="http://www.w3.org/2005/Atom"> <title>Atom-Powered Robots Run Amok</title> <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id> <updated>2003-12-13T18:30:02Z</updated> <author><name>John Doe</name></author> <content>Some text.</content> </entry>
The server signals a successful creation with a status code of 201. The response includes a Location header indicating the Member Entry URI of the Atom Entry, and a representation of that Entry in the body of the response.
HTTP/1.1 201 Created Date: Fri, 7 Oct 2005 17:17:11 GMT Content-Length: nnn Content-Type: application/atom+xml;type=entry;charset="utf-8" Location: http://example.org/edit/first-post.atom ETag: "c180de84f991g8" <?xml version="1.0"?> <entry xmlns="http://www.w3.org/2005/Atom"> <title>Atom-Powered Robots Run Amok</title> <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id> <updated>2003-12-13T18:30:02Z</updated> <author><name>John Doe</name></author> <content>Some text.</content> <link rel="edit" href="http://example.org/edit/first-post.atom"/> </entry>
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.
Mystery of the SLUG header. This is a suggestion by the client for a good name for the new resource. The server complied here by naming it .../first-post.atom. Apparently "slug" comes from newspaper lingo for a temporary name for a developing story.
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.
Note the Wikipedia article on REST
We looked at the big chart there of HTTP methods and their typical use in REST, originally from Richardson and Ruby, “Restful Web Services”, the first important book with implementations. Since that book, PATCH has been added as an HTTP method to the chart.
Note that REST/HTTP:
Obviously you need to be sure of all these aspects of HTTP to deal intelligently with REST.
REST is simple enough to be implemented in almost any language, but let's look at Java cases.
REST service code
We have seen how we can use wildcard URLs in web.xml to send multiple request URIs to a servlet.
Then once there, we can access the URI and interpret it, do the desired action, and send back an appropriate response.
REST client code
For GET, a primitive client can use Java URL class, url.openStream() gives an InputStream of the result.
For GET and POST, can use java.net.HttpURLConnection See example. Also shows Apache HTTP
Want XML/JSON on the wire, so need to use XML/JSON parser, XML generation.
For sizable project, should use a framework
JEE has spec JAX-RS for a server-side REST framework
Jersey provides an implementation of this, with client-side libraries as well. For the server side, it provides a servlet to use in any servlet container (tomcat or Glassfish or whatever) to handle incoming REST requests.
Good tutorial: firstRest at vogella.com. Note you don't need to use gradle (descendant of ant): see ant firstRest project linked to class web page and in $cs636/firstRest.
We looked at the tutorial, covering the annotations in server-side Java sources that guide its servlet to the right code to execute on various GET, POST, DELETE, etc requests coming in.
We looked at the web.xml, that shows how the provided servlet is put to use, and the package with the server sources is specified, so that the servlet can examine the annotations there.
We looked at Hello.java, the server source. It can handle GET requests to a certain URL (@Path) ending in /hello, sending back plain text, HTML, or XML representations of "Hello Jersey". We could easily add JSON. It tells which one to send by the Accept header on the incoming request.
We could look at the firstRest/build.xml, which shows how wget can specify the Accept header, so we can request data in our preferred format. This server code can return plain text, HTML, and XML. We could similarly use curl to specify headers.Just remember that it is straightforward to implement Java web services with the help of JAX-RS.