以前、gRPCの更新の際に、FieldMaskを使って余計なフィールドを更新しないようにする方法を調べた
今度は、repeatedのfield、いわゆる配列の要素のサブフィールドに対してfieldMaskしたい場合はどうするか調べた
例えば、次のような repeated User フィールドをリクエストに持つRPCで
message UpdateUsersRequest { repeated User user = 1; google.protobuf.FieldMask update_mask = 2; }
Userは以下のフィールドを持っている場合、
{ "user": { "id": "001", "name": "uga", "email": "uga@gmail.com" } }
emailだけ更新したい場合どうするか
結論、 sever側でリクエストとして受け取ったrepeatedのfieldをループで処理するしかなさそう
...
updateUserReply {
val updateUserList = request.userList.map {
val responseUser = User.newBuilder()
.setId(it.id)
.setName(it.name)
.setEmail(it.email).build()
val userWithMaskedFields = User.newBuilder()
FieldMaskUtil.merge(
request.updateMask,
responseUser,
userWithMaskedFields )
userWithMaskedFields.build()
}
// 更新処理
updateUserList.forEach {
this.user += it
}
}
ちなみに、ドキュメントを見ると、何やらワイルドカードというものがあるみたいで、最初これ使うのかな?と思ったが違った
これは配列の特定のインデックスのサブフィールドに対してマスクしたい時、"authors.0, authors.0.given_name"のようなインデックスを固定した書き方はNGのため、
"authors.*.given_name"のように*を使ってfieldMaskを指定するという話だった