web-services - 理解REST 。 动词。 错误代码, 和身份验证

  显示原文与译文双语对照的内容

在我PHP-based网络应用程序,数据库和我正在( 作为的后续问题,这个问题) cmss,寻找一个方式把api围绕着预设等功能。

我查看了一下,发现了几个"骨骼"框架。 除了我的问题中的答案,还有主音,一个我喜欢的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

如何在rest式的URL架构中表达这些动作?

我的本能是对一个像


/api/users/1/activate_login 

还需要一个状态码。

这背离了使用HTTP动词的思想,尽管。 你怎么看?

3 。如何返回错误消息和代码

rest的美妙部分源于它使用标准的HTTP方法。 在一个错误中,我发出一个标题为 3 xx 4xx或者 5 xx错误状态代码的标头。 有关详细的错误描述,我可以使用正文( 右边) 。 在描述发生了什么错误( 例如g,的方式到现在为止一切不错,但是如何将是把讯息专有错误代码才真正 detailed. "连接到数据库",或者"数据库登录错误") 错误? 如果我将它连同消息一起放入正文,我必须在以后解析它。 这种事情有标准的标题?

4.。如何进行身份验证

  • 基于REST原则的基于API的认证是什么样子的?
  • 最强部分不要利用会话来讲一个REST客户端,除此之外,它有一个严重违背了违规进行身份验证时剩下的工作原理? :) ( 只在这里开玩笑,基于会话的身份验证与我现有的基础设施很好。)

的编辑:感谢你所有出色的响应。 我将在明天或者后天通过它们。

时间:

我在几天前注意到这个问题,但我觉得我可以添加一些洞察力。 我希望这对你的RESTful风险有帮助。


1: 我在理解这个点对

对,这是对RESTful架构的正确表示。 你可以从 Wikipedia中找到以下矩阵,这对定义你的名词和动词很有帮助:


当处理一个的集合时,比如:http://example.com/resources/

  • 获取 : 列出集合的成员,用它们的成员uri完成进一步导航。 例如列出所有要出售的汽车。

  • : 意义定义为"将整个集合替换为另一个集合"。

  • 邮递: 在集合中创建新的条目,其中ID是自动指定的集合中。 创建的标识通常作为这里操作返回的数据的一部分包含。

  • 删除: 定义为"删除整个收藏集"。


带有 成员 URI like,当 dealing:http://example.com/resources/7HOU57Y

  • 获取 : 获取以适当MIME类型表示的集合的寻址成员的表示形式。

  • 使用指定的id,: 更新寻址集合的成员或者创建上面注明日期的。

  • 帖子: 将解决的成员视为一个在自己的权利,并创建一个新的下属,它集合。

  • 删除 : 删除集合中已经寻址的成员。


2: 我需要更多的动词

通常,当你认为需要更多的动词时,这可能意味着你的资源需要是 re-identified 。 记住,在REST中,你总是在资源上或者在资源集合上扮演角色。 你选择的资源对于你的API定义来说非常重要。

开启/关闭登录,若要创建一个新的会话,那么你可能要考虑"会话"为资源。 要创建新会话,请使用POST到 http://example.com/sessions/,并使用正文中的凭据。 若要过期,请使用PUT放置( 可能取决于你是否要保留会话历史) 或者DELETE删除 to http://example.com/sessions/SESSION_ID

更改密码: 这一次该资源是"用户"。 在body,需要一颗把来与新旧 http://example.com/users/USER_ID passwords. 你正在使用"用户"资源,而更改密码只是一个更新请求。 它与关系数据库中的UPDATE语句非常相似。

我的本能是对一个像 /api/users/1/activate_login 这样的URL进行调用

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

例如获取请求绝不应在数据库上创建会话,用新会话标识返回 cookie,或者保留服务器上的任何剩余。 获取谓词与数据库引擎中的SELECT语句类似。 请记住,对任何请求的响应与请求get动词时应该cache-able以同样的参数,就像当你请求一个静态网页。


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

将 4 xx或者 5 xx HTTP状态代码视为错误类别。 你可以在正文中阐述这个错误。

连接到数据库时出错: 数据库登录错误/错误: 一般情况下,你应该对这些类型的错误使用 500错误。 这是一个server-side错误。 客户没有做错什么。 500错误通常被认为是"可以重试的"。 换句话说,客户端可以重试同样的请求,并期待一旦服务器故障解决,它就会成功。 指定详细信息给我们身体,以使客户端将能够提供一些上下文中人类。

在一般情况下表明该客户端做了一些事,在其他类别的错误将是生态 wrong, 4 xx族,which. 特别是,这一类的错误通常指示向客户阐明永久没有必要重试这里请求,因为它是,因为它将继续失败。 换句话说,客户端在重试这里请求之前需要更改某些内容。 例如"未找到资源"( HTTP 404 ) 或者"格式错误的请求"( HTTP 400 ) 错误将在这里类别中出现。


阶段 4: 如何做身份验证

如被指出在点在于 1,而不是验证一个用户,你可能需要考虑创建一个会话。 你将返回一个新的"会话标识",以及适当的HTTP状态代码( 200: 授予访问权限或者 403: 拒绝访问。

然后你将询问你的RESTful服务器: "你能给我这个会话标识的资源"。

没有经过身份验证的模式- REST是无状态的: 在每次退出时你放或者过期session,才创建会话、你让服务员再给你资源使用这个会话ID作为参数和。

1 ,你对如何设计资源有正确的想法,敬请谅解。 我不会改变什么。

2,而不是试图用更多的动词扩展 HTTP,考虑你建议的谓词可以减少到基本的HTTP方法和资源。 例如你可以设置以下资源,而不是 activate_login 动词: /api/users/1/login/active 是一个简单的布尔值。 要激活一个登录,只需 PUT 一个文档,上面写着'真'或者 1或者其他。 若要停用,PUT 一个文档集合复制的元素存在或者说 0或者假。

类似地,要更改或者设置密码,只需执行 PUT/api/users/1/password

每当你需要添加( 像一个信用卡)的时候,你就可以用 POST 来思考。 例如你可以选择一个对某个资源比如 /api/users/1/creditsPOST 在一个主体中包含要添加的学分的数量。 可以使用同一资源上的PUT 覆盖值而不是添加。 带有负数的POST 将减去,以此类推。

3 。 让我强烈地建议跨多个扩展基本的HTTP状态码。 如果你找不到与你的情况相符的,请选择最近的,并将错误细节放入响应正文。 另外,记住HTTP头是可以扩展的;你的应用程序可以定义你喜欢的所有自定义标题。 例如我工作的一个应用程序可以在多个环境下返回一个 404 Not Found 。 让客户端解析响应正文不同,我们只添加了一个新的标头 X-Status-Extended,它包含了我们的专有状态代码扩展。 因此,你可能会看到如下响应:


HTTP/1.1 404 Not Found 
X-Status-Extended: 404.3 More Specific Error Here

这样,像web浏览器这样的HTTP客户端仍然知道如何处理常规 404代码,而更复杂的HTTP客户端可以选择查看 X-Status-Extended 标头以获得更具体的信息。

用于身份验证的4 ,如果可以,我建议使用HTTP身份验证。 但是,如果你觉得这一点很容易,那么使用cookie-based认证就没什么问题了。

对于你所声明的示例,我将使用以下内容:

activate_login

POST/users/1/activation

deactivate_login

DELETE/users/1/activation

change_password

PUT/passwords ( 假定用户已经被验证)

add_credit

POST/credits ( 假定用户已经被验证)

对于错误,你将在正文中以你收到请求的格式返回错误,如果收到:

DELETE/users/1.xml

你将用XML发送响应,对于 JSON 等等,这将是一样的。

对于身份验证,你应该使用http身份验证。

我建议( 作为第一步) 只用于更新现有实体。 POST 应该用于创建新的。 i.e.


/api/users when called with PUT, creates user record

不适合我。 你的第一段其余部分( 。 动词用法) 看起来很合理。

...