Projects/Data Access Layer/CrudWebServices
Overview
The DAL layer will be made available to the outside world using a webservice layer. For the 2.50 release a REST Webservice will be supported. SOAP support will be provided in the 2.60 release.
Glossary
This document uses the term business object to denote an entity and its dependent information. A business object can be a simple entity 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. A business object structure always has one business object which is the owner of all the business objects in that structure, for example for a sales order the sales order header business object is the owner of the complete structure. Another way of describing this is that the order lines depend on the order header, i.e. an order line can not exist without its order header and when an order header is removed also the order line should be removed.
Some background information related to REST:
The REST concept was first described by Roy Fielding:
An overview article on REST with a lot of links to other material:
A quick intro into an example REST approach:
Some links related to REST versus SOAP, there is a fair amount of articles on the web on this topic:
Why REST?
There are a number of reasons why a REST approach makes sense for a data centric service: 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
DAL REST Webservice
It is important to note that REST is not a standard but more an approach or architectural style. The DAL REST Webservice adheres to the REST approach:
- resources (business objects) are identified by specific links which are stable over time
- the GET action is side-effect free
- all http actions: POST, PUT, DELETE, GET are supported
- http response codes are used to specify results of actions
Goals
The DAL REST webservice functionality should fullfill the following goals:
- provide a CRUD-like interface so that external applications can retrieve, update, create and delete business objects
- provide an api on which external UI technologies can be developed
- provide a base for supporting import and export functionality
To achieve these goals the DAL REST Webservice function needs to support the following operations:
- retrieve a single business object using a url which contains both the type as well as the id of the request business object
- retrieve a list of business objects using just the type, for example http://www.openbravo.com/dal/AccountingAcct
- querying, filtering, paging and sorting of lists of business objects
- updating 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 which submits a xml structure
- 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 objects
- retrieval of a list of id and identifier values, for example to fill a listbox in an external user interface
- delete operation using either a url pointing to a specific business object which needs to be removed or a XML document (in the content) which contains business objects (as full xml or as partial xml) which need to be removed.
DAL REST Servlet
A request will be processed by the DAL REST webservice servlet. This servlet will use the url to determine the type of request and how to handle it. The DAL REST Servlet will also handle login and authentication (see below). A request (GET, POST, PUT) can consist of three parts:
- the url path
- the url parameters
- the content of the request
A GET request will not have content and is completely controlled by the url path and its parameters. A POST and PUT request will have content which is assumed to be a valid xml document.
The response of a REST call will be an XML document, containing the requested data, a result XML message or an error XML message.
Single Request and Response
A single request is a request which points to one unique business object. For example the url: http://www.openbravo.com/dal/AccountingAcct/5 will return the xml for an instance of the AccountingAcct business object with id 5. The REST Webservice will retrieve this business object from the database, create XML for it and return the resulting XML. See below for a description of the XML.
Query Request and Response
A query url is used to retrieve a list of business objects. It can handle filter, sort and paging parameters. An example of a query url: for example: http://www.openbravo.com/dal/AccountingAcct?bpartner.id=5&orderBy=bpartner.name,locto.regionname&firstResult=19&maxResult=10. This url will return all AccountingAAcct objects which have a business partner with id 5, sorted by the business partner name and regionname of the to-location, the page starting at object 19 with 10 objects should be returned.
The REST query functionality should support the following parameters in the url:
- whereclause: a HQL whereclause
- orderBy: an orderBy definition
- firstResult and maxResult parameters for paging support
The user has three types of possible operations which can be performed by the query:
- select: this operation will query for the business objects and return (in XML) the properties of each of the business objects (this depends on security settings also)
- list: this operation will return the id, entityname and identifier properties of a business object
- count: this will return the number of business objects which are selectable according to the filter. This action is used for support of paged views.
It is still open if these operations are part of the URI path or are passed as a parameter.
Update/Create Request and Response
A business object can be updated/created through REST using the http POST or PUT command. The posted XML should adhere to the XML Schema generated by the REST Webservice (see below). With one exception, for update situations it is allowed to only include the changed properties in the XML.
The system will automatically check (by querying) if a business object is new or not. If no uuid is supplied then it will always be considered as new, if a uuid is supplied then a database query is done. If the uuid exists (for that type) in the database then the system will assume an update. If the uuid does not exist it is an insert, in which case the uuid (in the xml) is maintained.
If the update was successfull a success response is returned (<success/>), if it fails an error XML response is send back.
Remove Request and Response
The REST webservice will also support a delete or remove request. Delete requests use the http DELETE command. The Delete action expects a single URI pointing to the business object which needs to be removed.
Update multiple business objects Request and Response (Import)
The system should also support updating of multiple business objects which are passed in one file. The following aspects need to be taken into account:
- the xml file can contains mixes of new and existing (to-be-updated) business objects
- there maybe references to new business objects in the same xml file, these references use a unique uuid which may not exist in the database. This means that the import logic needs to internally (within the xml file) resolve object references before persisting the total xml file.
- the xml file can contain mixes of different types of business objects
The idea is that for updating/creating of multiple business objects in one call a specific URL should be used (for example http://www.openbravo.com/dal/import).
Business Object to XML
The XML response to a retrieval request consists of the data of the business object or business objects. The business object is translated to xml in the following way:
- The entity name is used for the tag name of the business object element. The entity tag/element also has attributes for the id and the identifier.
- The property name is used for the element name of each property. It depends on the security settings of the user which properties or information is returned (see security section).
Property values are xml-ished as follows:
- Date value is exported according to the XML Schema datetime format
- String value is exported as is (encoding is required)
- Numeric value is exported using decimal point and no grouping
- Reference (to another business object) is converted to an xml tag which contains the id, the entity name and the identifier value. This makes it possible for consumers of the XML to easily create hyperlinks to retrieve the data of the reference business object. The identifier can be used to generate a display of the reference.
The element used for the XML version of a reference is also used in case when lists of references need to be exported.
Overview of return messages in XML
The design discusses different functionalities. To summarize this section lists the set of return types which can be expected for different types of REST requests:
- a request for a specific business object will return a XML document with this business object
- a request (a query) for a list of business objects will return a XML document with the data of those business objects
- a request (a query) for a list of identifiers will return a XML document with the only the id, entity name and the identifier of each business object
- a query with a count parameter will only return a simple xml message with a count number (<count>5</count>)
- an update/insert request will return a success XML message (<success/>) if it succeeded
- a query with a identifier parameter will return a list of identifier values (one for each business object)
If the requests fails then the error XML message (see below) is returned.
HTTP Return Codes
The DAL REST Webservice uses the following error codes:
- 200 (OK): for successfull requests
- 400 (Bad Request): in case the uri could not be parsed or in case of invalid xml
- 401 (Unauthorized): is returned when a security exception occurs
- 404 (Not found): if the entityname does not exist or the if an individual business object is addressed, if the business object does not exist. Note that a 410 (Gone) response could also be applicable here but it is less know therefore the 404 is used.
- 409 (Conflict): is returned for a POST or PUT action, specifies that the data which was posted is out-of-date or invalid.
- 500 (Internal Server Error): if an unrecoverable application error occured.
Login and Security
The REST Webservice should provide a login method which makes it possible to directly login using a url. The following aspects play a role here:
- The login and context should be stored in a session for performance reasons
- Also every request can contain a login code which is resolved before the actual action is carried out. This makes it possible to login together with the actual request in one action. This last option is not preferred from a performance point of view.
To support webservice clients which do not support http sessions the REST service can support a local session cache which stores the context. When a client logs in the context is created and stored in the local session cache. The system returns a token as a response to the login action. The client can then use this token in subsequent actions. When the token is received then the context is retrieved from the local session cache and it is used. If the context is not present then the user has not logged in. It is not sure if this local session cache will be implemented in this cycle.
The REST webservice uses the standard DAL security control mechanism to control read and write access. The content of the returned XML depends on the read security settings of the user:
- if the user has no read access then a security exception is thrown
- if the user can only view the identifier information of a type then only the id, entity name and identifier properties are returned
- if the user can view the full business object then all information is returned
Non-updatable fields: Client, Organisation etc.
There are a number of properties for each business object which are not always changeable through the REST webservice:
- Client and Organisation: a webservice update of a business object may not change the Client and Organisation information. In creation mode the client may not be set, the organisation may be specified, if not specified then
- Update and Created audit fields: the update and created audit fields are not updatable/changeable through the webservice api.
XSD Schema Generation for REST approach
The DAL webservice should also generate a xsd schema on the basis of the runtime model. This xsd schema can be used by clients to easily identify which types can be queried. The XSD Schema should define the xml for all create, update and retrieve scenarios for single business objects as well as lists of mixed business objects.
Error Handling
When a request can not be processed and an error occurs an error XML document and the http response code 409 are returned. This error XML document only contains the error message.
Note that in a future release the exception should be logged using a unique id and then the id should be returned as an error code. This is the safest method which does not expose internal details to the outside world.
The stacktrace and other more detailed information is not sent out on purpose (because of security reasons).
Simple xslt templates
For demo purposes the dal will also have a number of xslt templates to translate the xml to lists and single display of a business object with click-through to referenced business objects.
Future
- Support queries which returns joins of business objects
- Support web service clients which do not have http session support by implementing an explicit session on the server. When a user logs in a token is returned which maps to the internal session.
- Support a depth parameter, this controls how deep in a parent-child structure the results should be returned. Is usefull when one-to-many assocations are supported in the Application Dictionary.
Test
The REST Webservice functionality is tested using junit testcases.
Category: Projects


