In my previous two blog posts I have described REST (here) and how the new Oracle SOA Suite 12c REST adapter can be used to call RESTful services (here). I recommend those articles to be read first if you’re new to REST in order to better understand this article.
The newly introduced Oracle SOA Suite 12c REST adapter provides options for calling RESTful services but it can also be used to expose RESTful services. These exposed services can use XML or JSON as message exchange format. As described in the previous blog post, JSON support is implemented by implementing NXSD (Native Format Builder schema definition files, more information here) to describe the JSON message and make the transformation to and from XML possible. This XML can then be used as usual by the different components in a composite.
Exposing a RESTful service
In order expose a RESTful interface, the REST adapter provides several options. See the image below. A component or external service can be exposed. An interface can also be defined manually. If you just want to expose an existing service in a RESTful way, it might be better to consider an implementation in the Service Bus or for example custom Java code. If however the service hides a complex orchestration, you can consider using a composite with for example a BPEL component.
In this example, I am going to configure the REST adapter manually. This also is the only option I have currently seen for providing an interface returning JSON. As already described in my previous post on the REST adapter, the request can be configured to accept template or query style parameters (see http://www.soapui.org/REST-Testing/understanding-rest-parameters.html for more information on REST parameters). I have created a simple synchronous HelloWorldREST BPEL process similar in functionality to the SOA Suite 11g example I’ve created a while ago. The SOA Suite 12c example, using the REST adapter, has become a lot less complex and more readable (thus I expect less questions on this one). Since the example is that simple, I will not provide the sample code since it will contribute little. The process consists of a receive (creating a new instance), an assign and a reply. The assign puts ‘Hello ‘ in front of the input.
Going through the wizard is, as we’re used from Oracle, easy enough. Because the low level of complexity, I will not get into much detail here providing many screenshots of it and will mostly describe what you will get once you’re done with the configuration and provide some implementation tips.
Since a REST service can have a complex URL, the wizard provides an option to obtain a sample URL for a resource or operation. JSON support by the NXSD framework has already been described in my previous blog post.
After deployment of the service, things get more interesting. A RESTful service should adhere to several architectural constraints. See my blog post on this here. For example, a REST service should be self-descriptive. How is this accomplished with the REST adapters REST implementation? Actually in several ways.
The below screenshots are taken from SOAP UI. SOAP UI is useful for testing the service and generating requests. SOAP UI can also read WADL files and generate sample requests based on that. When the service URL is called with the HTTP OPTIONS verb, valid HTTP verbs are returned. See for more explanation of the HTTP OPTIONS verb http://zacstewart.com/2012/04/14/http-options-method.html. The Java JAX-RS framework also uses the HTTP OPTIONS verb in a similar way.
If you allow XML to be returned (‘Accept: application/xml’ HTTP header, I will get back later on this), you even get a complete WADL.
A WADL is to a REST service what a WSDL is to a SOAP service; an XML description/definition of the service/application. This WADL can be used by for example Java frameworks to automatically generate a client for you (see for example https://wadl.java.net/wadl2java.html). Oracle speeds up development of clients against RESTful services by providing this functionality. Some software vendors who provide a RESTful interface neglect to provide a WADL for their services (it would not be very polite of me to mention examples of them here) making client development a more cumbersome process. Luckily, Oracle values developer productivity.
Enterprise Manager support for WADL’s
In the Enterprise Manager test console, you can use the WADL to generate the request. This can be used for JAX-RS / Jersey services but also for our newly generated REST HelloWorld service.
For a newly generated REST enabled composite, this works the same;
Calling the service using an external client
To be honest, this was the hardest part. My first tries ended in this… (the response didn’t look very JSON to me even though I had specified it in the wizard)
I usually use the JDeveloper HTTP analyzer (see for example http://docs.oracle.com/cd/E16162_01/user.1112/e17455/aud_prof_test_apps.htm) to analyze a working request. The HTTP analyzer can be used in two ways. Create a request in JDeveloper and use JDeveloper to test the request or use the HTTP analyzer as a proxy. Using the HTTP analyzer to generate sample requests didn’t work well for me (I prefer SOAP UI). Using the HTTP analyzer as proxy allows analyzing traffic (HTTP requests) passing through. For XML webservices it is possible to set an HTTP proxy to pass the request through. Since I already had an example of a composite calling another REST service, I thought I could use that. For composites calling REST services however, I have not found the option to set the proxy server so this didn’t appear an option.
I tried several things related to the Content-Type. I managed to overwrite it with the JCA property rest.binding.http.Content-Type but that didn’t help me getting JSON instead of XML as reply. After some struggling with this, Edwin Biemond suggested that the Accept HTTP header might help. I tried it and it did.
The REST adapter
When to use which adapter
If you want to accept plain XML, you should use the HTTP adapter. If you want to accept SOAP, you’re better of using the SOAP adapter. Currently I have not yet looked at which adapters can use NXSD to translate XML to a ‘native’ format. I haven’t even mentioned the SocketAdapter yet which can be used to provide more low level communication. When using the SocketAdapter however, you will need to do a bit more yourself such as writing Java (see http://javaoraclesoa.blogspot.nl/2013/01/a-json-helloworld-bpel-process.html) or complex NXSD (see http://javaoraclesoa.blogspot.com/2012/12/receiving-json-requests-in-oracle-bpel.html) to provide functionality.
Food for thought. Exposing a CSV file
I’ve played with the thought of exposing CSV files created by/based on a REST request. NXSD can be used to describe more then JSON. A CSV file can also be described using an NXSD. When I understood the usage of the Accept HTTP header, I became less enthusiastic about this. Most likely it will not be easy (or even possible without using creative methods) to implement with the REST adapter. The client specifies what it accepts as a response. This allows the REST adapter to provide XML and JSON responses with the same adapter configuration while responding with the right format as the client requests. When however I want to return something which the wizard doesn’t allow me to select or the REST Adapter doesn’t support by default, the request isn’t accepted.