Contract-First Service Development

Aaron Skonnard has written two very interesting articles (article 1, article 2) on contract-first (web) service development. The articles refer to .Net and the ASMX web services toolkit.

WSDL-first (where the developer writes the WSDL first, then generates stubs and implements the code of the service using the generated stubs) is the most pure way of web service development since the developer concentrates on the format of messages and on message exchange patterns. Also WSDL-first is the best way to achieve interoperability. Unfortunately it is not usually the most productive. This is because both WSDL and XSD are complex standards and are hard to write manually.

WSDL-first is not the only way to do contract-first service development. You can create an interface, produce the WSDL from that interface and never change it (keep it immutable). This way the WSDL produced will always be the same and you get away with the versioning problems. You can change the implementation of the service by changing the class that implements the exposed service interface without changing the interface.

Similar techniques are used in object oriented system where in some languages, like Java, changing an interface breaks binary compatibility (see Evolving Java-based APIs). In these cases techniques like numbered interfaces are used to overcome this limitation.

The major benefit from this approach is productivity. Coding interfaces in statically typed programming languages is easy and when you specify the web service related metadata with annotations you can create a web service very quickly.

This way is used by Steve Swartz in his “Introduction to Indigo” MSDNTV episode to develop a simple web service using Indigo. In Java we have JSR-181 web service annotations that can be used to expose classes and interfaces as web services. You can find a stable JSR-181 implementation at Apache Beehive.

Below I implement the web service that Steve Swartz implemented in “Introduction to Indigo” MSDNTV episode in Java with JSR-181 annotations.

Define an endpoint with an interface + annotations:

import javax.jws.WebMethod;
import javax.jws.WebService;

@WebService(
  serviceName="IMyService",
  targetNamespace="uuid:12341234-1234-1234-1234"
)
public interface IMyService {

  @WebMethod
  public String mangle(String s);
}

and then implement the interface:

import javax.jws.WebService;

@WebService(endpointInterface="IMyService")
public class MyService implements IMyService {

  public String mangle(String s) {
    char[] chars = s.toCharArray();
    //We don't have Arrays.reverse() in Java
    int offset = chars.length - 1;
    for (int i = 0;  i < chars.length / 2; i++) {
      char c = chars[i];
      chars[i] = chars[i + offset];
      chars[i + offset] = c;
      offset -= 2;
    }
    return new String(chars);
  }
}

Please note that AFAIK MyService does not have to implement IMyService and that the endpointInterface member inside the @WebService annotation is the construct that creates the link between the service and its implementation.

Of course interface-first isn't perfect either. The developer is creating a web service while dealing with methods, parameters and objects so the web services produced might be more object-centric (introducing interoperability problems) than required. The first of the above articles has a really good discussion on when to use WSDL-first and when code-first (expose a class not an interface) that has some information that also apply to WSDL-first vs interface-first.