TL, DR; При реализации пользовательских методов , "конфигурация HTTP [...] должна использовать предложение body:*
, а все остальные поля сообщения запроса должны сопоставить с телом HTTP-запроса. ". Почему?
У меня проблема с Руководством по разработке API Google , за которым я пытаюсь следовать с gRP C с конечными точками облака .
HttpRule
используется для перекодирования HTTP / JSON в gRP C. Ссылка HttpRule гласит:
Обратите внимание, что когда использует *
в отображении тела , невозможно иметь Параметры HTTP, так как все поля, не связанные концом пути в теле.
[...] Обычно *
используется в пользовательских методах. которые вообще не используют URL для передачи данных.
... мнение также повторяется в документации пользовательских методов Google и усилены с помощью Google API Linter ,
При использовании именованного представления в отображении body
остается хорошо определенное пространство, оставленное для добавления метаданных в форма параметров строки запроса; Например, для нумерации страниц, ссылок, предупреждений об устаревании, сообщений об ошибках).
service Messaging {
rpc UpdateMessage(UpdateMessageRequest) returns (Message) {
option (google.api.http) = {
put: "/v1/messages/{message_id}"
// A named reference makes it possible to use querystring params
// and the HTTP body.
body: "data"
};
}
}
message UpdateMessageRequest {
message Data {
string foo = 1;
string bar = 2;
string baz = 3;
}
// mapped to the URL as querystring params
bool format = 1;
string revision = 2;
// mapped to the body
Data data = 3;
}
Это позволяет для запроса HTTP PUT /v1/messages/123456?format=true&revision=2
с телом
foo="I am foo"
bar="I am bar"
baz="I am baz"
Поскольку сопоставление связывается body
до типа UpdateMessageRequest.Data
, остальные поля попадают в строку запроса. Этот подход используется в стандартных методах, но не в пользовательских ) методах.
Пользовательские методы должны отображать body
в *
. Один и тот же API с пользовательским методом будет
service Messaging {
rpc UpdateMessage(UpdateMessageRequest) returns (Message) {
option (google.api.http) = {
put: "/v1/messages/{message_id}"
// Every field not bound by the path template should be
// mapped to the request body.
body: "*"
};
}
}
message UpdateMessageRequest {
message Data {
string foo = 1;
string bar = 2;
string baz = 3;
}
// mapped to the body
bool format = 1;
string revision = 2;
Data data = 3;
}
Если одинаковые метаданные используются в обоих стандартных и пользовательских ) методах, он должен быть добавлен в виде параметров строки запроса или помещен в тело.
Например, приложение Angular будет использовать HttpParams
// standard method
const params = new HttpParams().append('format', true).append('revision', 2);
const request = {
foo: "I am foo",
bar: "I am bar",
baz: "I am baz",
}
this.http.post<Document>(url, request, {params});
Однако Пользовательский метод требует, чтобы клиент поместил все в тело:
// custom method
const request = {
format: true,
revision: 2,
data: {
foo: "I am foo",
bar: "I am bar",
baz: "I am baz",
},
}
this.http.post<Document>(url, request);
Вопрос: В чем причина этого?