12

我们目前正在从我们的单体中解决较小的服务。我们的域与票务系统非常相似。我们决定从域的取消过程开始。

我们的取消服务有一个简单的端点“取消”,它接受票的 id。在内部,我们检索 id,对其执行一些与取消相关的操作,并更新商店中实体的状态。从商店的角度来看,取消票和实时票之间的唯一区别是一些属性。

根据我的阅读,PATCH 似乎是在这种情况下使用的正确动词,因为我只更新资源中的一个简单属性。

PATCH /api/tickets/{id}
Payload {isCancelled: true}

但 isCancelled 不是实体中的实际属性。在不属于实体的有效负载中发送属性是否公平,或者我应该考虑对这个请求进行建模的其他形式?我不想将整个实体作为有效负载的一部分发送,因为它很大。

我考虑过创建一个新资源 CancelledTickets,但在我们的域中,我们永远不需要 GET 取消票证。因此,不必创建新资源。

4

5 回答 5

7

公开GET资源的接口不是强制性的。

例如,使用

PUT /api/tickets/{id}/actions/cancel

提交取消请求。我选择PUT是因为不会有超过一个有效的取消请求。

希望对您有所帮助。

于 2017-08-30T06:34:59.097 回答
6

看看究竟什么是RESTful 方式。无论您是使用有效负载发送PATCH请求,isCancelled还是DELETE希望票证消失。它仍然是 RESTful 的。

你的举动取决于你的需要。如你所说

我考虑过创建一个新资源 CancelledTickets,但在我们的域中,我们永远不需要 GET 取消票证。

我只是发送DELETE。您不必物理移除它。如果可以取消取消,则实施isCancelled机制。只是口味问题。

于 2017-03-02T17:30:17.917 回答
5

REST 基本上是基于浏览器的 Web 的泛化。您应用于 Web 的任何概念也可以应用于 REST。

那么,您将如何在网页中设计取消活动?您可能会有一个表格行,其中包含某些活动,例如用图标和鼠标悬停的文本概述的编辑和删除,单击这些活动会调用服务器上的 URI 并导致后续状态。您对该按钮的 URI 可能是什么样子或者后面是否调用了 PATCH 或 DELETE 命令不太感兴趣。您只是对处理请求感兴趣。

如果您想通过 REST 执行相同的操作,这同样适用。不是提示用户对条目执行编辑或取消活动的图像,而是应该使用有意义的链接关系名称来提示客户有关可能性的信息。在您的情况下,这可能类似于reserve new tickets,edit reservationcancel reservation. 每个链接关系名称都附有一个 URL,如果客户想要执行其中一项活动,则可以调用该 URL。URI 的确切字符在这里对客户端也不重要。要调用的方法可能已经在响应中提供(作为进一步的随附字段),也可能通过处理响应的媒体类型提供。如果媒体类型和随附字段都没有提示使用 OPTIONS 请求的 HTTP 操作可以事先在 URI 上发出。这里的经验法则是,服务器应该教客户端最终如何实现某些目标。

通过遵循这样的概念,您可以将客户端与 API 分离,并使其对更改具有鲁棒性。不是客户端生成一个 URI 来调用客户端,而是由服务器提供可能的 URI 来调用。如果服务器曾经更改其内部 URI 结构,则使用提供的 URI 之一的客户端仍然能够调用服务,因为它只是使用服务器提供的 URI 之一。通过分析提示客户端何时调用此类 URI 的链接关系名称来确定使用哪一个。如上所述,需要在某处定义此类链接关系名称。但这正是菲尔丁在 2008 年声称的:

REST API 应该花费几乎所有的描述性工作来定义用于表示资源和驱动应用程序状态的媒体类型,或者定义扩展关系名称和/或现有标准媒体类型的超文本启用标记。(来源

选择哪种 HTTP 操作来取消票/预订可能取决于您的设计。虽然推荐的一些答案DELETE RFC 7231指出仅删除了 URI 和资源之间的关联,并且不保证实际资源也将在此处删除。如果您设计的系统可能会撤消取消操作,那么DELETE这对您来说不是正确的选择,因为在处理DELETE请求后,URI 到资源的映射不应该进一步存在。但是,如果您认为取消预订也会导致预订被取消,那么您可以使用DELETE.

如果您以一种将状态作为资源中的属性来维护的方式对资源进行建模,PATCH则资源可能是一个有效的选项。然而,在这里简单地发送类似的东西state=canceled可能还不够,因为PATCH客户端为了将某个资源(或多个资源)转换为所需的目标状态而完成的步骤计算也是如此。JSON Patch可能会提供有关如何完成此操作的线索。需要对原子性要求进行进一步说明PATCH。要么所有指令都成功,要么根本不成功。

正如PUT其他答案之一中提到的那样。PUT具有将给定 URI 上可用的当前表示替换为请求有效负载中给定的表示的语义。还允许服务器或者拒绝内容或者将其转换为更合适的表示并且也影响其他资源,即,如果它们模仿资源的版本历史。

如果上述操作都不能真正满足您的需求,您应该使用POST它,因为这是 HTTP 的通用瑞士军刀工具包。虽然此操作通常用于创建新资源,但不限于此。它应该在其他操作的语义不适用的任何情况下使用。根据HTTP 规范

POST 方法请求目标资源根据资源自己的特定语义处理请求中包含的表示。

这基本上是出狱卡。在这里,您可以根据自己的规则在服务器上处理任何内容。如果您想取消或暂停某事,请执行此操作。

我非常不鼓励使用它GET来创建、更改或取消/删除某些东西。GET是一种安全操作,并保证任何调用客户端不会改变服务器上调用资源的任何状态。请注意,它可能有轻微的副作用,即日志记录,尽管实际状态应该不受调用的影响。这是网络爬虫所依赖的属性。他们将简单地通过调用任何 URIGET并了解接收到的响应的内容。而且我假设您不希望 Google(或任何其他爬虫)取消您的所有预订,是吗?

如上所述,您应该使用哪种 HTTP 操作取决于您的设计。DELETE仅当您还要删除表示时才应使用,即使规范不一定要求这样做,但是一旦到资源的 URI 映射消失,您基本上无法进一步调用此资源(除非您创建了一个当然,首先是进一步的 URI 映射)。如果您将资源设计为将状态保留在一个属性中,我可能会选择,PATCH但总的来说,我基本上会选择POST这里,因为在这里您拥有所有选择。

于 2018-09-29T22:48:05.880 回答
-1

我建议拥有一个国家资源。

这使事情保持 RESTful。您将 HTTP 方法用作动词。URI 的状态部分是名词。那么你的请求体就简单了,并且与 URI 一致。

我唯一不喜欢的是状态的值需要文档,这意味着有哪些状态?这可以通过 API 解决,方法是在元资源或元对象中的票证主体的一部分上提供可能的状态。

PUT /api/tickets/:id/state
{state: "canceled"}
GET /api/meta/tickets/state
// returns
[
  "canceled",
  ...
]
GET /api/tickets/:id
{
  id: ...
  meta: {
    states: [
      "canceled",
      ...
    ]
  }
}
于 2021-04-16T22:55:56.293 回答
-3

对于以 Restful 方式建模 CANCEL Action :假设我们必须通过提供 noteId(Note's ID) 来删除 DB 中的一个便笺,并且 Note 是一个 pojo

1]在控制器:

 @DeleteMapping(value="/delete/{noteId}")
     public ResponseEntity<Note> deleteNote( @PathVariable Long noteId)
     {
        noteServiceImpl.deleteNote(noteId);
        return ResponseEntity.ok().build();
     }

2]服务层:

@Service
public class NoteServiceImpl {

@Autowired
private NotesRepository notesDao;

public void deleteNote(Long id) {
    notesDao.delete(id);
}

}

3]存储层:

 @Repository
public interface NotesRepository extends CrudRepository<Note, Long> {
 }

并在 4] 邮递员:http://localhost:8080/delete/1

在此处输入图像描述

所以我们通过 CANCEL Action 从 DB 中删除了 note Id 1

于 2018-09-29T20:20:28.543 回答