Represent messages in .proto files, package them as a separate jar, and ship it to target consumers of the service --which is basically the default approach I guess.
Do the same but also include hand crafted wrappers (not sub-classes!) around each message that implement a contract supporting at least these two methods (T is the wrapper class, V is the message class (using generics but simplified syntax for brevity):
public V toProtobufMessage() { //Build V from T }
public static T fromProtobufMessage(V message_) { //Build and return T from V }
public V toProtobufMessage() { V.Builder builder = V.newBuilder(); for (Item item : getItemList()) { builder.addItem(item); } return builder.setAmountPayable(getAmountPayable()). setShippingAddress(getShippingAddress()). build(); } public static T fromProtobufMessage(V message_) { return new T(message_.getShippingAddress(), message_.getItemList(), message_.getAmountPayable()); }
message ItemList {
repeated item = 1;
}
message CustomerInvoice {
required ShippingAddress address = 1;
required ItemList = 2;
required double amountamountPayable = 3;
}
message CustomerInvoice {
required ShippingAddress address = 1;
repeated Item item = 2;
required double amountamountPayable = 3;
}