I'm trying to use gRPC to build a simple CRUD service, but I keep finding myself creating messages with big overlaps.
This is best described by an example:
message Todo {
// id is only available for a persisted entity in database.
string id = 1;
string content = 2;
// this is only available for users with admin role.
string secret_content = 3;
}
service Todos {
rpc CreateTodo(CreateRequest) returns (CreateResponse) {}
rpc ReadTodo(ReadRequest) returns (ReadResponse) {}
}
message CreateRequest {
// this todo is not supposed to have id,
// should I create another version of Todo without an id field?
Todo todo
}
message CreateResponse {
// this todo will always have an id.
Todo todo = 1;
}
message ReadRequest {
string id = 1;
}
message ReadResponse {
// this todo should only have the secret_content field if the
// user is authenticated as an admin, if not, the field should not
// fallback to the zero value, the whole field must be missing.
Todo todo = 1;
}
Is this a good approach to build a CRUD like resource with gRPC? That is, having a single message (Todo
) representing the resource, and wrapping this message in response/request types per action.
Should the Todo type message have all fields covered by all requests/responses, and not set the ones which are not in use by each?
By default, gRPC uses Protocol Buffers, Google's mature open source mechanism for serializing structured data (although it can be used with other data formats such as JSON).
REST APIs generally use JSON or XML message formats, while gRPC uses protocol buffers. To signal errors, REST APIs use HTTP status codes, while gRPC uses error codes. gRPC's message sizes tend to be dramatically smaller than those of REST APIs.
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).
Should the Todo type message have all fields covered by all requests/responses, and not set the ones which are not in use by each?
Yes, this seems like a reasonable design. In protobuf v2, you would have marked such fields optional
to make it easier to understand. But in v3, all fields are optional by default anyway.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With