最近想尝试用restful构建新的项目,但是遇到了几个疑问点,求有经验的兄弟来帮忙解解惑.
我封装了一个restful的接口(api),那么网站html该怎么被请求/渲染呢?
我设想的是,restful单独启动一个服务,然后用nginx直接映射到template目录,然后通过api请求数据,使用前端模板进行渲染,大家是否这样子?还是有更好的方法?
在上面1的理解上上我在网上搜了下,发现了这个http://segmentfault.com/q/1010000000187725 ,大意是说刚刚的1中设想比较浪费资源,其建议是抽离出一层用于封装业务逻辑,只不过有些接口单独的提供api,一些接口负责将后端渲染好的html吐给前端.但是这个也有几点疑问:
- 这样子需要单独维护api侧和html渲染侧,其实无非是在原来的非restful设计基础上又整理出了api接口,业务量会增加不少,似乎后期维护也会多些体力,我有些现有的代码就是这样子的.
- 正如上侧所说,后端渲染的html页面吐给web端,web端不可避免的需要ajax请求,这个时候似乎又需要再封装一些纯吐json数据的接口,特别是在需要授权的时候,此处是通过cookie有状态的ajax请求,其与restful的无状态有概念上的一些冲突,这个ajax改怎么处理才合适?
如果大家知道开源restful项目,还请给予推荐,让俺学习学习,谢谢(以python的最佳).
1
scys 2015-04-23 15:10:31 +08:00 1
提供API的接口,尽量不提供任何HTML页面服务。
分开两种服务的负载。 |
2
learnshare 2015-04-23 15:14:29 +08:00 1
RESTFul 是 API,只有数据接口,跟页面毫无关系。
页面可以是静态文件(jQuery/Angular.js),然后在 JS 中请求 API 中的数据,并展示到页面中(这种方式和 App 类似,Android/iOS 与 Web 可以共享同一套 API); 也可以是另一个后端服务,这个后端负责请求 API 并渲染页面(这样就是两个后端了)。 http://www.django-rest-framework.org/ 是一个 django 的框架,可以用来做 RESTful API。其中也附带了一个调试 API 的 Web 工具,可以参考。 |
3
gkiwi OP @scys 谢谢.不过还是有点小问题想问下:
假设restful服务称为A,html页面我单独启一个服务(比如B)进行处理,那渲染呢?是 1. 我在B端就直接调用A服务进行渲染,然后再吐给用户 2. 还是直接将html文件扔给用户,然后在浏览器端通过js进行前端渲染? 这两个哪个比较好? 按我的理解,似乎用2比较方便,但是如此的话,登陆怎么办?因为restful没状态,我该怎么保存用户的认证呢?把认证后的token存在localStorage或者cookie中么? 求解惑:) |
4
learnshare 2015-04-23 15:22:45 +08:00 1
RESTful 的 API 可以通过 token 的方式完成用户认证,就是每个登录过的用户在请求时都通过这个 token 来辨认。
>单独维护api侧和html渲染侧 是否使用 RESTful 方式,甚至是后端 API 方式,要看具体的应用场景。RESTful 只能提供访问数据库的一个个 API,使 Web/App 端可以与后端彻底分离,让第二个人单独开发都可以。如果 Web 的渲染也用后端做,那就需要两个后端(API 和渲染)来支持了。 >后端渲染的html页面吐给web端,web端不可避免的需要ajax请求 好像没有啥关系 |
5
gkiwi OP @learnshare 谢谢.
麻烦请参考下第三条的回复, 如果再起个服务进行页面渲染的的话,那么权限认证该怎么处理好呢?因为html端显然是通过cookie存储比较方便,那么这个服务B,请求restful服务A的时候,用什么做认证呢?像我上面说的将token存在cookie里面是否靠谱? |
6
learnshare 2015-04-23 15:27:33 +08:00 1
@gkiwi 再展开说说 token 的认证方式。
1. 所有要求登录后才能访问的 API 都必须携带有效的 token 来访问,否则就要求用户去登录; 2. 登录 API 可以 POST api_url/login {user, pswd},然后返回 {token},可以存到 cookie/localStorage 等位置。 token 的方式该如何控制安全性,可以自己多思考吧。 |
7
gkiwi OP @learnshare 为什么总比你慢半拍!!!
大概了解了,确实再把html渲染交给后端,似乎就浪费了前端分离的优势了.知道该怎么做了,非常感谢:) 多加个问题,token每次由用户端发送,特别是某些GET请求时候,安全性有啥办法处理么?https? |
8
gkiwi OP |
9
learnshare 2015-04-23 15:35:41 +08:00 1
@gkiwi 使用 RESTful 来写 API 之后,前端页面有两种方式来做:
1. 用另一个后端调用 API 来渲染; 2. 纯前端渲染,Ajax 等方式调用 API。 在某种程度上说,方式 1 不符合后端 API 化的目的(都已经写成 API 了,还要渲染页面干嘛)。不过后端渲染的方式也有其优势(性能高一些等); 方式 2 就是将前端写成一个 WebApp,和写一个 Android/iOS App 类似的方式,通过 Ajax 等手段来访问 API。这种方式彻底分离了前后端,可以交给不同的人来做,相互之间都不用了解实现细节,只通过 API 文档沟通就可以了。 当然,也有一些前后端同时做页面渲染的技术,门槛高,没玩过。 |
10
learnshare 2015-04-23 15:36:57 +08:00
@gkiwi 慢半拍是因为我在补充自己,而不是回复你的问题 √
|
11
gkiwi OP @learnshare 确实如你所说的,似乎再用后端来渲染html不大合适,之前老想着认证这块,所以就痛哭了..
前后端渲染我用后端jinja2+前端vuejs做过一个web离线订单的处理,因为考虑纯离线的web操作,只能用前端框架做数据绑定和渲染,不过最后前端性能出了问题... |
12
gkiwi OP @learnshare 一起学习进步:)
|
13
caixiexin 2015-04-23 15:51:04 +08:00
感觉像是在纠结是不是完全遵守RESTful设计网站,我刚接触的时候也有这种纠结 = =
用前端html模板渲染的方式还是后端渲染再吐给用户的方式? 看你的应用场景吧,我记得前端渲染一般都是单页型应用(Gmail,笔记网页版什么的),前端技术好的话可以做到很多酷炫的webapp,用上前端mvc框架还能做出兼容各种设备的响应试应用。但是有几个缺点:页面渲染慢,项目刚开始前端工作量比后端大,SEO支持不好什么的。传统后端渲染的优缺点就跟它相反了。业务复杂的站点肯定根据实际需求两种都会用到的。 个人觉得RESTful只是种http的资源设计风格,严格遵守的话,会束手束脚的。个人学习的话,多做些尝试或许能更明白一些。 我也半桶水,希望没说错:( |
14
caixiexin 2015-04-23 16:07:10 +08:00
还有登录认证问题,我觉得就是因为要保证RESTful资源的无状态,才会有token的存在啊,因为它没有任何状态数据,只是个票据而已。
RESTful的安全控制,具体可以参考下目前各大开放平台使用的OAuth2.0方式。 |
15
clino 2015-04-23 16:12:27 +08:00
我现在用uliweb+avalonjs写web应用的时候都是用这种方式,后端大部分只是提供api, javascript 的代码比后端的多不少
问题1,用avalonjs这种mvvm类型的刷新从api获取到的内容的时候只要管更新数据就可以了,用这类框架开发效率较高 问题2.2,对于我这里的情况,api接口和其他的接口没什么差别,一样可以用session来鉴别用户,当然不用这个用其他的机制也可以 |
16
gkiwi OP @caixiexin 不能赞同更多.
我也是最近有些空闲,自己做个新项目,就想用restful练练手,学习下restful和angularjs. 不过每次看到angularjs.cn网站我就有些蛋疼,毕竟主要内容需要0.5-1秒后才出现... |
17
gkiwi OP |
18
learnshare 2015-04-23 16:44:40 +08:00 1
@caixiexin 响应试 -> 响应式 和 MVC 没关系,甚至可以跟 JS 没关系
|
20
caixiexin 2015-04-23 17:17:14 +08:00
@learnshare 啊。。抱歉,确实说错了,后端做多了,前端苦手,见谅:)
|
21
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 里。 |
22
gkiwi OP @mytharcher 学习了,利用accept作区分确实是一种很好地思路.
不过我的起始困惑是:在html页面渲染上,由前端渲染还是后端渲染,两种情况下的授权机制该怎么处理才比较合适的问题. token若是存在cookie里面,给我的感觉和session没啥区别了,都是本地拿着一个认证key. 觉得token存在localStorage似乎更好些,因为存在cookie里面就不叫无状态了... restful设计思路目前来看一个好处就是不需要ios/android/wp等各平台自家的应用维护cookie.而且token的周期应该由服务器来维护,而不是浏览器. |
23
mytharcher 2015-04-23 19:50:30 +08:00
前端渲染和后端渲染主要看需求,比如需要 SEO 那就后端渲染,否则现在大规模的 Angular 等框架全是在前端渲染的。而且这跟授权机制好像没有太大的联系,这类非内容的文件,基本就是和 js/css 一样归为任何人可见 assets 的。
至于 token 存在 cookie 里,和你存在 localStorage 里唯一的区别就是过期时间,如果你后端直接忽略掉 cookie 内容,那就变成无状态的了。有自动管理过期时间的 cookie,那就没必要折腾一套东西来专门处理,而且反正你都要放在 header 里。 |
24
armoni 2015-04-23 20:57:13 +08:00
用nodeJS渲染吧,nodejs里调用rest api获取json,渲染到HTML,就是angular写的头疼
|
26
gkiwi OP @mytharcher
其实使用angularjs,在SEO这块有种解决方案,就是在判断出是搜索引擎时候,专门吐出一些不带样式的网页,不过从pagerank算法来讲,这个显然是不太好,而且据说有一定几率会被搜索引擎识别为作弊而封掉. token放在cookie不读取,你这块的意思是每次想后端api请求时候,现在浏览器端读取token然后作为参数传到后台么?如果是这个,那确实是无状态的了,哈哈~ 不过有几个缺点: 1. 每次cookie都被请求带着,占用带宽,特别是有很多同域图片时候,每次请求都带着cookie就有点过分了,这个也是设计restful的一个原因(?优势?). 2. 后端做token时间管理是基本上必不可少的,因为还得考虑安卓/IOS/WP之类的app端.可以参照这个帖子:/t/148426 .因为在每个平台的app都维护一套时间管理显然成本更高. 当然啦,目前我要做的项目只有web端,token放哪里都可以了.目前尽量按照restful的标准来就是纯为练练手:) |
28
mytharcher 2015-04-24 09:05:26 +08:00 1
需要用前端 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 根本不是一个层面的事情。 |
29
gkiwi OP @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/ 至于是不是一个层面,这个得看所指的深度了,看清本质就好了,个人有个人的看法,无法统一. 谢谢一起扯皮了这么久,自己对这块的理解也有新的认识:) |