Wednesday, January 14, 2009

Service Coupling - Service Interface evolution impact

Service providers should consider potential service consumer needs when coming up with service interfaces. However evolution of service interfaces is a fact of life we all have to contend with eventually. In an enterprise SOA, service providers and consumers are very much under enterprise SOA goverance and there are specific things which can be done, to minimize the pain of service consumers having to change with evolving service interfaces. Let us consider this problem through the example of the following Employee Information Service which has the following interface
public interface EmployeeInformationService {
    List getEmployeeInformation(Employee request);
}

class Employee {
    private long id;
    private String name;
    ...
    ...
}


1. A key thing in above interface is that the employee service's domain class Employee is exposed to consumers. To avoid this it would be desirable to wrap up the class in service integration abstractions like EmployeeInformationRequest and EmployeeInformationResponse

public interface EmployeeInformationService {
    EmployeeInformationResponse getEmployeeInformation(EmployeeInformationRequest r);
}

class EmployeeInformationRequest {
    private long requestId
    private String requestStatus;
    private Employee employee;
    ....
}

class EmployeeInformationResponse {
    private long responseId
    private String responseStatus;
    private List employee;
}



2. Even on the service consumer end, coupling between the service interface and the consumer's application logic can be greatly minimized using a consumer specific ServiceClient interface. In addition a object mapping tool such as dozer can be used to map attributes between consumer classes and service classes, declaratively. More about dozer


3. A key thing about reducing coupling is not the mere use of above abstractions but rather a conscious use of only the bare minimum, functionally necessary service interface attributes in the consumer. This judicious neglect of unrequired service object attributes by a consumer is what increases the consumers resilence to changes in service interface

For example if the Employee class in service interface contains 20 atttributes but our consumer needs to know only about 4 attributes then the consumer side classes should be aware of only 4 Employee attributes and mappings to translate to and from equivalent Employee attributes

The whole idea being that if Employee existing attributes were changed or deleted in the provider, unless the same were being used by our consumer, our consumer would be unaffected by the change.

Summary: Often in SOA implementation, providers communicate through XML messages and expose XSD schemas for message structures. This is equally applicable for SOAP based or Plain Old XML(POX) message exchanges. Here consumers often imnport the entire XSDs exposed by the provider and also do XSD based validations.

These consumers needlessly couple themselves to provider interface, instead consumers should do "just enough" validations and also "be aware of" minimum information being sent by the provider.This will go a long way in promoting reduced coupling between providers and consumers, and will allow provider interfaces to evolve with minimal impact on consumers