小编典典

了解 REST:动词、错误代码和身份验证

all

我正在寻找一种将 API 包装在基于 PHP 的 Web 应用程序、数据库和 CMS 中的默认函数的方法。

我环顾四周,发现了几个“骨架”框架。除了我问题中的答案之外,还有Tonic,一个我喜欢的
REST 框架,因为它非常轻量级。

我最喜欢 REST 的简单性,并希望基于它创建一个 API 架构。我试图了解基本原理,但还没有完全理解它。因此,提出了一些问题。

1.我理解对了吗?

假设我有一个资源“用户”。我可以像这样设置许多 URI:

/api/users     when called with GET, lists users
/api/users     when called with POST, creates user record
/api/users/1   when called with GET, shows user record
               when called with PUT, updates user record
               when called with DELETE, deletes user record

到目前为止,这是 RESTful 架构的正确表示吗?

2. 我需要更多的动词

创建、更新和删除在理论上可能就足够了,但实际上我需要更多的动词。我意识到这些是可以嵌入到更新请求中的东西
但它们是可以具有特定返回码的特定操作,我不想将它们全部放入一个操作中。

在用户示例中想到的一些是:

activate_login
deactivate_login
change_password
add_credit

我将如何表达诸如 RESTful URL 架构中的操作?

我的直觉是对像这样的 URL 进行 GET 调用

/api/users/1/activate_login

并期望返回状态码。

但是,这偏离了使用 HTTP 动词的想法。你怎么看?

3.如何返回错误信息和代码

REST 的美妙之处很大一部分来自于它对标准 HTTP 方法的使用。出现错误时,我会发出一个带有 3xx、4xx 或 5xx
错误状态代码的标头。对于详细的错误描述,我可以使用正文(对吗?)。到目前为止,一切都很好。但是,传输 专有错误代码
的方式是什么,该代码更详细地描述了出错的原因(例如“无法连接到数据库”或“数据库登录错误”)?如果我将它与消息一起放入正文中,我必须在之后将其解析出来。这种事情有标准的标题吗?

4.如何进行认证

  • 遵循 REST 原则的基于 API 密钥的身份验证是什么样的?
  • 在对 REST 客户端进行身份验证时,是否有反对使用会话的优点,除了它公然违反 REST 原则?:) (这里只是在开玩笑,基于会话的身份验证可以很好地与我现有的基础设施配合使用。)

阅读 101

收藏
2022-03-06

共1个答案

小编典典

我晚了几天才注意到这个问题,但我觉得我可以添加一些见解。我希望这对您的 RESTful 冒​​险有所帮助。


第1点:我理解对了吗?

你理解的没错。这是 RESTful
架构的正确表示。您可能会发现Wikipedia中的以下矩阵对定义名词和动词非常有帮助:


在处理 Collection URI 时,例如: http://example.com/resources/

  • GET :列出集合的成员,并附上他们的成员 URI,以便进一步导航。例如,列出所有待售汽车。

  • PUT :含义定义为“用另一个集合替换整个集合”。

  • POST :在集合中创建一个新条目,其中 ID 由集合自动分配。创建的 ID 通常包含在此操作返回的数据中。

  • DELETE :含义定义为“删除整个集合”。


在处理 成员 URI 时,例如: http://example.com/resources/7HOU57Y

  • GET :检索以适当的 MIME 类型表示的集合的寻址成员的表示。

  • PUT :更新集合的寻址成员或使用指定的 ID 创建它。

  • POST :将被寻址的成员本身视为一个集合,并为其创建一个新的下属。

  • DELETE :删除集合的寻址成员。


第 2 点:我需要更多动词

一般来说,当你认为你需要更多的动词时,实际上可能意味着你的资源需要重新识别。请记住,在 REST
中,您总是对资源或资源集合进行操作。您选择什么作为资源对于您的 API 定义非常重要。

激活/停用登录 :如果您正在创建一个新会话,那么您可能希望将“会话”视为资源。要创建新会话,请使用
POSThttp://example.com/sessions/和正文中的凭据。要使其过期,请使用 PUT 或
DELETE(可能取决于您是否打算保留会话历史记录)到http://example.com/sessions/SESSION_ID.

更改密码: 这次资源是“用户”。您需要一个 PUT
http://example.com/users/USER_ID处理正文中的旧密码和新密码。您正在对“用户”资源进行操作,更改密码只是一个更新请求。它与关系数据库中的
UPDATE 语句非常相似。

我的直觉是对像这样的 URL 进行 GET 调用 /api/users/1/activate_login

这违背了一个非常核心的 REST 原则:HTTP 动词的正确使用。任何 GET 请求都不应留下任何副作用。

例如,GET 请求不应该在数据库上创建会话、返回带有新会话 ID 的 cookie 或在服务器上留下任何残留物。GET 动词类似于数据库引擎中的
SELECT 语句。请记住,当使用相同的参数请求时,使用 GET 动词对任何请求的响应都应该是可缓存的,就像您请求静态网页时一样。


Point 3:如何返回错误信息和代码

将 4xx 或 5xx HTTP 状态代码视为错误类别。您可以详细说明正文中的错误。

无法连接到数据库: / 不正确的数据库登录 :通常您应该对这些类型的错误使用 500 错误。这是服务器端错误。客户没有做错任何事。500
个错误通常被认为是“可重试的”。即客户端可以重试相同的请求,并期望一旦服务器的问题得到解决,它就会成功。在正文中指定详细信息,以便客户端能够为我们人类提供一些上下文。

另一类错误是 4xx
系列,通常表明客户端做错了什么。特别是,此类错误通常向客户端表明无需按原样重试请求,因为它将继续永久失败。即客户端需要在重试此请求之前更改某些内容。例如,“找不到资源”(HTTP
404)或“格式错误的请求”(HTTP 400)错误就属于这一类。


第4点:如何进行身份验证

正如第 1 点所指出的,您可能需要考虑创建会话,而不是验证用户。您将收到一个新的“会话 ID”以及相应的 HTTP 状态代码(200:授予访问或
403:拒绝访问)。

然后你会问你的 RESTful 服务器:“你能给我这个 Session ID 的资源吗?”。

没有经过身份验证的模式 - REST 是无状态的:您创建一个会话,要求服务器使用此会话 ID 作为参数为您提供资源,然后在注销时删除或使会话过期。

2022-03-06