Как HTTP PATCH должен сообщать об удалении атрибутов ресурса при использовании FieldMask - PullRequest
0 голосов
/ 08 ноября 2019

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 (, либо в обоих случаях). ) чтобы определить, следует ли его удалить. Это кажется сумасшедшим , особенно если у ресурса много полей.

...