Updating data from protobuf

I am creating a microservice system with several components disabled, and now I am trying to figure out how to implement the knowledge of which fields on the object should be updated based on the data provided by protobuf .

The flow is as follows:

  • The client sends a JSON request to the API.
  • The API translates the JSON data into a protobuf structure, which is then sent to the microservice responsible for processing it.
  • The microservice receives data from the API and performs any action on it, in this case I try to change one value in the MySQL table, for example, the client's email address.

Now the problem is that since protobuf (understandably) does not allow pointers, the protobuf object will contain null values ​​for everything that is not provided. This means that if the client wants to update their email address, I don’t know if they also IncludeInMailLists to false - or if it is simply not provided (has a value of zero) and should not change.

The question arises: how do I - from the protobuf object - know if the value is explicitly set to 0 or simply not specified?

My current solution pretty much has a special UpdateCustomer object, which also has an Fields array that determines which fields the microservice should serve, but it feels like a bad solution.

Someone must have already decided it better. How to implement it?

+5
source share
1 answer

Protobufs field masks are one way.

https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#google.protobuf.FieldMask

https://github.com/golang/protobuf/issues/225

But if you use grpc , then there is a (kind of) built-in way.

Grpc Wrappers

Since proto3 (protobufs v3) there was no difference between a primitive that was not installed and a primitive that was set to "zero" (false, 0, "", etc.).

Instead, you can use objects or the protobufs language as a "message", since objects can be nil / null. You did not mention what language you work in, but I hope these examples make sense.

For an RPC service, for example:

 import "google/protobuf/wrappers.proto"; service Users { rpc UpdateUser(UpdateUserRequest) returns (UpdateUserResponse) } message UpdateUserRequest { int32 user_id = 1; google.protobuf.StringValue email = 2; } message UpdateUserResponse {} 

Note important import "google/protobuf/wrappers.proto"; . This gave you access to google protobufs covers here . These are not objects that have methods that allow you to check for availability.

The java generated Grpc code gives you methods like .hasEmail() , which returns true if this value is present. The receiver at an undefined value will still return you a null value. I think the golang version uses pointers that you can check for nil instead of the hasX() explicit method.

Further info / discussion on this github issue

+2
source

Source: https://habr.com/ru/post/1271544/


All Articles