DTO interfaces for implementing web service integration

Posted on

Problem

I am trying to define some interfaces to implement some web service integration middleware.
The SOA pattern that fits this system is probably the Multi-Channel Endpoint.

I expect a lot of mapping of data formats happening in this integration so I am trying to come up with some interfaces to implement this.

For each web service client I would like to provide a Service Facade that will map the input data to a common data structure (DTO) that will then be interpreted by the middleware which will orchestrate the services that connect to the legacy applications.

My attempt at coding the interfaces goes like this:

// Protocol for mapping POJOs to some Map-like data structure
public interface Dto {

    // Map from POJO fields to DtoData
    public DtoData toData();

    // Map from DtoData to POJO
    public void fromData(DtoData data);

}

public class DtoData {
    Map<String, Object> data;

    public Map<String, Object> getData() {
        return data;
    }

    public void setData(Map<String, Object> data) {
        this.data = data;
    }
}

// This class provides default mapping methods from POJOs to Maps.
// Uses Jackson and Dozer for mapping back and forth between objects.
// TODO use DI to create mapper objects.
public abstract class AbstractDto implements Dto {

    @Override
    public DtoData toData() {        
        ObjectMapper mapper = new ObjectMapper();
        DtoData map = mapper.convertValue(this, DtoData.class);
        return map;
    }

    @Override
    public void fromData(DtoData data) {
        DozerBeanMapper mapper = new DozerBeanMapper();
        mapper.map(data, this); 
    }

}

public class DtoImpl extends AbstractDto implements Dto {

    private DtoData dtoData;

    public DtoData getDtoData() {
        return dtoData;
    }

    public void setDtoData(DtoData dtoData) {
        this.dtoData = dtoData;
    }

}

Any suggestions on how to improve this and pitfalls that I can expect?

Solution

I am not sure I understand what’s the reason of your Dto and of its AbstractDto and DtoImpl implementations. Why does it need to hold a dtoData instance?
I think that you should separate the definition of Dtos, the definition of DtoData and the definition of a Mapper that translates between the two representation.

I think you should’t really have a Dto interface or leave it to be just a marker interface, but I don’t really like them as they are usually an anti pattern.

I don’t like that you pass directly a Map to your DtoData. What about something implementing this (very Map-like) interface?

interface DtoData
{
    void setValue(String key, object value);
    void getValue(String key, object value);
    Set<String> getKeys();
}

Finally all the conversions should be handled by a Mapper, implementing this interface.

inteface Mapper
{
    Object toDto(DtoData dtoData);
    DtoData toDtoData(Object dto);
}

If you organise your program in this way you have different pieces that cover different responsibilities and it should be trival to change format of DtoData and the way you map them.

One possible improvement over that would be to let the compiler help you putting everything together in the right way. You can do that by rewriting Mapper such that it is generic. Something like Mapper<T,K>.

Leave a Reply

Your email address will not be published. Required fields are marked *