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.
Manual configuration
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.
HTTP OPTIONS
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.
Conclusion
The REST adapter
Although this is the first Oracle SOA 12c release, I’m impressed with what Oracle managed to accomplish with (of course among other things) the REST adapter. It introduces a lot more flexibility for integrating services of different kinds. For example, direct integration with usually Javascript based front-ends becomes a lot easier this way. For classic XML developers, REST and JSON might be a bit getting used to at first. It is a good idea to familiarize yourself with them if you not already have since the architecture and the message exchange format are gaining popularity. JSON is benefiting from the popularity of Javascript and Javascript frameworks which are commonly used to achieve rich client interfaces (AngularJS for example). JSON is usually easier to use in Javascript and less verbose (requiring less bandwidth to transport) then XML. Using less bandwidth is useful for the communication between mobile devices and backend servers. The constraints which are posed by the REST architectural style, allow loose coupling of client/server, scalability and other feats. These are becoming more and more important as IT landscapes grow in complexity. With this REST and JSON support, Oracle SOA Suite has made an important step forward.
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.
a big thanks for me bro, i’ve been strugling for daaaaays. i put JSON as input but my output always give me xml, i try many header, Content-type, Media-Type, Response, but nothing works until i found this. keep it up your work truly helping.
HI Maarten,
Thanks a lot for the blog I have followed and practiced it,
how can I add basic authentication security policy to a restfull service in 12c.
I have gone through multiple blogs but my problem is
My webservice requires me to send basic credentials with “authenticate-pre-emptively” property set.
can you help me here
Thanks a lot In advance
harsha
Hi Maarten, I am trying a use a tab separated(tsv) using REST adapter. It returns stating Unknown media type : text/plain. I tried to set the property in invoke rest.binding.http.Content-Type as text/plain. Still the same issue Any suggestions please ?
Thanks,
Revathi
Did you solve that issue?
This issue will not get resolved until Oracle adds support for that media type. See this note from Oracle metalink
SOA 12c: Support for Rest Services additional media types (Doc ID 2013265.1)
Initial release of SOA 12c has support for the following Media Types:
application/xml
application/json
application/x-www-form-urlencoded
Through Patch 19580101, the following were added:
application/xml+atom
application/atom+json
Infact somebody logged a bug too
Bug 21518838 : Call to REST based service results “Unknown media type : text/plain; charset=utf
And oracle closed it saying its not a bug, they just dont support it…how convenient 🙂
Then what would be the solution for it.
can anybody suggest me some solution
Hi Maarten
You have mentioned that it is not possible to set the http proxy from the console for REST services. So, how can I set the proxy host and port for a REST adapter call? I have tried it from the composite.xml by setting the binding properties but it doesn’t seem to work.
Kindly help. Would really appreciate any kind of help.
Regards
Gaurav
Hi Gaurav,
I have not seen a way to directly allow the REST adapter to use an HTTP proxy. You can however use the Service Bus to achieve such functionality. See for example: https://blogs.oracle.com/knutvatsendvik/entry/using_proxy_server_with_osb
You can also configure a proxy serverwide: https://docs.oracle.com/cd/E53672_01/doc.111191/e53673/GUID-36A18CFA-55F1-4D19-B371-A6D15EBF2E24.htm
I hope this helps you,
Regards,
Maarten
Maarten,
Thanks, you saved me a lot of time with the accept application/json tip. Other rest services don’t have that problem (e.g. the out of the box BPM rest services). There might be some additional properties we need to set? Or it is a bug in the adapter…
Any thoughts on that?
Cheers
Lonneke