了解 REST:动词、错误代码和身份验证 [英] Understanding REST: Verbs, error codes, and authentication

查看:23
本文介绍了了解 REST:动词、错误代码和身份验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

我最喜欢 REST,因为它的简单性,并希望基于它创建一个 API 架构.我正在努力了解基本原则,但尚未完全理解.因此,有一些问题.

1.我理解对了吗?

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

/api/users 当用 GET 调用时,列出用户/api/users 当用 POST 调用时,创建用户记录/api/users/1 使用 GET 调用时,显示用户记录当用 PUT 调用时,更新用户记录当用 DELETE 调用时,删除用户记录

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

2.我需要更多动词

Create、Update 和 Delete 理论上可能就足够了,但在实践中我将需要更多的动词.我意识到这些内容可以嵌入到更新请求中,但它们是具有特定返回码的特定操作,我不想将它们全部放入一个操作中.

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

activate_login停用_登录更改密码添加信用

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

我的直觉是对像

这样的 URL 进行 GET 调用

/api/users/1/activate_login

并期待返回状态代码.

不过,这与使用 HTTP 动词的想法背道而驰.你怎么看?

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

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

4.如何进行身份验证

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

解决方案

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

<小时>

第 1 点:我理解正确吗?

你理解正确.这是 RESTful 架构的正确表示.您可能会发现维基百科中的以下矩阵对定义您的名词和动词非常有帮助:><小时>

处理集合 URI 时,例如:http://example.com/resources/

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

  • PUT:含义定义为用另一个集合替换整个集合".

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

  • DELETE:含义定义为删除整个集合".

<小时>

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

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

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

  • POST:将被寻址的成员视为一个集合,并为其创建一个新的下级.

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

<小时>

第 2 点:我需要更多动词

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

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

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

<块引用>

我的直觉是进行 GET 调用到一个像/api/users/1/activate_login

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

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

<小时>

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

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

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

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

<小时>

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

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

然后你会问你的 RESTful 服务器:你能给我这个会话 ID 的资源吗?".

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

I am looking for a way to wrap APIs around default functions in my PHP-based web applications, databases and CMSs.

I have looked around and found several "skeleton" frameworks. In addition to the answers in my question, there is Tonic, a REST framework I like because it is very lightweight.

I like REST the best for its simplicity, and would like to create an API architecture based on it. I'm trying to get my head around the basic principles and have not fully understood it yet. Therefore, a number of questions.

1. Am I understanding it right?

Say I have a resource "users". I could set up a number of URIs like so:

/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

is this a correct representation of a RESTful architecture so far?

2. I need more verbs

Create, Update and Delete may be enough in theory, but in practice I will have the need for a lot more verbs. I realize these are things that could be embedded in an update request, but they are specific actions that can have specific return codes and I wouldn't want to throw them all into one action.

Some that come to mind in the user example are:

activate_login
deactivate_login
change_password
add_credit

how would I express actions such as those in a RESTful URL architecture?

My instinct would be to do a GET call to a URL like

/api/users/1/activate_login 

and expect a status code back.

That deviates from the idea of using HTTP verbs, though. What do you think?

3. How to return error messages and codes

A great part of REST's beauty stems from its use of standard HTTP methods. On an error, I emit a header with a 3xx,4xx or 5xx error status code. For a detailed error description, I can use the body (right?). So far so good. But what would be the way to transmit a proprietary error code that is more detailed in describing what went wrong (e.g. "failed to connect to database", or "database login wrong")? If I put it into the body along with the message, I have to parse it out afterwards. Is there a standard header for this kind of thing?

4. How to do authentication

  • What would a API key based authentication following REST principles look like?
  • Are there strong points against using sessions when authenticating a REST client, other than that it's a blatant violation of the REST principle? :) (only half kidding here, session based authentication would play well with my existing infrastructure.)

解决方案

I noticed this question a couple of days late, but I feel that I can add some insight. I hope this can be helpful towards your RESTful venture.


Point 1: Am I understanding it right?

You understood right. That is a correct representation of a RESTful architecture. You may find the following matrix from Wikipedia very helpful in defining your nouns and verbs:


When dealing with a Collection URI like: http://example.com/resources/

  • GET: List the members of the collection, complete with their member URIs for further navigation. For example, list all the cars for sale.

  • PUT: Meaning defined as "replace the entire collection with another collection".

  • POST: Create a new entry in the collection where the ID is assigned automatically by the collection. The ID created is usually included as part of the data returned by this operation.

  • DELETE: Meaning defined as "delete the entire collection".


When dealing with a Member URI like: http://example.com/resources/7HOU57Y

  • GET: Retrieve a representation of the addressed member of the collection expressed in an appropriate MIME type.

  • PUT: Update the addressed member of the collection or create it with the specified ID.

  • POST: Treats the addressed member as a collection in its own right and creates a new subordinate of it.

  • DELETE: Delete the addressed member of the collection.


Point 2: I need more verbs

In general, when you think you need more verbs, it may actually mean that your resources need to be re-identified. Remember that in REST you are always acting on a resource, or on a collection of resources. What you choose as the resource is quite important for your API definition.

Activate/Deactivate Login: If you are creating a new session, then you may want to consider "the session" as the resource. To create a new session, use POST to http://example.com/sessions/ with the credentials in the body. To expire it use PUT or a DELETE (maybe depending on whether you intend to keep a session history) to http://example.com/sessions/SESSION_ID.

Change Password: This time the resource is "the user". You would need a PUT to http://example.com/users/USER_ID with the old and new passwords in the body. You are acting on "the user" resource, and a change password is simply an update request. It's quite similar to the UPDATE statement in a relational database.

My instinct would be to do a GET call to a URL like /api/users/1/activate_login

This goes against a very core REST principle: The correct usage of HTTP verbs. Any GET request should never leave any side effect.

For example, a GET request should never create a session on the database, return a cookie with a new Session ID, or leave any residue on the server. The GET verb is like the SELECT statement in a database engine. Remember that the response to any request with the GET verb should be cache-able when requested with the same parameters, just like when you request a static web page.


Point 3: How to return error messages and codes

Consider the 4xx or 5xx HTTP status codes as error categories. You can elaborate the error in the body.

Failed to Connect to Database: / Incorrect Database Login: In general you should use a 500 error for these types of errors. This is a server-side error. The client did nothing wrong. 500 errors are normally considered "retryable". i.e. the client can retry the same exact request, and expect it to succeed once the server's troubles are resolved. Specify the details in the body, so that the client will be able to provide some context to us humans.

The other category of errors would be the 4xx family, which in general indicate that the client did something wrong. In particular, this category of errors normally indicate to the client that there is no need to retry the request as it is, because it will continue to fail permanently. i.e. the client needs to change something before retrying this request. For example, "Resource not found" (HTTP 404) or "Malformed Request" (HTTP 400) errors would fall in this category.


Point 4: How to do authentication

As pointed out in point 1, instead of authenticating a user, you may want to think about creating a session. You will be returned a new "Session ID", along with the appropriate HTTP status code (200: Access Granted or 403: Access Denied).

You will then be asking your RESTful server: "Can you GET me the resource for this Session ID?".

There is no authenticated mode - REST is stateless: You create a session, you ask the server to give you resources using this Session ID as a parameter, and on logout you drop or expire the session.

这篇关于了解 REST:动词、错误代码和身份验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆