Title: WSDL 1.1 Extensions for REST
Category: documentation
## Overview
The [Resource-Oriented Architecture](http://en.wikipedia.org/wiki/Representational_State_Transfer) defines four concepts:
1. Resources
1. Their names (URIs)
1. Their representations
1. The link bet ween them
and four properties:
1. Addressability
1. Statelesness
1. Connectedness
1. A uniform interface
HTTP binding as defined in WSDL 1.1 is not well suitable to describe services implementing these concepts and properties, mainly because a port type may access 4 different locations/resources but with only one HTTP method.
To better describe RESTful services, and turn a port type into a "resource type", ODE brings a set of 4 extensions:
1. one HTTP method per operation (instead of one per binding)
1. a unique URI Template for all operations
1. access to HTTP headers
1. fault support
Further details below.
In this page, we use an imaginary blog service as a use case to illustrate and make things more palpable. We will focus on the resources defined by the following URI template: `http://blog.org/post/{id}`
Let's assume that such a resource accept four operations:
* GET to retrieve a post
* DELETE to delete it
* PUT to update the post
* POST to add a comment to a post
Check out unit tests!
### One verb per operation
According to the WSDL 1.1 specification, the verb describing the HTTP method has to be at [the binding level](http://www.w3.org/TR/wsdl#A4.3). Which implies that the same HTTP method is used by all operations of a given port type. But RESTful web services leverage HTTP methods as a uniform interface to describe operation on resources. So for instance, if you want to use the following HTTP operations -- GET, POST, PUT, DELETE -- for a given resource, four different bindings would be required. And consequently four port types and four ports. Quite verbose and unusable, isn't it?
So, this extension is to push down the HTTP verb at the operation level. And if an operation does not have its own verb, then the verb defined at the binding level will be used.
This extension is declared in the namespace: `http://www.apache.org/ode/type/extension/http`
Please note that ODE supports GET, POST, PUT, DELETE only.
:::xml
### URI Template
A RESTful service exposed a set of resources, each of them being accessible through a uniform interface: HTTP methods for a web service. So we need a way to define four operations (at most) for a single resource.
Moreover it's very likely that the resource URI actually describes a set of resources. For instance, the set of posts contained in our imaginary blog: `http://blog.org/post/{post_id}`.
HTTP binding offers the [http:operation ](http://www.w3.org/TR/wsdl#_http:operation) element to set the path of an operation. While the service address is set in the [http:address](http://www.w3.org/TR/wsdl#_http:address) of the [wsdl:port](http://www.w3.org/TR/wsdl#_ports) element.
So one could imagine splitting the URL this way:
:::xml
However, here 3 issues show up:
* the location is not accessible from the End Point Reference. _=> ODE cannot process it before invoking the external service._
* [http:urlReplacement](http://www.w3.org/TR/wsdl#_http:urlReplacement) is only accepted for GET _=> what about the uniform interface?!_
* http:urlReplacement requires all parts of the operation input message to be mentioned in the operation location. Meaning that:
* => the resource id (in the present example) must be a part of the message.
* => no parts may be stored in the HTTP body. this conflicts with a PUT operation for instance. With a PUT you would like to set the id in the url and the resource data in the HTTP request body.
To solve this, ODE allows [http:operation](http://www.w3.org/TR/wsdl#_http:operation) elements to be omitted or empty, and the full resource URI to be set in a single place, the http:address element.
In addition, the http:urlReplacement is relaxed: all parts are *not* required in the URI template anymore. One part could go in the URI, another in the request body.
:::xml
### HTTP Headers manipulation
HTTP protocal convey a lot of information in Request/Response Headers. Caching information, Content description for instance. All this data is completely left out by WSDL 1.1 HTTP Binding. To fix this, ODE provides a header element. This element can be used to insert a part or a static value into a given HTTP request header (standard or custom). And the way around, a HTTP request header into a part. Also note that all HTTP response headers are inserted into the message headers, and thus are available from the BPEL process.
:::xml
For every HTTP response, in addition to HTTP response headers, the [Status-Line](http://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html#sec6.1) is passed as a message header. To save some painful XPath string manipulations, the Status-line is already parsed into the following structure:
:::xml
HTTP/1.1200OKHTTP/1.1 200 OK
So that you can write the following BPEL lines:
:::xml
$statusLinenumber($statusLine/Status-Code) > 200 and number($statusLine/Status-Code) < 300'Request successful!!!'$outputVar.TestPart
### Fault Support
Another domain completely neglected by WSDL 1.1 HTTP Binding is Fault management. The word is not even mentioned in the [HTTP Binding section](http://www.w3.org/TR/wsdl#_http).
ODE allows you to bind a fault with HTTP Binding. If a [4xx or a 5xx](http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4) is returned, the following logic is applied:
A failure is thrown if the code is one of these:
Status-Codes triggering a Failure
3xx Redirections
401_UNAUTHORIZED
408_REQUEST_TIMEOUT
503_SERVICE_UNAVAILABLE
504_GATEWAY_TIMEOUT
Note that 3xx errors should be pretty rare since by default the first hundred redirections are followed. You can tweak this value by setting the property http.protocol.max-redirects in the enpoint-configuration.properties of your process.
Here what ODE does, if the status code is one of those listed in the next table (500, 501, etc):
* check that the operation has at least one fault in its abstract part, and one fault binding
* check that the Content-type header describes an xml document ('application/xml', 'application/atom+xml' etc)
* check that the body is not empty
If so far everything is fine, the HTTP response body is parsed into an xml document. Then the fault to be thrown is inferred from the qname of the response root element, i.e the fault having a message part matching the root element. This matching process is exactly the same as for a SOAP service.
If one of these steps fails, a failure is thrown.
Status-Codes that may trigger a Fault
if the body element matches a fault declaration
500_INTERNAL_SERVER_ERROR
407_PROXY_AUTHENTICATION_REQUIRED
501_NOT_IMPLEMENTED
409_CONFLICT
502_BAD_GATEWAY
410_GONE
505_HTTP_VERSION_NOT_SUPPORTED
412_PRECONDITION_FAILED
400_BAD_REQUEST
413_REQUEST_TOO_LONG
402_PAYMENT_REQUIRED
414_REQUEST_URI_TOO_LONG
403_FORBIDDEN
415_UNSUPPORTED_MEDIA_TYPE
404_NOT_FOUND
411_LENGTH_REQUIRED
405_METHOD_NOT_ALLOWED
416_REQUESTED_RANGE_NOT_SATISFIABLE
406_NOT_ACCEPTABLE
417_EXPECTATION_FAILED
Note that you can't bind a given fault to a specific status code.
:::xml
...