RESTful API的GET方法返回什么?

时间:2018-08-30 09:54:38

标签: rest asp.net-web-api

我对REST比较陌生,从一开始我就有一个问题。

我直截了当地说,我有一个电子商务系统,所以我有一些“产品”,我也有这个资源:errorMessage: string = ""; setErrorMessage(message:string){ this.errorMessage = message; } getErrorMessage(){ return this.errorMessage; } setRegistrationData(provider, email){ this.login.accountExist(provider, email).subscribe( (response: UserCount) => { if (response.count == 0) { //do something return true; }else{ this.setErrorMessage("Custom Error Message"); return false; } } 在我的Web api中,我发送GET HTTP请求对此。

它应该返回什么?如果它返回包括所有属性的整个实体,那么在我只需要其中一些属性而其他属性将无用的情况下,这是不合适的。例如,在某些情况下,我只需要“标题”和“价格”,因此,我不需要其他属性,这只是开销。

如何处理?

谢谢。

2 个答案:

答案 0 :(得分:3)

我可以考虑两种处理方法。

自定义媒体类型

您可以使用以下一种(或两种)媒体类型来检索产品的完整表示形式:

GET /api/products/1 HTTP/1.1
Host: example.com
Accept: application/json
GET /api/products/1 HTTP/1.1
Host: example.com
Accept: application/vnd.company.full+json

以下媒体类型仅检索产品的简短表示形式:

GET /api/products/1 HTTP/1.1
Host: example.com
Accept: application/vnd.company.short+json

查询字符串参数

或者,您可以支持使用查询字符串参数选择要检索的字段。

使用以下内容检索产品的完整表示形式:

GET /api/products/1 HTTP/1.1
Host: example.com
Accept: application/json

以下内容仅检索产品的名称和价格:

GET /api/products/1?fields=name,price HTTP/1.1
Host: example.com
Accept: application/json

为了方便起见,尽管列出了字段,您始终可以返回产品的标识符。


上述方法也可以应用于资源集合,例如/api/products

正如Evert在评论中指出的那样,“ ”可能值得研究,无论如何发送所有内容是否确实会降低性能或带宽。如果没有明显的成本,则可以使用更胖的模型进行清晰度有时会更好一些。 “

再进一步,引用Donald Knuth:"premature optimization is the root of all evil"。也就是说,由于您认为将会获得性能上的提升,因此不存在您不应该优化的可衡量的性能问题。可以执行一些明显的优化,但是在进行度量之前,应避免所有并非显而易见的优化。

答案 1 :(得分:0)

请记住,/api/products/1234标识的是资源,而不是实体。您的API可能有许多描述相同实体的不同资源。参见Jim Webber的演讲REST: DDD In the Large

(还要注意,这是一个折衷方案,因为每个资源都有自己的缓存条目-如果客户端修改一个资源,然后看到描述相同实体的另一个资源的陈旧副本,这可能会很尴尬)。 / p>

如果使用不同的资源方法,则可以在所需的URI中使用任何拼写形式。查询字符串是一种常见选择,或者是路径段上的文件扩展名,甚至生成单独的路径段。据我所知,选择之间唯一的真实区别是relative resolution(RFC 3986)在您的用例中是否具有任何价值。

  

它应该返回什么?

一个常见的选择是使用DataTransferObject模式。福勒写道

  

在使用远程界面(例如Remote Facade(388))时,每次调用都非常昂贵。结果,您需要减少呼叫数量,这意味着您需要在每个呼叫中​​传输更多数据。一种方法是使用大量参数。但是,这通常很难进行编程-实际上,对于Java这样的仅返回单个值的语言,这通常是不可能的。

     

解决方案是创建一个数据传输对象,该对象可以保存呼叫的所有数据。

由于REST被“设计用于大颗粒超媒体数据传输的高效”(Fielding),因此该方法非常合适。