Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Protocol buffer and OO design

Tags:

I'm using protocol buffer as a wire data-format in a client-server architecture. Domain objects (java beans) will go through following life-cycle.

  1. Used in client side business logic
  2. Converted to protobuf format
  3. Transmitted to the server
  4. Converted back to domain object
  5. Used in server side business logic

"Protocol Buffers and O-O Design" section in ProtoBuf documentation recommends wrapping generated class inside proper domain model.

I'd like to find-out the best appoach.

For e.g. I have a simple proto definition.

package customer;  option java_package = "com.example"; option java_outer_classname = "CustomerProtos";  message Customer {     required string name = 1;     optional string address = 2; } 

This is how domain model is defined. As you can see, the data is completely stored in proto builder object.

package com.example;  public class CustomerModel {     private CustomerProtos.Customer.Builder builder = CustomerProtos.Customer.newBuilder();      public String getName()     {         return builder.getName();     }      public void setName(String name)     {         builder.setName(name);     }      public String getAddress()     {         return builder.getAddress();     }      public void setAddress(String address)     {         builder.setAddress(address);     }      public byte[] serialize()     {         return builder.build().toByteArray();     }  } 

Is this a good practice? because these objects are used in all phases of life-cycle, but we only requires protocolbuf format at client-server transmission phase.

Is there any performance issue when accessing proto builder class getter/setter methods specially when proto definition is complex and nested?

like image 852
Sujee Avatar asked Aug 02 '12 08:08

Sujee


People also ask

What is protocol buffer used for?

Protocol Buffers (Protobuf) is a free and open-source cross-platform data format used to serialize structured data. It is useful in developing programs to communicate with each other over a network or for storing data.

What is protocol buffer format?

Protocol buffers are a combination of the definition language (created in . proto files), the code that the proto compiler generates to interface with data, language-specific runtime libraries, and the serialization format for data that is written to a file (or sent across a network connection).

Why is it called protocol buffer?

Why the name "Protocol Buffers"? The name originates from the early days of the format, before we had the protocol buffer compiler to generate classes for us. At the time, there was a class called ProtocolBuffer which actually acted as a buffer for an individual method.

What is Protocol buffers gRPC?

Protocol Buffer, a.k.a. Protobuf Protobuf is the most commonly used IDL (Interface Definition Language) for gRPC. It's where you basically store your data and function contracts in the form of a proto file.


2 Answers

I have no experience with protocol buffers, but I would not recommend implementing your domain objects tailored to a specific serialization/transfer framework. You might regret that in the future.

The domain objects and logic of a software application should be as independent as possible from specific implementation issues (in your case serialization/transfer), because you want your domain to be easy to understand and be reusable/maintainable in the future.

If you want to define your domain objects independent of serialization/transfer, you have two options:

  1. Before serialization/transfer, you copy the information to protocol buffers specific objects and send them to your server. There you would have to copy the information back to your domain objects.
  2. Use a non-protocol serialization library like Kryo or ProtoStuff to directly transfer your domain objects to the server.

The disadvantages of option 1 are that your domain is defined two times (which is undesirable with respect to modifications) and the copying of information (which produces error-prone and non maintainable code).

The disadvantages of option 2 are that you lose schema evolution (although ProtoStuff apparently supports it) and the complete (potentially large) object graph is serialized and transferred. Although you could prune the object graph (manually or with JGT) before serialization/transfer.

like image 70
Barry NL Avatar answered Sep 26 '22 00:09

Barry NL


We've made a protobuf-converter to solve the problem of transformation of your Domain Model Objects into Google Protobuf Messages and vice versa.

How to use it:

Domain model classes that have to be transformed into protobuf messages must satisfy conditions:

  • Class has to be marked by @ProtoClass annotaion that contains reference on related protobuf message class.
  • Class fields has to be marked by @ProtoField annotaion. These fields must have getters and setters.

E.g.:

@ProtoClass(ProtobufUser.class) public class User {      @ProtoField     private String name;     @ProtoField     private String password;      // getters and setters for 'name' and 'password' fields     ... } 

Code for conversion User instance into related protobuf message:

User userDomain = new User(); ... ProtobufUser userProto = Converter.create().toProtobuf(ProtobufUser.class, userDomain); 

Code for backward conversion:

User userDomain = Converter.create().toDomain(User.class, userProto); 

Conversion of lists of objects is similar to single object conversion.

like image 24
Roman Gushel Avatar answered Sep 24 '22 00:09

Roman Gushel