设计有效的rest API

Mat*_*ist 1 api rest

我正在尝试通过HTTP设计REST API.我对此完全陌生,所以请告诉我,我的任何假设或想法是否完全错误.

域名是简约的.我有一个产品数据库,每个产品都有一个相关的图像.在我看来,我可以通过以下两种方式之一设计我的API:

  1. 我可以将每个图像与其产品捆绑在一起,并将它们表示为一种资源.这种api的缺点是,每当你输出或获取产品时,你必须通过电线发送图像,即使你不需要特别需要阅读或更改图像.根据我的理解,不要PUT或GET 完整的资源表示不是RESTful .此外,在这种情况下,客户端缓存图像将毫无用处.

  2. 我可以将产品和图像建模为两种不同的资源.获取产品时,它将包含一个image_id,可用于获取图像.此模型需要两个HTTP请求.一个用于获取产品,另一个用于获取相应的图像.也许不是那么糟糕,但是如果我想显示所有产品的列表以及它们的图像怎么办?然后我突然有了一堆HTTP请求.使用SSL时,我想这可能会产生性能问题.但好消息是,我的API的消费者可以选择在客户端缓存图像.

那么,我如何将我的API建模为RESTful和高效?

Che*_*eso 5

你在考虑数据模型是件好事.
与此相关,REST没有指定或暗示数据模型必须完全去规范化.

通常,在获取资源时,您将收到一个信息包,其中还包含对其他相关资源(如产品图像)的URL引用.它还可以包括对产品类别,产品制造商等的引用.每个都可能是您可以从中派生URL的URL或ID.像这样的消息:

{
   "id": 123456,
   "description" : "Your basic paperweight",
   "category" : { id: 17717,  "name" : "Home furnishings" },
   "manufacturer": { id : 78783, "name" : "Boeing" },
   "price" : 1.99,
   "imageId" : 109101
}
Run Code Online (Sandbox Code Playgroud)

...可能意味着这样的网址:

http://api.mycompany.com/product/123456   
http://api.mycompany.com/category/17717   
http://api.mycompany.com/manufacturer/78783   
http://api.mycompany.com/image/109101    
Run Code Online (Sandbox Code Playgroud)

...并注意链接资源的完整表示(如类别,制造商等)不会与原始资源一起传输.这是部分去标准化的数据模型.

关于你对PUT的评论:

  1. 这是一个意见问题,但是...... 对于许多开发人员 来说,允许通过PUT进行部分更新是完全可以接受的.所以你可以更新资源而不指定所有内容; 现有字段将保持不变.如果选择此行为,则在处理边缘情况时可能会使(服务器端)代码复杂化.例如,客户端如何表明他想要删除或删除字段?(传递null可能有效,但对于某些数据,null是一个有意义的值.)

  2. 为什么担心PUT?如果你想要部分更新,很容易使用POST,在查询参数中使用动词(例如,"partialUpdate").实际上这就是Roy Fielding所倡导的,这对我来说很有意义.

部分更新将是这样的:

POST /products/123456?action=partialUpdate 
*headers*

{ 
  "description" : "A fabulous paperweight designed in Sweden, now at a new low price." },
  "price" : 1.78 
}
Run Code Online (Sandbox Code Playgroud)