restful 的一个网站设计问题

2015-04-23 15:03:28 +08:00
 gkiwi

最近想尝试用restful构建新的项目,但是遇到了几个疑问点,求有经验的兄弟来帮忙解解惑.

  1. 我封装了一个restful的接口(api),那么网站html该怎么被请求/渲染呢?

    我设想的是,restful单独启动一个服务,然后用nginx直接映射到template目录,然后通过api请求数据,使用前端模板进行渲染,大家是否这样子?还是有更好的方法?

  2. 在上面1的理解上上我在网上搜了下,发现了这个http://segmentfault.com/q/1010000000187725 ,大意是说刚刚的1中设想比较浪费资源,其建议是抽离出一层用于封装业务逻辑,只不过有些接口单独的提供api,一些接口负责将后端渲染好的html吐给前端.但是这个也有几点疑问:

    1. 这样子需要单独维护api侧和html渲染侧,其实无非是在原来的非restful设计基础上又整理出了api接口,业务量会增加不少,似乎后期维护也会多些体力,我有些现有的代码就是这样子的.
    2. 正如上侧所说,后端渲染的html页面吐给web端,web端不可避免的需要ajax请求,这个时候似乎又需要再封装一些纯吐json数据的接口,特别是在需要授权的时候,此处是通过cookie有状态的ajax请求,其与restful的无状态有概念上的一些冲突,这个ajax改怎么处理才合适?
  3. 如果大家知道开源restful项目,还请给予推荐,让俺学习学习,谢谢(以python的最佳).

5019 次点击
所在节点    问与答
29 条回复
mytharcher
2015-04-23 17:25:01 +08:00
题主所说的需求其实最主要是在响应的时候根据请求头中的 accept 字段来进行判断输出就好了。这是 HTTP 协议的标准方法,比如 express 框架 4.0+ 就支持了: http://expressjs.com/4x/api.html#res.format

举个例子,对同一个资源的 GET 访问: http://yourhost.com/employee ,如果在请求头里的 accept 指明了 application/json 那么就返回 JSON 数据,否则浏览器默认最大概率是 text/html 这样就可以判断返回渲染好的网页。

多维度(method/accept/content-type等)的区分控制才是 RESTful 的正道。至于上面说的用 token 保持状态,其实和 cookie 区别不大,对浏览器来说还要自己维护过期时间,所以不如直接 token 放 cookie 里。
gkiwi
2015-04-23 18:56:18 +08:00
@mytharcher 学习了,利用accept作区分确实是一种很好地思路.
不过我的起始困惑是:在html页面渲染上,由前端渲染还是后端渲染,两种情况下的授权机制该怎么处理才比较合适的问题.


token若是存在cookie里面,给我的感觉和session没啥区别了,都是本地拿着一个认证key.
觉得token存在localStorage似乎更好些,因为存在cookie里面就不叫无状态了...

restful设计思路目前来看一个好处就是不需要ios/android/wp等各平台自家的应用维护cookie.而且token的周期应该由服务器来维护,而不是浏览器.
mytharcher
2015-04-23 19:50:30 +08:00
前端渲染和后端渲染主要看需求,比如需要 SEO 那就后端渲染,否则现在大规模的 Angular 等框架全是在前端渲染的。而且这跟授权机制好像没有太大的联系,这类非内容的文件,基本就是和 js/css 一样归为任何人可见 assets 的。

至于 token 存在 cookie 里,和你存在 localStorage 里唯一的区别就是过期时间,如果你后端直接忽略掉 cookie 内容,那就变成无状态的了。有自动管理过期时间的 cookie,那就没必要折腾一套东西来专门处理,而且反正你都要放在 header 里。
armoni
2015-04-23 20:57:13 +08:00
用nodeJS渲染吧,nodejs里调用rest api获取json,渲染到HTML,就是angular写的头疼
armoni
2015-04-23 20:58:59 +08:00
@gkiwi 存在localStorage里
gkiwi
2015-04-23 22:37:44 +08:00
@mytharcher

其实使用angularjs,在SEO这块有种解决方案,就是在判断出是搜索引擎时候,专门吐出一些不带样式的网页,不过从pagerank算法来讲,这个显然是不太好,而且据说有一定几率会被搜索引擎识别为作弊而封掉.

token放在cookie不读取,你这块的意思是每次想后端api请求时候,现在浏览器端读取token然后作为参数传到后台么?如果是这个,那确实是无状态的了,哈哈~
不过有几个缺点:
1. 每次cookie都被请求带着,占用带宽,特别是有很多同域图片时候,每次请求都带着cookie就有点过分了,这个也是设计restful的一个原因(?优势?).
2. 后端做token时间管理是基本上必不可少的,因为还得考虑安卓/IOS/WP之类的app端.可以参照这个帖子:/t/148426 .因为在每个平台的app都维护一套时间管理显然成本更高.

当然啦,目前我要做的项目只有web端,token放哪里都可以了.目前尽量按照restful的标准来就是纯为练练手:)
gkiwi
2015-04-23 22:38:45 +08:00
@armoni 每次想去学习angularjs都头疼...localStorage最好不过:)
mytharcher
2015-04-24 09:05:26 +08:00
需要用前端 history API 且 SEO 这事其实主要是改造服务端,添加 rewrite 规则以及里用 accept 吐不同类型的结果才是正道。至于 Google 愿不愿意去解析执行 JS 后再索引那是另一回事。

服务端忽略 cookie 这里更正一下,这个说法其实我说的不准确,后面补充说。但是 token 放 cookie 里是没有问题的,如果你不用 cookie,那么无论如何也要找地方来放,放 query 里肯定是不合适,所以一般是用 header 里的字段,比如 Authorization,而且图片等静态资源一般通过 CDN 来区别域名,所以不存在占用带宽的区别。除了 cookie 的 HTTP 头浏览器都不会在本地自动保存并过期失效,那么有现成的东西就没必要去另外实现一套机制。即使在其他客户端(原生),自己实现从头里取另一个字段保存并设置有效时间,和取 cookie 没有本质的区别。

补充说 cookie 到服务端的情况,服务端拿到请求头以后,无非也就是一个字段,至于 session 是如何实现的那是另一码事,可以放程序内存(单机),也可以放数据库(多机)。而且就算号称是无状态的,没有 session 怎样验证 token 的有效期和合法性?实际上我在另一个关于 RESTful 的帖子( /t/118049 )里就说过关于用户获取授权的请求问题 ,登入其实就是一个 POST /session 的请求,用以在服务端的 session 记录中新增一个项目,之后用以验证查询。所以无状态之说,现在想来根本不现实,除非客户端和服务端都永久保存 session 的 token,就像 ssh-key 一样。

至于你提到的 /t/148426 帖子里最后大家的结论其实一样 token 和 session 根本不是一个层面的事情。
gkiwi
2015-04-24 14:39:53 +08:00
@mytharcher

关于SEO我俩应该没啥分期.

我觉得你可能忽略了客户端单独维护cookie的成本~

对于token的每次请求存哪里(cookie,header,每次查询时候待在参数里面),网上各种例子都有,比如将token放在每次查询到串里:
http://stackoverflow.com/questions/25327476/implementing-an-restful-api-authentication-using-tokens-yii
这个app端不需要任何的时间管理处理,只要在第一次登陆时候,服务器返回一个token数据,开发人员将其存在本地存储即可.
至于你后面说的,"没有 session 怎样验证 token 的有效期和合法性"这个建议你看看这个:
https://github.com/miguelgrinberg/REST-auth/blob/master/api.py
无状态是指的client端:)
token和session的区别异同,
建议看看这个:
https://auth0.com/blog/2014/01/27/ten-things-you-should-know-about-tokens-and-cookies/
至于是不是一个层面,这个得看所指的深度了,看清本质就好了,个人有个人的看法,无法统一.

谢谢一起扯皮了这么久,自己对这块的理解也有新的认识:)

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/185717

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX