实用的REST服务设计问题

时间:2014-01-03 09:48:03

标签: rest

我正在开发一个项目,其当前的稳定版本是使用JSP / Servlet编写的,需要使用客户端MVC框架Backbone.js和使用spring web MVC编写的服务器上的REST服务重写为单页面应用程序。对于使用Objective C编写的iOS应用程序,应该使用相同的REST服务集。

这是我第一次编写非平凡的REST服务,我已经阅读了一本关于Rest和许多博客条目以及许多StackOverflow条目的书,如下所示:

我还没有找到我在设计REST服务时遇到的所有问题的明确答案。我已经完成了这些服务的设计,但我想验证我的设计。

  1. 我的应用程序将Car作为主要资源。所以我获取所有汽车的URI就像

    GET http:/host:port/mywebappname/cars
    

    获取特定汽车的URI是

    GET http:/host:port/mywebappname/cars/MH12-1234
    

    其中MH12-1234是汽车的ID。

    当我想要获得2010年由福特和现代制造的所有这类汽车时,我的麻烦就开始了。我认为可能的URI要么

    GET http:/host:port/mywebappname/cars/search/Ford;Hyundai/2010
    

    GET http:/host:port/mywebappname/car/search?make=Ford,Hyundai&year=2010
    
    1. 其中哪一个是对的?
    2. 我无法想象“搜索”作为资源,所以我将汽车作为资源并将搜索作为一项操作。这是针对REST意识形态的吗?
  2. 我的汽车资源有许多可能的操作,例如画车,洗车等。这些操作的URI看起来跟着我。

    POST http:/host:port/mywebappname/cars/MH12-1234/paint/yellow/glossy
    

    POST http:/host:port/mywebappname/cars/MH12-1234/paint?color=yellow&finish=glossy
    
    1. 其中哪一个是对的?我应该将整个汽车对象作为请求体的一部分发送吗?
    2. 有人建议将操作名称作为请求标头的自定义属性发送。所以在我的情况下,paint将进入请求标头内。在这种情况下,我在哪里发送color=yellowfinish=glossy等信息?作为请求正文或标题的一部分?
  3. 一旦客户端读取汽车资源,它可能想要将其轮子更改为其他合适的车轮。因此,此操作的URI可能类似于

    GET http:/host:port/mywebappname/car/MH12-1234/replace/wheel/rear-left
    

    这基本上是用其他合适的车轮替换左后轮。

    1. 这是正确的做法吗?
    2. 这项服务应该归还整辆车还是新车?
  4. 在客户端界面中玩汽车对象的用户可以尝试对汽车进行各种操作。例如。用户可以将其涂成黄色,然后将其涂成绿色并更换多个轮子,最后点击“保存”。对于用户发起的每个操作,我必须将整个汽车对象或其一部分发布到服务器。那么发送它的一部分是否可以避免电线上的封装尺寸?

    现在这些请求以PUT或POST的形式发送,服务器在内存中执行这些操作并返回修改后的car对象。现在汽车资源作为请求发送,并且汽车对象作为响应被接收。这是一个有效的场景吗?

    如果是,那么在两种情况下(保存按钮单击或任何操作)我必须将相同的汽车资源POST或PUT到服务器。我想在点击保存按钮时实际将汽车资源保存到数据库,在其他操作的情况下,我只想在服务器内存中执行操作并返回修改后的资源。如何在服务器上区分用户点击保存,因为我在PUT或POST资源的两种情况下都会这样做?

2 个答案:

答案 0 :(得分:0)

尽量避免使用操作。

只需修改汽车客户端的属性并执行PUT以保存更改。

然后,服务器端应该验证它是否连贯(比如不要使用paint而不是gas)并保存或最终返回HTTP错误。

对于搜索/过滤器,我喜欢this approach

无论如何,REST更像是一般指南,您不需要您的API按字面意思遵循REST原则。

按照REST指南执行您认为更合乎逻辑的数据,而不是将API限制在其中。

答案 1 :(得分:0)

尝试在http resquest等REST服务中思考,所以

  1. 我会选择 GET http:/ host:port / mywebappname / car / search?make = Ford,Hyundai& year = 2010 因为更类似于GET请求。还试着考虑一下2010年所有车型的请求,其他格式为GET http:/ host:port / mywebappname / cars / search // 2010

  2. 正确的将发送 POST http:/ host:port / mywebappname / cars / MH12-1234 并在帖子正文中发送请求信息,格式为thar选择,通常是xml o json。 我建议您必须使用其他网址来提供此服务,例如 http:/ host:port / mywebappname / service 。尝试隔离网址:汽车必须用于搜索汽车或添加新车,而不是在车库操作中预约。

  3. 在这种情况下最好的是使用PUT服务,在REST中添加或修改项目,但通常仅用作修改项目,并且与POST服务类似: PUT http :/ host:port / mywebappname / cars / MH12-1234 以及正文中的修改。

  4. 取决于你想要的:如果网络是买车,也许你只需要在选择完成后添加一辆新车;如果是车库,修改意味着将车送到车库,也许必须是另一项服务,当车完成时,机械师会修改汽车。