In this post I will talk about new very exciting functionality in Openbravo 2.50: full REST web services support for all tables in the Openbravo datamodel (including the tables added by modules).
I will first start with a general overview and then some examples of web service calls which you can try directly in your browser. The post is concluded with a short description on how to add your own REST-like web services and a number of interesting links on REST.
Openbravo REST provides a CRUD-like interface so that external applications can retrieve, update, create and delete business objects through standard HTTP requests.
Some benefits of using a REST approach:
- favors identifying and addressing resources which fits to the data-centric nature of the provided apis (a resource corresponds to a business object)
- has actions (POST, PUT, DELETE, GET) which correspond to standard CRUD actions
- allows linking to specific business objects or to sets of business objects. This is a very powerfull feature of a REST approach and it allows for easy navigation between business objects.
- is simple to develop and use, and very lightweight from an architectural point of view
The Openbravo REST webservice operates on Business Objects in Openbravo. Before continuing let's first explain what a Business Object is (in Openbravo). A business object can be a simple entity (==table) such as a currency which just has basic primitive fields. On the other hand it can also be a structure of entities, for example an order header with its order line.
Openbravo REST web services provide the following functionality:
- retrieve a single business object or a list of business objects using a standard HTTP GET request
- querying, filtering, paging and sorting of lists of business objects, again through standard HTTP requests
- update of an existing business object or multiple business objects through XML and a HTTP POST or PUT operation
- creation of new business objects through a POST/PUT operation
- export and import of data: xml files which contain a mix of different types of business objects and a mix of new and existing business object
- delete operation using either a url pointing to a specific business object which needs to be removed or a XML document which contains business objects (as full xml or as partial xml) which need to be removed.
This functionality can be used for standard integration scenario's, but it can also be used to develop another UI on top of Openbravo using an alternative UI-technology (e.g. Flex).
The Openbravo REST web services use the same access/authorizations as the standard Openbravo application. Before calling a web service the caller must log in. The login functionality is provided by the Openbravo REST framework. All REST actions are then executed in the context of a client/organization and current role of the user.
Now let's go to some examples. When you have Openbravo running then you can try these out directly in your browser by entering the urls in your browser's address bar. Note that the examples assume that Openbravo runs locally on port 8080, it maybe necessary to replace the localhost:8080 part with your own server name/port. The examples assume that the web service user has access to the Country and Currency tables.
http://localhost:8080/openbravo/ws/dal/Country- Get a specific Country (in this case Spain):
http://localhost:8080/openbravo/ws/dal/Country/106Note that the xml returned contains both the Country and its children (Regions), i.e. a business object structure.
- An ordered example, query for all countries and return them ordered by ibanCode and regionName:
http://localhost:8080/openbravo/ws/dal/Country?orderBy=iBANCode,regionName- The same example with paging, returns 10 Countries starting from the 19th:
http://localhost:8080/openbravo/ws/dal/Country?orderBy=iBANCode,regionName&firstResult=19&maxResult=10- Do some filtering, only return countries which have a Currency with id 102 and a iBANLength of minimum 23:
http://localhost:8080/openbravo/ws/dal/Country?where=currency='102' and iBANLength>=23(the where parameter can contain a
Hibernate Query Language where clause)
After trying some examples, the next question is which web services are provided by Openbravo, i.e. what url's are valid, what are the entity names and XML property names, what is valid xml? To answer this question Openbravo REST has a special web service which can be called. This web service generates a XML Schema of the available business objects and their elements (including the tables added by custom/external modules). You can try it yourselve on your local running Openbravo instance:
http://localhost:8080/openbravo/ws/dal/schemaThese first examples only retrieved data. The REST web services also have update/create/delete functions. To support web service testing, Firefox has a nice add-on:
Poster. This add-on allows you to POST/PUT XML to a URL. For these examples I again assume that you have Openbravo running locally. I will be creating a new currency, updating its precision and then deleting the currency.
Here is an example of xml which can be used to create a new Currency:
<?xml version="1.0" encoding="UTF-8"?>
<ob:Openbravo xmlns:ob="http://www.openbravo.com">
<Currency>
<active>true</active>
<iSOCode>OBD</iSOCode>
<symbol>€</symbol>
<description>Openbravo Dollars</description>
<standardPrecision>2</standardPrecision>
<costingPrecision>4</costingPrecision>
<pricePrecision>4</pricePrecision>
<currencySymbolAtTheRight>true</currencySymbolAtTheRight>
</Currency>
</ob:Openbravo>
You can easily create this xml by retrieving a Currency through a url (for example, the
euro) and then removing the XML parts related to id, client/organization and audit info.
Click on the Poster icon (right-bottom in Firefox) and set the options as displayed in the image below.
Note that the xml (displayed above) is entered in the Content field, the Action is set to POST and the User Auth. fields contain the login and password. The user must have permissions to create a Currency. The standard Openbravo demo user has these capabilities.
Then click on the first GO button, you should be seeing the following result:
This xml gives a success message but more importantly it also gives the id back of the newly created object. This allows software, making REST calls, to use this id in further processing. In our case we can use this id to check if the currency was indeed created (note replace the id in the url with the id you received back):
http://localhost:8080/openbravo/ws/dal/Currency/FF8081811FA6E26B011FA6EA2E9C0002
Now as a next step let's update a field of the new Currency, in this case the precision is changed. The image below shows how this is done. The xml only has the field which needs to be updated and the id of the Currency is present as an xml attribute (to try-this-at-home, replace the id value with the one created in your case).
And to clean up let's delete the new currency. This is done with a DELETE action, the url of the action needs to point to the business object which needs to be deleted (in this case the Currency created above).
The above actions can be performed for all of the 425+ tables in Openbravo. More importantly REST webservices automatically work out-of-the-box also for new tables added by modules.
The delete action concludes the quick overview of the capabilities of Openbravo REST Webservices. The overview hopefully showed how easy it is to use REST webservices. Software talking to REST webservices need basic xml processing capabilities but that's the only real prerequisite.
The Openbravo REST framework can be extended with new Webservices. See
here for more information. Openbravo REST takes care of security and exception handling. Web services can be added (installed/uninstalled) as part of a module.
For more information:
- REST Webservice Technical Design
- REST test cases can be found in the openbravo development project in the src-test folder and then in the org.openbravo.test.webservice package
Here are some other interesting (non-Openbravo) links:
Some links related to REST versus SOAP, there is a fair amount of articles on the web on this topic: