用于非CRUD操作的REST API设计,例如保存,部署,执行代码

时间:2017-01-19 13:25:39

标签: rest

我的REST API上下文中的资源是用某种编程语言编写的应用程序代码。可以轻松映射到HTTP谓词的CRUD操作是保存/编辑/删除代码。难以映射到HTTP方法的非CRUD操作是在服务器上部署代码,执行代码和取消部署。

我在SO中遇到的常见建议是:

  1. 将操作重组为显示为资源字段,例如如果您的操作是激活引擎,请设计URI:PATCH engines/123,正文:{"status":"active"}
  2. 将动作视为子资源,例如: PUT engines/123/active没有身体
  3. 使用查询参数,例如PUT engines/123?activate=true
  4. 务实并寻找非REST的RPC风格的网址,例如: PUT engines/activate?id=123
  5. 我绝对无法将deploy / undeploy / execute代码操作放入#1和#2中建议的资源中。您能否分享您的意见,我们如何最好地为这些行动设计API?

3 个答案:

答案 0 :(得分:4)

  

请您分享您的意见,我们如何最好地为这些行动设计API?

创建/更新/删除信息资源,作为其副作用,请在API后面工作。

所以想想文件。

一个非常好的例子:在RESTful Causistry中,蒂姆布雷询问关于关闭机器的api。特别是Seth Ladd's response,阅读

非常重要

从根本上说,REST是一个解决文书工作问题的官僚机构。如果您想完成任何工作,请提交正确的表格;它成为描述你想要做什么的信息资源。

path_to_chromedriver = '/path/to/chromedriver' 
browser = webdriver.Chrome(executable_path = path_to_chromedriver)
try:
    response = get_data(browser)
except Exception as e:
    print str(e)
finally:
    browser.close()
    browser.quit()

请求只是一个文档,就像桌面上的粘滞便笺要求您解决某个任务的文档一样。

就REST而言,URI的拼写绝对无关紧要;但从人类可读的命名约定的角度来看,从资源是文档的事实开始 - 而不是您希望文档具有的副作用。

因此,例如,它完全正常且符合其余条件,描述事物当前状态的文档和描述要对事物进行更改的文档是不同的文档< / em>具有不同的标识符。

答案 1 :(得分:0)

根据REST API design RuleBook,我认为您正在寻找控制器:

        A controller resource models a procedural concept. 
    Controller resources are like executable functions, with parameters and return values; inputs and outputs.
        Like a traditional web application’s use of HTML forms, a REST API relies on controller
        resources to perform application-specific actions that cannot be logically mapped to
        one of the standard methods (create, retrieve, update, and delete, also known as
        CRUD).
        Controller names typically appear as the last segment in a URI path, with no child
        resources to follow them in the hierarchy. 
The example below shows a controller resource that allows a client to resend an alert to a user:
        POST /alerts/245743/resend

还有:

POST should be used to create a new resource within a collection and execute controllers.

答案 2 :(得分:0)

可以轻松映射到HTTP动词的

CRUD操作是 保存/编辑/删除代码。难以映射的非CRUD操作 HTTP方法是将代码部署在服务器上,执行代码,以及 取消部署。

我认为您误解了整个概念。您将操作映射到HTTP方法和URI,而不仅仅是映射到HTTP方法。对于CRUD,这是显而易见的。对于“非CRUD”,您需要添加具有其他URI的新资源,而不是尝试向列表中添加新的HTTP方法。

PATCH与PUT一样用于更新资源,但是对于PATCH,您发送更新指令而不是表示形式。确定可以使用它,也可以使用POST。如果您不发送正文中新资源状态的表示,则使用PUT并不是一个好主意。

因此,其中任何一个都可以是很好的:

PATCH engines/123 "activate"
PUT engines/123/state "active"
POST engines/123/activation null

您可以使用“部署/取消部署/执行”来执行相同操作:

PATCH engines/123 "deploy"
PUT engines/123/state "before-deploy"
POST engines/123/execution null

但这只是一个建议。您可以基于HTTP标准选择动词,我认为最好避免在URI中使用动词,我只使用名词,因为这样才有意义。 URI并不是那么重要,它就像网页上的URI一样,看起来不错,但是没有人真正在乎,除非他们必须写下来。为了清楚起见,除非您在响应中发送这些超链接,否则这仍然不是REST。

{
    id: "engines/123",
    type: "docs/engine",
    operations: [
        {
            operation: "docs/engine/activation", 
            id: "engines/123",
            method: "PATCH",
            body: "activate"
        }
    ]
}

使用RDF和本体使这一过程更加深入。