这个RESTAPI设计正确吗?

这个RESTAPI设计正确吗?,rest,Rest,我正在开发一个部署系统,该系统需要在池中的所有或部分机器上的池上部署一些应用程序。为了简单起见,假设我对api只有3个要求 部署 取消 地位 我现在对为上述操作设计RESTAPI调用感到困惑:以下是我的想法。如果有效负载为空,我将在池中的所有机器上部署 http://my-endpoint/api/{pool-name}/deploy Payload: { "machines" : [ "machine-1.fqdn", "machine-2.fqdn"

我正在开发一个部署系统,该系统需要在池中的所有或部分机器上的池上部署一些应用程序。为了简单起见,假设我对api只有3个要求

  • 部署
  • 取消
  • 地位
  • 我现在对为上述操作设计RESTAPI调用感到困惑:以下是我的想法。如果有效负载为空,我将在池中的所有机器上部署

    http://my-endpoint/api/{pool-name}/deploy
    
    Payload:
    {
        "machines" : [
            "machine-1.fqdn",
            "machine-2.fqdn",
            "machine-3.fqdn"
        ]
    }
    Response:
    {
        "status": "OK",
        "jobId": "9999"
    }
    
    然后,客户端可以根据作业ID轮询状态或取消部署:

    http://my-endpoint/api/{pool-name}/status/{jobId}
    http://my-endpoint/api/{pool-name}/cancel/{jobId}
    
    现在,jobId在整个部署系统中是唯一的,因此在api中使用{pool name}表示“status”和“cancel”似乎是不对的。这个设计好吗?我在网上读了很多关于在REST中映射动作的文章,这些文章只会增加我的困惑。我的应用程序中没有任何积垢。我只是想确定我做这件事的方式是正确的。有人能指出设计中的缺陷吗?任何提示都会有帮助。

    一些想法:

    首先,您的回答不考虑某些机器工作而某些机器不工作的可能性。因此,您的响应可能需要是一个数组,每个尝试的机器都有一个状态

    其次,这不是严格的restful,您正在创建的URL实际上是动词。从实用角度讲,它会起作用,但要做到RESTful,您应该识别您的实体并使用GET、PUT、POST和DELETE

    所以这里你的实体可能就是工作

    PUT to /myendpoint/api/job
    
    使用包含池名和机器数组的有效负载。响应将是状态和作业ID的数组

    [ 
    {
    "status": "OK",
    "jobId": "m1-9999"
    },{
    "status": "OK",
    "jobId": "m2-9999"
    },{
    "status": "BAD",
    "machine": "m3"
    "reason": "xxx"
    }
    ]
    
    您可以获取作业id以获取状态。作业ID足以识别它在哪台机器上

    GET myendpoint/api/job/m2-9999
    

    然后使用有效负载“cancel”发布到相同的URL以取消作业。

    对于cancel和status,我实际上更喜欢以下内容

    http://my-endpoint/api/{pool name}/cancel/{job id}

    我的设计是不对空请求负载采取任何操作。这是为了防止非严重用户不必要地攻击API。我希望有一个有效负载,否则会向它们抛出一个错误响应

    同样,对于成功取消/状态,将返回如下响应

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <request-result>
    <http-code>200</http-code>
    <description>REST Request is successfully processed</description>
    <internal-error-info></internal-error-info>
    <message>Job with {id} is processed successfully</message>
    <requested-operation>Cancel</requested-operation>
    <resource-name>JobName</resource-name>
    <status>SUCCESSFUL</status>
    </request-result>
    
    
    200
    REST请求已成功处理
    已成功处理具有{id}的作业
    取消
    工作名称
    成功的
    
    我会删除url中的“/api”部分,但其余部分看起来很好。感谢您的评论。+1,除了PUT的语义在这里不合适之外-PUT应该在要放置的url处创建一个新资源。使用POST@djna非常感谢。你让我走上了正确的道路。关于您对每台机器状态的观察,我同意。我应该提到,部署只是创建了一个新的作业,由Quartz负责。有关作业执行的所有详细信息都将在状态调用中返回给客户端。@AntonTykhyy是的,我将使用POST。我相信我不需要公开PUT,因为一旦创造了工作岗位,就没有什么可以改变的。它只能被取消或查询状态。@安东:我很困惑,我们正在创建一个新的作业资源,为什么PUT不适用于此?@djna PUT的标准语义是在请求中指定的URL处创建一个资源,即PUT/jobs/12345应该创建一个id为12345的新作业,这样,后续的GET/jobs/12345将获取作业对象的当前状态。但是,您通常不希望调用方能够指定新作业的id,而是自己生成并将其返回给调用方。因此,调用方不知道新作业可用的URL,因此POST是合适的。见本手册第9.5节和第9.6节。