【问题标题】:REST Web Services API DesignREST Web 服务 API 设计
【发布时间】:2021-04-12 18:01:26
【问题描述】:

只是想获得有关我计划如何构建我的 API 的反馈。下面的虚拟方法。这是结构:

GET http://api.domain.com/1/users/ <-- returns a list of users
POST http://api.domain.com/1/users/add.xml <-- adds user
POST http://api.domain.com/1/users/update.xml <-- updates user
DELETE (or POST?) http://api.domain.com/1/users/delete.xml <-- deletes user

问题:

  1. 只使用 GET 和 POST 可以吗?
  2. 我打算依靠文件名来指示要执行的操作(例如要添加的 add.xml)是个好主意吗?做这样的事情会更好:POST http://api.domain.com/1/users/add/data.xml
  3. 保持这些资源版本化的好方法是什么?在我的示例中,我在域名后使用 /1/ 来表示版本 1。替代方案是:http://api1.domain.com... 或 http://api-1.domain.com... 或 http://apiv1.domain.com... 或 http://api-v1.domain.com... 或http://api.domain.com/v1/... 或
  4. 验证的最佳方式是什么?

【问题讨论】:

标签: rest


【解决方案1】:

在深入研究 REST 之前,您确实需要掌握以下术语:

资源 - 您希望在 API 中提供的东西/数据(在您的情况下为“用户”)

URI - 资源的通用唯一 ID。不应提及正在执行的方法(例如,不应包含“添加”或“删除”)。但是,您的 URI 结构不会使您的应用或多或少 RESTful - 这是一个常见的误解。

统一接口 - 您可以对资源执行的一组固定操作,大多数情况下是HTTP。每种 HTTP 方法的用途都有明确的定义。

对于您的 URI,它们现在最令人不安的是,它们包含有关正在执行的操作的信息。 URI 是 ID,仅此而已!

让我们举一个现实世界的例子。我的名字是内森。 “Nathan” 可以被认为是我的 ID(或者用简单的术语 URI——为了本示例的目的,假设我是唯一的“Nathan”)。我的姓名/ID 不会因您希望与我互动的方式而改变,例如当你想和我打招呼时,我的名字不会变成“NathanSayHello”。

REST 也是如此。当您要更新该用户时,由http://api.domain.com/users/1 标识的用户不会更改为http://api.domain.com/users/1/update.xml。您要更新该用户的事实暗示了您使用的方法(例如 PUT)。

这是我对你的 URI 的建议

# Retrieve info about a user 
GET http://api.domain.com/user/<id>

# Retrieve set all users
GET http://api.domain.com/users

# Update the user IDed by api.domain.com/user/<id>
PUT http://api.domain.com/user/<id>

# Create a new user.  The details (even <id>) are based as the body of the request
POST http://api.domain.com/users

# Delete the user ID'd by api.domain.com/user/<id>
DELETE http://api.domain.com/user/<id>

至于你的问题:

  1. 在适当的时候使用 PUT 和 DELETE 并避免重载 POST 来处理这些函数,因为它会破坏 HTTP's definition of POST。 HTTP 是您的统一接口。这是您与 API 用户之间关于他们如何期望与您的服务交互的合同。如果你破坏了 HTTP,你就破坏了这个契约。

  2. 完全删除“添加”。使用 HTTP 的 Content-Type 标头指定发布数据的 MIME 类型。

  3. 您指的是 API 的版本还是资源的版本? ETag 和其他响应标头可用于对资源进行版本控制。

  4. 这里有很多选择。基本 HTTP 身份验证(简单但不安全)、摘要式身份验证、自定义身份验证(如 AWS)。 OAuth 也是一种可能。如果安全是最重要的,我使用客户端 SSL 证书。

【讨论】:

  • 回复+1,但是:PUT/DELETE 必须是幂等的,而不是 POST。 POST 可以随心所欲。 “幂等”只是意味着如果操作重复两次,它会产生相同的结果 - 用数学语言来说就是f(f(x)) = f(x)。在我们的例子中,如果对同一资源执行两次相同的 PUT,则结果必须与仅完成 1 次相同。另一方面,POST 取决于开发人员给出的语义,可能会产生不同的结果(例如两次 POST 可能会发送 2 封电子邮件)
  • 你是完全正确的。这应该读作“普遍缺乏幂等性”,通常看到它正在创建一个绝对不是幂等的资源(或者在您的示例中是发送电子邮件的工作)。将相应调整帖子。
【解决方案2】:

1) 在您的设计中可能不会。 POST 不是幂等的!所以你不应该使用更新或删除,而是使用来自 Rest 的 PUT 和 DELETE

2) 更好的选择是在 WS 调用中使用标头 Content-Type,例如:application/xml

3) 你也可以在标题 Content-Type 上使用它:application-v1.0/xml

4) 不确定它是否是最好的,但可能最简单的方法是在RFC 2617 中使用 HTTP 的内置身份验证机制。一个例子:AWS Authentication

【讨论】:

  • 您对 (1) 的推理很薄弱。 POST 不是“非幂等的”,它“不一定是幂等的”。由于他定义了服务器端语义,他的 POST 可能是幂等的,这对于 http 和整个世界来说都很酷。
  • @NasBanov 来自 w3.org Http Methods 文档w3.org/Protocols/rfc2616/rfc2616-sec9.html。请看第 9.1.2 节幂等方法。 Post 永远不会显示为可能的幂等方法。
  • @DiegoDias,9.1.2 讨论 GET/HEAD/PUT/DELETE,对 POST 没有任何影响。如果我说乔和萌是诚实的,那并不意味着比利是骗子。 [9.5] “POST 方法执行的实际功能由服务器确定,通常取决于请求 URI” - 例如,如果我有一个(触发器)灯开关,它就不是幂等的。但如果它是一个“ON”按钮,它将是幂等的
  • 参见第 9.6 节:“POST 和 PUT 请求之间的根本区别反映在 Request-URI 的不同含义上。POST 请求中的 URI 标识将处理封闭实体的资源。 ...相比之下,PUT 请求中的 URI 标识了请求中包含的实体”。所以如果你想使用PUT,你需要提前知道userID并做PUT http://api.domain.com/1/user/123654。如果您希望添加用户并获得 ID 作为回报,您应该这样做 POST http://api.domain.com/1/users
【解决方案3】:
  1. 在 REST 中,HTTP“动词”用于表示操作类型:您将无法仅使用“GET”和“POST”来表达所有 CRUD 操作

  2. 否:资源的 URL 通常是“文档标识符”应该出现的位置

  3. “文档”的版本可以在创建/修改所述资源时在 HTTP 响应标头中传输。唯一标识资源应该是服务器的职责 - 尝试在客户端执行此操作将证明是一项艰巨的挑战,即保持一致性。

当然,这个话题有很多变化......

【讨论】:

    【解决方案4】:

    我根据标头进行了身份验证。类似的东西

    X-Username:happy-hamster
    X-Password:notmyactualpassword
    

    如果您担心安全问题,请通过 SSL 进行。 当然,存在其他实现。例如,亚马逊的 S3: http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTAuthentication.html

    如果您无法发出 PUT 和 DELETE 请求,则最好通过 POST 将它们隧道化。在这种情况下,操作在 URL 中指定。如果我没记错的话,RoR 就是这样做的:

    POST http://example.com/foos/2.xml/delete
    

    POST http://example.com/foos/3.xml/put
    
    ...
    
    <foo>
        <bar>newbar</bar>       
    </foo>
    

    这有点离题,但关于版本控制和整体 REST,您可能需要查看 CouchDB。这是good book available on-line

    【讨论】:

      【解决方案5】:

      使用 post 创建和删除功能并不是一个好的 rest api 设计策略。使用 Put 来创建、发布以更新和删除以删除资源。 有关设计 rest api 的更多信息,请点击链接 - best practices to design rest apis

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-12-13
        • 2016-02-04
        • 2022-06-28
        • 2019-01-21
        • 2018-07-09
        • 1970-01-01
        • 2021-02-15
        相关资源
        最近更新 更多