This technique of starting with a web service contract definition is at the heart of the ‘contract-first’ approach to service-oriented architecture implementation and has numerous technical benefits including…
- Positive logic-to-contract coupling (because the implementation code follows the contract).
- Positive consumer-to-contract coupling (because the consumer couples to the contract).
- Avoids contract-to-implementation coupling (where the implementation influences the contract).
- Avoids contract-to-technology coupling (where the consumer becomes dependent on the implementation technology).
I don’t want to go on about contract-first SOA, but it is really important. In fact it’s the only method allowed by some web services frameworks such as the well respected Spring Web Services. Springsource’s reasoning for only supporting the contract-first method is explained in great detail here.
The business case for my service.
I’ve decided to implement a web service for managing ‘Product’ entities which I’m going to refer to as the ‘Product Entity Service‘. Product information management (or PIM for short) is a very common business activity and therefore, my entity service should have lots of re-use potential. I personally know this is true because of my previous retail and defence logistics experience, but if I wanted to prove this to be the case, I’d normally analyse the business processes and look for all the places where product information is of benefit. If I did that I’d probably find that the following business processes would be potential consumers of the Product Entity Service (in a traditional retail setting for example)…
- Buying, product purchasing and on-boarding
- Sales order capture
- Sales order fulfilment
- Customer service
- Catalogue production
- Business-2-Business enablement
- etc. etc.
My Product Entity Service’s Operations.
Because I’m creating a service that is purely tasked with managing the Product entities, I’m going to keep the operations quite rudimentary. My service will offer consumers create, read, update, delete and find operations. The service will be a SOAP based web service with a WS-I interoperability certificate to help ensure cross platform compatibility with a wide range of consumers. I may, at a later date, also offer a REST version of the same service (often referred to as the concurrent contracts pattern).
My service consumers (possibly other services or processes) can then do with these Product entities whatever they like, for example by offering more business aligned features to support Product work-flows such as ‘approve’ or ‘discontinue’.
My service contract will be described using the Web Services Description Language (WSDL). I tend to hand craft these and then check them against the WS-I basic profile to make sure I’ve created an interoperable contract. WSDL’s are not particularly friendly files to work with, but any good SOA architect should be able to write one in my opinion.
The Product Entity’s data model.
A Product data entity should be capable of describing a real life Product that is of value to the business. Every business has its own ideas of what exactly this data item should contain, so in order to keep it simple I’ll just define a few basic fields such as id, name, description, manufacturer, category, and size. I’ll also add some housekeeping fields such as version, date created/updated/deleted, etc. It’s best to think of this data as a ‘document’ as both SOA and NoSQL definitely benefit from a ‘document-centric’ view of the world.
The Product document will be described using XML Schema (i.e. as an XSD). I also tend to do these by hand and I use lots of modularity in the structure to help support the schema centralisation pattern which fosters reuse and interoperability amongst the data models used in SOA. This technique is often referred to as creating a ‘canonical data model’ that describes all the business entities within one central model.
Creating the Java Service.
Now that the service contract is complete, I’m ready to create my maven project and begin the implementation of the service. To do this I use the latest Netbeans IDE because it has great wizards for starting Maven projects and importing WSDL’s for implementation. Maven helps with code compilation, packaging, deployment and testing as well as managing dependencies and performing code generation for my services. Both of these tools are free.
The WSDL importing process creates a Java interface that represents and reflects the service’s contract. It also creates a set of Java objects that represent the XML structures used by the service as messages. These objects are annotated by the import routine using JAXB annotations. JAXB offers ‘marshalling and unmarshalling’ of XML text into Java objects. This happens invisibly behind the scenes as part of the JAX-WS web services framework.
All I have to do now is create an implementation of the methods on the service. In the first instance I simply add some basic boilerplate code just to get something working. Once that’s done you I deploy the service to a server and do some basic integration testing to check it’s all hanging together and that the service endpoint is being exposed as intended. The server I use for this is Glassfish 3.1 from Oracle which can be integrated within Netbeans and is also free.
Initial Service Integration Testing
I use SOAP UI for my service testing because it’s free and very capable. It can be used as a testing tool for almost any SOAP or REST service, and using a test harness like this will prevent me from having to build a working service client which can be quite time consuming.
I should mention that service development can be done in a completely test driven way with SOAP-UI but at the very start it’s easier to have a basic service deployed (even if it doesn’t work) just so that you can grab it’s WSDL from it’s endpoint using the “http://service?wsdl” convention and check that everything is deployed and integrated correctly. If I didn’t do this, I could get started just with the WSDL, but the endpoint location wouldn’t work so tests would fail not because of bad logic but because of a general lack of service availability.
I’m now able to create basic tests which pass Product messages backwards and forwards successfully between the service implementation hosted locally on Glassfish and the SOAP-UI test client, even if those messages don’t do anything and the Products they contain don’t get persisted yet.
The next stage is to begin the CouchDB integration so that the Product messages can be persisted and retrieved from the NoSQL database. Then, between the service and the CouchDB DAO I’ll add any business logic that I need to make it all behave as it should.
Subscribe now to get an alert when I start the CouchDB DAO. If you missed Part 1 of this diary series you can catch-up here.
Costs so far:
- Software – £0.
- Time – 2-to-8 hours (depending on experience).
Reference: Implementing Entity Services using NoSQL – Part 2: Contract-first from our JCG partner Ben Wilcock at the SOA, BPM, Agile & Java blog.