好问题。
TL,DR;在实现custom methods时,“ HTTP配置[...]必须使用body:*
子句,并且所有剩余的请求消息字段都应映射到HTTP请求正文。”] >。 为什么?
我尝试使用API Design Guide跟踪Google的gRPC with Cloud Endpoints时遇到问题。
HttpRule
用于transcode HTTP/JSON to gRPC。 HttpRule reference状态:
时,有一个定义良好的空间,可以以查询字符串参数形式添加元数据;例如。用于分页,链接,弃用警告,错误消息)。注意,当使用正文中的
映射时,不可能具有HTTP参数,因为不受路径限制的所有字段都在主体结尾。*
[...]
完全用于传输数据的URL。*
的常用用法在不使用]的自定义方法中>...在Google的Custom Methods documentation中也重复了这一观点,并以Google's 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; }
这允许对带有主体的
/v1/messages/123456?format=true&revision=2
进行HTTP PUT请求>foo="I am foo" bar="I am bar" baz="I am baz"
由于映射将
body
绑定到类型UpdateMessageRequest.Data
,因此其余字段最终出现在查询字符串中。这是standard方法中使用的方法,但custom)方法中没有使用。自定义方法必须将
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);
问题:
TL,DR;在实现自定义方法时,“ HTTP配置必须使用body:*子句,并且所有剩余的请求消息字段都应映射到HTTP请求主体。”为什么?我有问题...
body
-我们告诉您将*
用于自定义方法,但是我们不会对执行其他操作设置任何技术障碍。我可以想到几个很好的“例外情况”,其中*
以外的物体可能有意义。第一个是自定义方法,该方法以一种标准方法为模型,但是出于某种原因应该自定义。第二种情况是自定义方法是否接受了完整的资源,并希望将主体设置为该资源。这将使该方法与Create
和Update
一致,这显然对API的用户有价值。[如果您有明确的论点,那就是将其他东西用作主体(尤其是某些东西本身就是资源本身),无论如何,请使用不同的主体并告诉短毛绒保持安静。我们写“应该”是有原因的。
您还问过:为什么我们首先提出该建议?
有几个原因。最大的一个是,上述例外情况很少见。我在内部进行了数百次API审查,但实际上我无法想到一个(不是说它们不存在)。在大多数情况下,对用户来说最好的事情是使请求消息镜像HTTP有效负载。
另一个原因是关键限制:将特定字段指定为正文会限制您可以在该字段中添加
outside
,因为查询字符串在类型(仅是基本类型)和数量方面都受到限制(URI长度限制)。因为以后更改body
会造成重大变化,所以这在某种程度上会束缚您的双手。显然,这对您的用例可能很好,但是请务必注意。无论如何,希望对您有所帮助-哦,谢谢您使用我的东西。 :-)好问题。