TL, DR ; Как HTTP PATCH должен сообщать об удалении атрибутов ресурса при использовании FieldMask ?
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
resource:
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
(, либо в обоих случаях). ) чтобы определить, следует ли его удалить. Это кажется сумасшедшим , особенно если у ресурса много полей.