RESTful设计/登录或/注册资源?

Qco*_*com 109 api rest web-services http restful-url

我正在设计一个Web应用程序,然后停下来考虑如何将我的api设计为RESTful Web服务.目前,我的大部分URI都是通用的,可能适用于各种网络应用:

GET  /logout   // destroys session and redirects to /
GET  /login    // gets the webpage that has the login form
POST /login    // authenticates credentials against database and either redirects home with a new session or redirects back to /login
GET  /register // gets the webpage that has the registration form
POST /register // records the entered information into database as a new /user/xxx
GET  /user/xxx // gets and renders current user data in a profile view
POST /user/xxx // updates new information about user
Run Code Online (Sandbox Code Playgroud)

我有一种感觉,我在这里搜索SO和谷歌后做了很多错.

从开始/logout,也许因为我什么都没有GET- 它可能更适合于POST请求/logout,销毁会话,然后GET重定向.这个/logout词应该留下来吗?

怎么样/login/register.我可以改变/register,/registration但这不会改变我的服务从根本上起作用的方式 - 如果它有更深层次的问题.

我现在注意到我从未暴露过/user资源.也许这可以以某种方式利用.例如,带上用户myUser:

foo.com/user/myUser
Run Code Online (Sandbox Code Playgroud)

要么

foo.com/user
Run Code Online (Sandbox Code Playgroud)

最终用户不需要URI中的额外详细程度.但是,哪一个在视觉上更吸引人?

我在这里注意到关于这个REST业务的一些其他问题,但如果可能的话,我真的很感谢我在这里提出的一些指导.

谢谢!

更新:

我还想听些意见:

/user/1
Run Code Online (Sandbox Code Playgroud)

VS

/user/myUserName
Run Code Online (Sandbox Code Playgroud)

ndp*_*ndp 114

RESTful可以用作构建URL的指南,您可以创建会话用户资源:

  • GET /session/new 获取具有登录表单的网页
  • POST /session 根据数据库验证凭据
  • DELETE /session 销毁会话并重定向到/
  • GET /users/new 获取具有注册表单的网页
  • POST /users 将输入的信息作为新的/ user/xxx记录到数据库中
  • GET /users/xxx //在配置文件视图中获取并呈现当前用户数据
  • POST /users/xxx //更新有关用户的新信息

这些可以是复数或单数(我不确定哪一个是正确的).我通常用于/users用户索引页面(如预期的那样),并/sessions查看谁登录(按预期方式).

使用URL中的名称而不是数字(/users/43vs. /users/joe)通常是希望对用户或搜索引擎更友好,而不是任何技术要求.要么很好,但我建议你保持一致.

我认为如果你使用注册/登录/注销,或者sign(in|up|out)它与其余的术语不兼容.

  • 确实是休息是让自己不快乐的一种方式,并且浪费时间在完全无关紧要的事情上. (7认同)
  • 真棒!我喜欢你用这些资源的名词; 那很干净.虽然,从我所听到的,并没有将`/ new`附加到`GET/session /`non RESTful?我听说动词通常留给HTTP动词(`GET`,`POST`等). (6认同)
  • 就个人而言,我不喜欢使用返回表单(/ new)的路由.这打破了视图和业务逻辑之间的分离.Tha说,没有/新路线,建议的一个看起来很完美. (5认同)
  • @Zach new不是动词.在这种情况下,它是会话的子资源. (2认同)

ell*_*ben 57

有一点特别突出,因为没有REST-ful:使用GET请求注销.

(来自http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Safe_methods)

某些方法(例如,HEAD,GET,OPTIONS和TRACE)被定义为安全,这意味着它们仅用于信息检索,不应更改服务器的状态.换句话说,它们不应该具有副作用,除了相对无害的效果,例如日志记录,缓存,横幅广告的提供或递增网络计数器.[...]

服务器的[... H] andling [GET请求]在技术上不受任何限制.因此,粗心或有意的编程可能会导致服务器上的重大变化.这是不鼓励的,因为它可能导致Web缓存,搜索引擎和其他自动代理[...]的问题

对于注销和重定向,您可以在注销URI上发布一个帖子,将303响应重定向到注销后页面.

http://en.wikipedia.org/wiki/Post/Redirect/Get

http://en.wikipedia.org/wiki/HTTP_303

编辑以解决URL设计问题:

"我如何设计我的资源?" 对我来说是一个重要的问题; "我该如何设计我的网址?" 是两个方面的考虑因素:

如果可能,用户将看到的URL不应该太丑陋和有意义; 如果您希望将cookie发送到某些资源而不是其他资源,您需要构建路径和cookie路径.

如果JRandomUser想要查看自己的个人资料,并且您希望URL比foo.com/user/JRandomUseror 更漂亮foo.com/user/(JRandom's numeric user id here),您可以创建一个单独的URL,供用户查看自己的信息:

GET foo.com/profile /*examines cookies to figure out who 
                     * is logged in (SomeUser) and then 
                     * displays the same response as a
                     * GET to foo.com/users/SomeUser.
                     */
Run Code Online (Sandbox Code Playgroud)

在这个问题上我会比智慧更容易宣称无知,但这里有一些资源设计考虑因素:

  1. 消费者:哪些资源可以直接在浏览器中查看,通过XHR加载,或者由其他类型的客户端访问?
  2. 访问/身份:响应是否依赖于cookie或引用?

  • 啊,我想我现在看到了.莫莫的回答确实让事情变得清晰起来.因此构建RESTful API以允许多个平台"GET","POST","PUT"和"DELETE"资源.网站只是访问API的另一个平台.换句话说,网站URL设计与RESTful API设计完全不同.请告诉我,如果我还是错的话哈哈. (2认同)

die*_*dha 54

会话不是RESTful

  • 是的我知道.它正在完成,通常使用OAuth,但实际上会话不是RESTful.您不应该主要拥有/ login/logout资源,因为您不应该有会话.

  • 如果您要这样做,请将其设为RESTful.资源是名词,/ login和/ logout不是名词.我会和/ session一起去.这使得创建和删除成为更自然的动作.

  • POST与GET的会话很容易.如果您将用户/密码作为变量发送,我会使用POST,因为我不希望将密码作为URI的一部分发送.它将显示在日志中,并可能通过电线暴露.您还冒着让GET args限制软件失败的风险.

  • 我通常使用Basic Auth或没有使用REST服务的Auth.

创建用户

  • 它是一种资源,因此您不需要/注册.

    • POST/user - 如果请求者无法指定id,则创建用户
    • PUT/user/xxx - 假设您事先知道id,创建或更新用户
    • GET/user - 列出x个用户ID
    • GET/user/xxx - 获取id为xxx的用户的详细信息
    • DELETE/user/xxx - 删除id为xxx的用户
  • 使用哪种ID是一个难题.你必须考虑强制执行唯一性,关于重复使用DELETEd的旧ID.例如,如果要回收id(如果可能的话),则不希望在后端使用这些id作为外键.您可以查找外部/内部ID转换,以减轻后端要求.

  • 这是最好的答案./ login和/ logout不是资源,打破了REST的想法. (6认同)
  • 身份验证!=会话 (5认同)
  • 实际上,/login 和/logout 是名词。我假设您正在考虑 /log_in 和 /log_out。 (4认同)
  • “会话不是RESTful的,因此不使用身份验证”。好吧... (2认同)
  • “我会选择 /session。这使得创建和删除变得更加自然。” 我同意这一点,但是应该使用哪个 HTTP 动词来登录(即启动会话)?得到?邮政?放?假设 DELETE 用于注销。 (2认同)

mom*_*omo 20

我将简单地谈谈我为我的客户集成各种REST Web服务的经验,无论是用于移动应用程序还是用于服务器到服务器的通信,以及为其他人构建REST API.以下是我从其他人的REST API以及我们自己构建的REST API中收集的一些观察结果:

  • 当我们说API时,它通常是指编程接口的集合而不是表示层.REST也是以数据为中心而不是表示驱动的.这就是说大多数REST以JSON或XML的形式返回数据,很少返回特定的表示层.这种特性(返回数据,而不是直接网页)给予REST进行多渠道交付的能力.这意味着可以在HTML,iOS,Android中呈现相同的Web服务,甚至可以用作服务器到服务器的组合.
  • 将HTML和REST结合为URL非常罕见.默认情况下,REST是思想作为服务而没有表示层.对于那些使用Web服务来根据他们想要的方式从他们调用的服务中呈现数据的人来说,这是一项工作.到目前为止,您的URL不符合我迄今为止遇到的大多数基于REST的设计(也不符合来自Facebook或Twitter的标准)
GET  /register // gets the webpage that has the registration form
  • 继续前一点,基于REST的服务进行重定向(例如下面建议的那样)也是不常见的(我没有遇到过):
GET  /logout   // destroys session and redirects to /
POST /login    // authenticates credentials against database and either redirects home with a new session or redirects back to /login
 

由于REST被设计为服务,因此诸如登录和注销之类的功能通常返回成功/失败结果(通常以JSON或XML数据格式),然后消费者将解释该结果.如您所述,此类解释可能包括重定向到适当的网页

  • 在REST中,URL表示所采取的操作.出于这个原因,我们应尽可能消除歧义.虽然在您的情况下让GET和POST具有执行不同操作的相同路径(例如/ register)是合法的,但这样的设计会在所提供的服务中引入歧义,并且可能会使您的服务的消费者感到困惑.例如,下面介绍的URL对于基于REST的服务并不理想
GET  /register // gets the webpage that has the registration form
POST /register // records the entered information into database as a new /user/xxx

这些是我所处理的一些要点.我希望它可以为您提供一些见解.

现在,就REST的实现而言,这些是我遇到的典型实现:

  • GET  /logout  
    

    在后端执行注销并返回JSON以表示操作的成功/失败

  • POST /login
    

    将凭据提交到后端.返回成功/失败.如果成功,通常它还将返回会话令牌以及配置文件信息.

  • POST /register
    

    提交注册到后端.返回成功/失败.如果成功,通常将其视为成功登录,或者您可以选择将注册作为不同的服务

  • GET  /user/xxx
    

    获取用户配置文件并返回用户配置文件的JSON数据格式

  • POST /user/xxx 
    // renamed to 
    POST /updateUser/xxx
    

    将更新的配置文件信息发布为JSON格式并更新后端中的信息.将成功/失败返回给调用者

  • GET /注销很危险.GET应该是幂等的.浏览器也喜欢预取<a> hrefs,它会让你退出! (11认同)
  • 是的,如果您正在将REST API与基于HTML的应用程序(通过Javascript和AJAX)集成,那么JSON将由Javascript本地解析,您将获得巨大的好处.在Android/Java中,与XML相比,JSON更容易解析. (3认同)

Cha*_*ehn 5

我相信这是一种 RESTful 身份验证方法。对于登录,您使用HttpPut. 这个HTTP方法可以在提供key的情况下进行创建,重复调用是幂等的。对于注销,您在HttpDelete方法下指定相同的路径。没有使用动词。适当的集合多元化。HTTP 方法支持该目的。

[HttpPut]
[Route("sessions/current")]
public IActionResult LogIn(LogInModel model) { ... }

[HttpDelete]
[Route("sessions/current")]
public IActionResult LogOff() { ... }
Run Code Online (Sandbox Code Playgroud)

如果需要,您可以用 current 代替 active。