Skip to end of metadata
Go to start of metadata

In this post I will describe how to do contract first in a very simple and efficient way. All people involved in webservice design have the problem what tool to use to describe the webservice interface. Of course there are wsdl editors but you can make many errors in using them and they are normally not very intuitive.

What we would like to have

Ideally I would imagine to have a domain specific language that makes designing the webservice very easy and fail safe. Then there should be an IDE that supports me in writing the DSL. Either with content assist or with a graphical editor. In any case the IDE should check the DSL while it is entered and help me to do the right thing. Some people favor using Model Driven Design tools to do this job but it is quite hard finding good tools and configuring them for the job.

Which tools did I choose and why

I wanted to go some way in the direction of a DSL for webservices but without using a big MDD tool. So I thought about how to have most advantages of a DSL with just Java and the normal Eclipse IDE. So I needed Java code that looks almost like a DSL and a tool to generate the webservice out of it. For the WSDl generation I used Apache CXF with JAXWS and JAXB annotations to describe the webservice. While this setup is quite standard I focused on keeping the syntax as simple as possible.

So how does the DSL look like

To describe a data object I use a java class with just attributes. The Namespace will come from the package name. To make JAXB understand this syntax only one annotation is necessary. Of course some more annotations are necessary if you want to use special fetaures.

Customer datatype

The sample class Customer gives a nice overview which primitive datatypes can be used. Additionally you can create arrays of primitive or class datatypes in this way. The complete example also contains an enumeration definition to show this is possible. I think this code is quite near the DSL I would imagine to describe my services.

Enumeration CustomerType

Shows how enumerations are handled:

NoSuchCustomerException

 Defining Exceptions is a little tricky as the default behaviour is to create Exception_Exception classes in the later generated Java code. So we have to use the @WebFault annotation to give the Bean for the data a name that is separate from the Exception name.

Service definition

As you can see only two annotations are necessary here. @WebService marks the interface as a service and @Webparam is necessary as Java will else loose the name of the parameter and the wsdl will contain arg0 instead of the desired name. Using the @WebService annotation you can also customize the port name and service name.

How is the wsdl generated

To generate the wsdl the maven plugin cxf-java2ws-plugin is used. See the pom.xml in the complete example for details.

Let´s take a look at the resulting WSDL

You can download the wsdl this example creates here.

The customer Class is a complex type in xsd. As you can see the Java types have been described as their respective XSD primitive types.

Each element has minOccurs="0" which marks it as optional. This is a good thing as you can add new optional elements and keep compatible. If you do not want this optionality you can use @XmlElement(required=true).

The array of Strings for address is described as maxOccurs="unbounded" so the element may be repeated in the later xml to form the array.

Enumeration customerType

The enumeration customerType is described as a simple type with a restriction:

Fault NoSuchCustomerException

The Exception we defined is generated as a complexType with the defined details and a message for the fault. It is important here that the Element and the Message have different names. We ensure this by using the @Webfault Annotation above. Else the later Java Code generation will produce an ugly Exception name NoSuchCustomerException_Exception.

The wsdl defines a SOAP/HTTP binding by default but can also be used to build services based on JMS as I will show in my next post.

Summary

As you can see the generated WSDL looks quite clean and correctly expresses the service interface we wanted to describe. In most cases where you are not satisfied with what the conversion does you can correct the WSDL using JAX-WS or JAXB annotations. But I recommend to use them sparsly to keep the DSL easy to read.

In the next post I will show ho to build service consumers and providers using the WSDL we just built.

You can download the complete example here.

References

13 Comments

  1. Anonymous

    I believe what you are doing is called 'Bottom Up' web services. Bottom up services are defined by a Java interface, which the contract (written as an XML schema which defines the XML messages) is then generated from. Whether you use CXF or Axis or whatever java2wsdl tool to generate the XML Schemas and bindings, you are first defining the code that will process the service and then defining the contract afterwards.

    For contract first development, no domain specific language is neccesary. The engineers/analysists defining the service should just create the schema of the input and output messages. It is not hard for people to write XML Schemas (the things that represent the contract) and there are lots and lots of tools to do so, which are imported into the WSDL. The xsd to WSDL importation is now done automatically (again, there are tools in Spring-WS and scripts elsewhere).

    1. I think what I do is stilll contract first as I use the WSDL to create Server and Client stub code. It does not really matter how the wsdl is created. Bottom up or Code first means you create the wsdl from your implementation or the interface you use in your code. This is not what I do.

  2. Anonymous

    Sorry Christian, but i'm with the first guy - this isn't contract first WSDL at all. Simple case in point - see the xs:restriction on the customerType, how are you going to restrict its length or content with a regex in the Java code?

     My advice to you would be to get a book like Thomas Erl's 'SOA Principals of Service Design' for a steer on this, or even check out the excellent write-up from the Spring-WS guys here (http://static.springframework.org/spring-ws/sites/1.5/reference/html/why-contract-first.html).

    I appreciate the sentiment about the tool support, it is poor, buy get a copy of XML Spy and you can't go far wrong.

    1. The idea is not to use things like restrictions. Of course there are nice things you can do with xml schema. But I do not think they are really necessary to define a service and the bear the risk of not working on some platforms.

      I have a question for you. What if I would use a model driven design approach to service definition. I would define my own dsl that allows to define a service. Then I would use a tool like Openarchitectureware to transform this dsl into wsdl. This is a clear case of contract first in my opinion. So I simply use cxf instead of a mdd tool and java instead of a custom dsl. Still this is contract first as I first define the contract and then the implementation. Please remember we are talking about contract first not about wsdl first.

      Another example is corba. There you define contracts in IDL. If you start with IDL and then generate code from it this is contract first. It does not matter if you write the IDL by hand or use a transformation to generate it.

      1. Anonymous

        Why not use restrictions? It is far easier to develop correct code when the schema informs you what the correct input is. For instance if your customerName is a minimum length of 5 letters and a maximum length of 15 then the information should be in the schema - not buried in your program code.  Even if validation is turned off in the production phase, it is extremely helpful during development.

        M. Gruen

        1. I have read an interesting article about this problem. In theory things like minimum or maximum letters seem to make sense in the xsd. The problem is though that they also need to be checked in the business logic when the method is called directly. Besides there are checks that can not be done in the xsd. So the better idea is to do most of the validation in the business logic. Still it should be declarative. There is a jsr about bean validation that handles this.

           In the mean time I have experimented how Class inheritance is mapped to xsd. This is one example where I made good experiences with restrictions.

  3. Anonymous

    Yes. This seems to be no point of calling this as contract first approach. i agree with "anonymus" using an xml spy or eclipse wsdl designer would be a better starting point.

  4. Anonymous

    I know ppl that come to this site are interessted in contract first ws,

    That is : define the xml (or xsd) that you want your service to handle., from that approch you write the ws to handle incoming xml and do business code and than build response message. 

    1. First define the xml

    2. Use Trang to generate xsd. (http://www.thaiopensource.com/relaxng/trang.html). , a cmd based tool to generate an xsd from xml files (as example). 

    3. From xsd generate wsdl by using spring-ws. 

    (But i dont how to do step 3 with apache cfx and spring ws)

    1. Anonymous

      That is : define the xml (or xsd) that you want your service to handle., from that approch you write the ws to handle incoming xml and do business code and than build response message. 

      1. First define the xml

      2. Use Trang to generate xsd. (http://www.thaiopensource.com/relaxng/trang.html). , a cmd based tool to generate an xsd from xml files (as example).
      I'm a rookie and and am severely lost at this point.  

      Why  would you xml then convert to xsd, then generate wsdl?

      What savings are there in complexity, syntactical size, or usability?

      I think the authors intention was that defining an API using java interfaces is a damn side simpler than wsdl editing, even with wsdl editors that never do the "right thing" when used in model mode. For example, try generate a method that takes no input params in the eclipse wsdl editor. You get error markers all over until you manually fix up the syntax. I think the need for something simple, like idl is missing from wsdl defined APIs and that this is a viable option.

  5. Anonymous

    Hi,
    I'm with Christian on this one. My company, by way of acquisition, had the need to integrate several disparate systems (Java, .NET, CRM systems) across most of Europe (meaning various spoken languages, also). Basically, our system, a web shop/catalog, needs to interrogate these remote systems in an implementation-neutral manner. We've tried documenting the required system behaviour, but somehow, the implementors always seem to do it differently (i.e. like adding/removing a parameters etc. etc.). So, we set about generating WSDL-contracts (i.e. contract first).

    Christian's idea of using our already existing Java code as a DSL, using annotations, has saved us IMMENSE time in documenting the many services, especially where semi-complex types are involved (i.e. Classes contain many fields and list/arrays etc.). Basically, we did not have to concern ourselves with the redocumenting the system, this was already in-place/inferred via the Java object model. We have successfully round-tripped our web services from Java (an annotated Interface definition), to a .NET web service, back into a Java client. This WSDL process is automated via CXF and Ant, and we use Spring/CXF to consume the resultant web service, meaning almost no code is written (the new external web service already conforms to our Spring-exposed interfaces).

    Just as a side note, we also use XSLT to remove the wsdl:service node from these 'contract' WSDL documents, as the Endpoint address is unnecessary as this will be furnished to us, from the implementor, after they have re-implemented the remote service.

    If you should need some code examples, feel free to contact Rich via sixman9 at RemoveThisNoSpam gmail.com.

  6. Anonymous

    I agree with Christian and the other supporters which I suppose begs the question that isn't an Interface a contract like a WSDL definition?  A contract represents supported functionality/behaviour regardless of the implementation, it just happens that a contract can be in the form of a Java interface or WSDL but either way it serves the same purpose.

  7. Anonymous

    Hi, Christian, i am using your tool to generate the wsdl from my business logic classes for a university project, i have tested your tool with a sample pojo and all go very well. But, now i hava java class with a metod that write a file xml on the filesistem, and to do this, in my eclipse project i have imported the xerces libraries to use the XMLSerialize class, now to generate my wsdl, i store my project's classes in the src directory on the right place in according to the package name, but when i do the command mvn install, maven shows build error because it can't find xerses library, no alone for this particular case, but also in general, how i can import the externals jars? I must transport the jars physically in to one directory? I must specify the dependencies to the local jars in the pom.xml? In this case, how i can do this? Sorry if my english is not very good, i am italian.

    1. Could you elaborate some more what you want to achieve? In the project that defines the webservice you normally will not need any external libraries as you only define the contract. In the implementation you could of course need external libs. In that case you specify the libs as maven dependencies then maven will load them from the repository and set up your classpath.