Rails中的非RESTful操作

jos*_*ing 8 rest ruby-on-rails

好吧,当GitHub停机时,代码设计问题:
我总是在rails应用程序(通常)中使用非标准RESTful操作进行分析瘫痪.

我有乔布斯,我希望能够取消(并重新激活)它们.它不像设置复选框那么简单; 还有一些其他事情需要发生.所以我不能只使用现有的JobsController#update行动.

我看到以下是我的选择:

1.只需添加cancelreactivate现有的作业控制器.路线将是这样的:

POST /admin/jobs/cancel/:job_id
POST /admin/jobs/reactivate/:job_id
Run Code Online (Sandbox Code Playgroud)

(不是RESTful;假设这是一个坏主意)

2.创建一个JobCancellationsControllerwith createdestroyactions.重新激活作业是destroy一种JobCancellation资源.

我将使用嵌套路由,如下所示:

resources :jobs, except: :show do
  resource :job_cancellation, only: [:create, :destroy]
end
Run Code Online (Sandbox Code Playgroud)

默认情况下会给我一些类似的东西

一个)

POST /admin/jobs/:job_id/job_cancellation
DELETE /admin/jobs/:job_id/job_cancellation
Run Code Online (Sandbox Code Playgroud)

我可以在不改变控制器的情况下整理路线,就像:

b)

POST /admin/jobs/:job_id/cancellation
DELETE /admin/jobs/:job_id/cancellation
Run Code Online (Sandbox Code Playgroud)

虽然这看起来不太直观 - "取消"会更好cancel.所以我可以在保持控制器相同的同时改变路线:

C)

POST /admin/jobs/:job_id/cancel
DELETE /admin/jobs/:job_id/cancel
Run Code Online (Sandbox Code Playgroud)

第一条路线现在有意义(虽然RESTful严格来说不是吗?),但第二条路线不是......"删除工作取消"?所以你要把它改成:

d)

POST /admin/jobs/:job_id/cancel
POST /admin/jobs/:job_id/reactivate
Run Code Online (Sandbox Code Playgroud)

现在路由是有意义的,但看起来可疑地接近上面的选项1),即使路由确实映射到RESTful动作JobCancellationsController而不是非RESTful动作JobsController.将POST /admin/jobs/:job_id/reactivate路线映射到JobCancellationsController#destroy动作似乎非常棒.

为了避免这种最后的情况JobCancellationsController#destroy,我可以改为:

3.选项2类似,但创建两个控制器:JobCancellationsController一个create动作而已,而JobReactivationsControllercreate只有行动.

这样做的"正确"方法是什么?或者至少,哪些是我可以迅速消除的"不正确"方式?我错过了一种完全不同的,更好的方式吗?

jos*_*ing 11

在讨论了Ruby Australia冗余渠道后,我将建议整合到下面:

答案

只需添加cancelreactivate现有的JobsController.

使用此代码:

resources :jobs do
  post :cancel, on: :member
  post :reactivate, on: :member
end
Run Code Online (Sandbox Code Playgroud)

创建路线,如:

POST /admin/jobs/:job_id/cancel
POST /admin/jobs/:job_id/reactivate
Run Code Online (Sandbox Code Playgroud)

这很简单直观,即使它不是严格的RESTful.

(另一种建议的方法是PATCH到现有的update方法,状态为取消;虽然我想在你的更新方法中需要有条件的cancelsvs常规updates)

讨论中提出的其他有用的观点

  • 当你被出售时,资源非资源的东西是一个常见的陷阱"REST是最好的!" (即,Jobs是资源,但JobCancellations不是真的,所以不要试图使它们成为资源).

  • 如果您不需要删除作业的功能,则可以使用该destroy操作取消作业而不是cancel操作.

  • IMO完整的REST仅在您不可能遇到的某些情况下有用,除非您在大公司.

  • 制作一个有意义的API.Rails只是提供了轻松完成CRUD的方法.这与宁静相关,但不是全部.

  • REST(或HATEOS)方法是/jobs/1234.json包含一个cancelLink: {url: "url", method: "POST", rel: "link to the docs"}属性

  • 当我们构建我们的API时,我们有一个非官方的规则,如果我们不确定该怎么做,我们只是复制github所做的,因为我们喜欢他们的API.

  • fwiw,我使用了一堆根据休息设计得很好的"休息"API,但作为开发人员使用起来很糟糕.更重要的是你A)覆盖原语和B)使它比你遵守REST(或HATEOS,或者你今天关注的任何东西)一样友好.

以上所有内容基本上都指向了我总是试着告诉自己的建议:"最重要的是代码简单易懂.设计模式只有在它们帮助您实现目标的范围内才有用.如果设计模式没有要实现这个目标,你可能会错误地使用它,或者将它应用于不正确的情况,或者过于严格地使用它".