TL,博士;使用FieldMask时,HTTP PATCH 应如何传达资源属性的删除?
Google用于实现标准方法的API 设计指南指出,应该使用FieldMask来实现部分更新。下面是我自己设计的更新资源的示例:Test
该服务的 API 为部分更新定义了一个Test
资源和一个HTTP PATCH方法 ( UpdateTest
)。
// A test resource.
message Test {
string name = 1;
google.protobuf.StringValue description = 2;
}
// Request message for update method.
message UpdateTestRequest {
// The resource name of the test to be updated.
string name = 1;
// Wrap the actual data in a data field.
Test test = 2;
// Field mask to support partial updates.
google.protobuf.FieldMask update_mask = 3;
}
// Partially update a Test resource.
rpc UpdateTest(UpdateTestRequest) returns (google.protobuf.Empty) {
option (google.api.http) = {
patch: "v1/{name=tests/*}"
body: "*"
};
}
同样设计的服务器实现使用FieldMask来合并资源(原始消息):
updated_test = v1_test_pb2.Test(name = 'Updated')
original_test = v1_test_pb2.Test(
name = 'Original',
description = google.protobuf.wrappers_pb2.StringValue(
value = 'I am Original!')
)
mask = google.protobuf.field_mask_pb2.FieldMask(
paths = ['name', 'description']
)
# from, to
mask.MergeMessage(updated_test, original_test)
print(updated_test)
最终结果是一个补丁Test
资源:
name: "Updated"
description {
value: "I am Original!"
}
清除该description
字段会完全删除该属性:
updated_test = v1_test_pb2.Test(name = 'Updated')
updated_test.ClearField('description')
original_test = v1_test_pb2.Test(
name = 'Original',
description = google.protobuf.wrappers_pb2.StringValue(
value = 'I am Original!')
)
# from, to
mask.MergeMessage(updated_test, original_test)
print(updated_test)
...最终修补的Test
资源将是:
name: "Updated"
伟大的。但是如何在 HTTP PATCH 请求中编码呢?
我能想到的唯一“解决方案”是,如果FieldMask包含description
但更新的Test
资源未提供值,则应使用ClearField将其删除。
这将需要手动访问掩码或Test
消息(或两者)中的每个字段,以确定是否应将其删除。这似乎很疯狂,特别是如果资源有很多字段。