我即将从头开始创建一堆Web应用程序 . (有关概述,请参阅http://50pop.com/code . )我希望能够从许多不同的客户端访问它们:前端网站,智能手机应用程序,后端Web服务等 . 所以我真的想为每个客户端提供JSON REST API .
此外,我更喜欢在后端工作,所以我梦想着让我完全专注于API,并聘请其他人来制作前端用户界面,无论是网站,iPhone,Android还是其他应用 .
Please help me decide which approach I should take:
一起在铁路上制作一个非常标准的Rails网络应用程序 . 在控制器中,执行respond_with开关,以提供JSON或HTML . 然后JSON响应是我的API . 亲:很多先例 . 伟大的标准和许多以这种方式做事的例子 . Con:不一定要API与Web应用程序相同 . 不喜欢if / then respond_with switch方法 . 混合两个非常不同的东西(UI API) .
REST SERVER JAVASCRIPT-HEAVY CLIENT创建一个仅限JSON的REST API服务器 . 使用Backbone或Ember.js直接访问客户端JavaScript,在浏览器中显示模板 . 亲:我喜欢API和客户端的分离 . 聪明的人说这是要走的路 . 理论上很棒 . 似乎前卫而令人兴奋 . 骗局:没有多少先例 . 这方面的例子并不多 . 公共示例(twitter.com)感觉迟钝,甚至转向这种方法 .
REST服务器服务器端HTML客户端创建仅限JSON的REST API服务器 . 创建一个基本的HTML网站客户端,仅访问REST API . 减少客户端JavaScript . 亲:我喜欢API和客户端的分离 . 但是提供简单的HTML5非常简单,而且不是客户密集型的 . 骗局:没有多少先例 . 这方面的例子并不多 . 框架也不支持这一点 . 不知道如何处理它 .
特别是从经验中寻求建议,而不仅仅是在理论上 .
18 回答
REST服务器JavaScript重度客户端是我在最近的工作中遵循的原则 .
REST服务器实现在node.js Express MongoDB(非常好的写入性能)Mongoose ODM(非常适合建模数据,包括验证)CoffeeScript(我现在改为ES2015)这对我来说效果很好 . 与其他可能的服务器端技术相比,Node.js可能相对年轻,但它使我可以编写带有集成支付的可靠API .
我使用Ember.js作为JavaScript框架,大多数应用程序逻辑都是在浏览器中执行的 . 我已经使用SASS(特别是SCSS)进行CSS预处理 .
Ember是一个由强大社区支持的成熟框架 . 它是一个非常强大的框架,最近有很多关于性能的工作,比如brand new Glimmer rendering engine(受React启发) .
Ember核心团队正在开发FastBoot,让's you to execute your JavaScript Ember logic on server-side (node.js specifically) and send pre-rendered HTML of your application (which would normally be run in browser) to user. It is great for SEO and user experience as he doesn'等待这么长时间才能显示页面 .
Ember CLI是一款很棒的工具,可以帮助您组织代码,并且可以随着代码库的增长而扩展 . Ember还拥有自己的插件生态系统,您可以从各种Ember Addons中进行选择 . 您可以轻松地抓取Bootstrap(在我的情况下)或Foundation并将其添加到您的应用程序 .
不是通过Express提供所有服务,我选择使用nginx来提供图像和JavaScript重度客户端 . 在我的情况下使用nginx代理是有帮助的:
我可以说它在实践中也很棒 . 分离REST API的另一个优点是您可以在以后为其他应用程序重用它 . 在完美世界中,您应该能够使用相同的REST API,不仅适用于网页,还适用于移动应用程序,如果您决定编写一个 .
现在看起来不一样了 . 有很多做REST API的例子很多客户端都在使用它 .
我个人更喜欢选项(3)作为解决方案 . 它几乎用于我的前任(家喻户晓)雇主的所有网站 . 这意味着你可以得到一些前端开发人员,他们了解Javascript,浏览器怪癖以及编写前端的所有内容 . 他们只需要知道“卷曲xyz,你就会得到一些json”而且他们会离开 .
与此同时,你的重量级后端人员可以编写Json提供商的代码 . 这些人根本不需要考虑演示,而是担心后端,超时,优雅的错误处理,数据库连接池,线程和扩展等 .
选项3为您提供了良好,可靠的三层架构 . 这意味着你从前端吐出的东西是SEO友好的,可以用于旧的或新的浏览器(以及关闭JS的那些),并且如果你想的话仍然可以是Javascript客户端模板(所以你可以做一些事情,比如使用静态HTML处理旧浏览器/ googlebot,但是向使用最新版本的人发送JS构建的动态体验Chrome浏览器或其他) .
在我见过选项3的所有情况下,它是一些PHP的自定义实现,在项目之间不是特别可以转移,更不用说进入开源领域了 . 我想最近PHP可能已被Ruby / Rails取代,但同样的事情仍然是正确的 .
FWIW,$ current_employer可以在几个重要的地方使用选项3 . 我正在寻找一个很好的Ruby框架来构建一些东西 . 我敢肯定我可以将大量的宝石粘在一起,但我更喜欢一个广泛提供模板,'卷曲',可选身份验证,可选的memcache / nosql连接缓存解决方案的产品 . 我没有找到任何连贯的东西:-(
我更喜欢走#2和#3的路线 . 主要是因为#1违反了关注点的分离并混合了各种各样的东西 . 最终你会发现需要一个没有匹配的HTML页面/等的API endpoints ,你将在同一个代码库中使用混合的HTML和JSON endpoints . 它变成了一个疯狂的混乱,即使它的MVP,你最终还是必须重新写它,因为它太混乱,甚至不值得打捞 .
使用#2或#3可以让您完全拥有一个API(无论大多数情况下都是如此) . 这提供了很大的灵活性我还没有100%在Backbone / ember / what / etc.js上销售 . 我认为它很棒,但正如我们在twitter上看到的那样,这不是最佳选择 . 但是...... Twitter也是一家公司的巨大野兽,拥有数亿用户 . 因此,任何改进都会对各个业务部门的各个领域的底线产生巨大影响 . 我认为除了速度之外,还有更多的决定,而且他们不会让我们参与其中 . 但那只是我的个人意见 . 但是,我不打折骨干及其竞争对手 . 这些应用程序很好用,非常干净,响应速度很快(大多数情况下) .
第三种选择也有一些有效的诱惑力 . 这是我遵循帕累托原则(80/20规则)并在服务器上呈现20%的主标记(反之亦然),然后有一个漂亮的JS客户端(骨干/等)运行其余部分 . 您可能无法通过JS客户端与REST API进行100%通信,但如果有必要,您将做一些工作以使更好的体验 .
我认为这是“依赖于”那些问题之一,答案是“它取决于”你正在做什么,你在服务的人以及你希望他们接受什么样的经历 . 鉴于我认为你可以决定2或3或它们的混合 .
在Rails中构建JSON API是第一类,JSONAPI :: Resources gem为http://jsonapi.org spec'd API做了大量工作 .
对于atyourservice.com.cy,我们使用服务器端呈现的页面模板,尤其是覆盖se部分 . 并在页面加载后使用API进行交互 . 由于我们的框架是MVC,所有控制器函数都复制到json输出和html输出 . 模板很干净,只接收一个对象 . 这可以在几秒钟内转换为js模板 . 我们始终维护服务器端模板,并根据请求重新转换为js .
一个非常好的问题,我很惊讶,因为我认为现在这是一个非常常见的任务,因此我将有足够的资源来解决这个问题,但事实并非如此 .
我的想法如下: - 创建一些模块,它们在API控制器和HTML控制器之间具有通用逻辑 without 返回json或渲染html,并在HTML控制器和API控制器中包含此模块,然后执行任何操作,例如:
这里有一些很好的答案 - 我肯定会推荐#2或#3 - 分离在概念上也很好,但在实践中也是如此 .
很难预测API上的负载和流量模式等内容,而我们看到谁独立提供API的客户可以更轻松地进行配置和扩展 . 如果你必须使用人类网络访问模式,那就不那么容易了 . 此外,您的API使用最终可能比您的Web客户端更快地扩展,然后您可以看到在哪里指导您的工作 .
在#2#3之间它确实取决于你的目标 - 我同意#2可能是webapps的未来 - 但是如果那个 Channels 只是其中之一,你可能想要更直接的东西!
我通常会选择第二个选项,使用Rails构建API,以及JS的主干 . 您甚至可以使用ActiveAdmin免费获得管理面板 . 我用这种后端运送了数十个移动应用程序 . 但是,这在很大程度上取决于您的应用是否具有互动性
我在最后RubyDay.it做了一个关于这种方法的演讲:http://www.slideshare.net/matteocollina/enter-the-app-era-with-ruby-on-rails-rubyday
对于第三个选项,为了获得第二个选项的响应,您可能想尝试pajax作为Github .
我们在建造gaug.es时选择了#2 . 我参与了API(ruby,sinatra等)和我的商业伙伴Steve Smith,在前端工作(javascript客户端) .
优点:
并行快速移动 . 如果我领先于史蒂夫,我可以继续为新功能创建API . 如果他在我之前工作,他可以非常轻松地伪造API并构建UI .
API免费 . 对应用程序中的数据进行开放式访问很快就会成为标准功能 . 如果您从头开始使用API,则可以免费获得 .
清洁分离 . 最好将您的应用视为客户端的API . 当然,第一个也是最重要的客户端可能是网络客户端,但它可以帮助您轻松创建其他客户端(iPhone,Android) .
缺点:
我现在想不起有任何缺点 .
结论:如果您计划发布API,API JS客户端就是您的选择 .
附:我还建议在发布之前完整记录您的API . 记录Gaug.es API的过程确实帮助了我们
http://get.gaug.es/documentation/api/
很好问 . 1.当然,这对我来说是未来有用的参考 . @Aaron和其他人也为讨论增添了 Value . 与Ruby一样,这个问题同样适用于其他编程环境 .
我使用了前两个选项 . 第一个用于众多应用程序,第二个用于我的开源项目Cowoop
Twitter案例
据我了解,Twitter可能会在服务器上进行初始页面呈现,但对于页面更新,它仍然有一些API调用和客户端模板来操作DOM . 因此,在这种情况下,您需要维护双模板,这会增加一些开销和复杂性 . 与Twitter不同,不是每个人都能买得起这个选择 .
我们的项目堆栈
我碰巧使用Python . 我使用JsonRPC 2.0而不是REST . 我建议REST,虽然我喜欢JsonRPC的想法有各种原因 . 我使用下面的库 . 考虑选项2/3的人可能会发现它很有用 .
API服务器:Python一个快速的Web微框架 - Flask
前端服务器:Nginx
客户端MVC:Knockout.js
其他相关工具/库:
Jquery
Accounting.js换货币
Webshim:跨浏览器polyfill
director:客户端路由
sphc:HTML生成
我的结论和建议
选项3!
总而言之,我已经成功使用了选项2,但现在倾向于选项3以获得一些简单性 . 使用构建脚本生成静态HTML页面并使用专门提供静态页面的超快速服务器提供服务非常诱人(选项2) .
我决定为Infiniforms寻找选项#2的架构,因为它提供了一个将UI与业务逻辑分开的好方法 .
这样做的一个优点是API服务器可以独立于Web服务器进行扩展 . 如果您有多个客户端,那么网站将不需要扩展到与Web服务器相同的程度,因为某些客户端swill是基于手机/平板电脑或基于桌面的 .
这种方法还为您向用户开放API提供了良好的基础,特别是如果您使用自己的API为您的网站提供所有功能 .
在Boundless,我们已经深入了解选项#2并将其推广到成千上万的学生 . 我们的服务器是JSON REST API(Scala MongoDB),我们所有的客户端代码都是直接从CloudFront提供的(即:www.boundless.com只是CloudFront的别名) .
优点:
前沿/令人兴奋
为您带来很多好处:API为您自己的Web客户端,移动客户端,第三方访问等提供了基础 .
极快的站点加载/页面转换
缺点:
没有SEO友好/准备没有更多的工作 .
需要一流的网络前端用户,他们随时准备应对70%javascript网站体验的现实以及这意味着什么 .
我认为这是所有网络应用程序的未来 .
对Web前端人员的一些想法(这是所有新的/挑战给予这种架构的地方):
CoffeeScript . 更容易生成高质量的代码 .
Backbone . 组织逻辑和活跃社区的好方法 .
HAMLC . Haml CoffeeScript模板=> JS .
SASS
我们've built a harness for our front-end development called ' Spar ' (Single Page App Rocketship) which is effectively the asset pipeline from Rails tuned for single page app development. We'将在未来几周内在我们的github页面上开源,以及一篇博客文章,详细解释如何使用它和整体架构 .
更新:
关于人们对Backbone的关注,我认为它们被高估了 . Backbone更像是一个组织原则,而不是一个深层框架 . Twitter的网站本身就是一个巨大的Javascript野兽,覆盖数百万用户和传统浏览器的每个角落,同时实时加载推文,垃圾收集,显示大量多媒体等 . 在所有'纯'js网站中我都是看到,Twitter是奇怪的一个 . 通过JS提供的许多令人印象深刻的复杂应用程序非常好 .
您选择的架构完全取决于您的目标 . 如果您正在寻找支持多个客户端并获得良好前端人才的最快方式,那么投资独立API是一个很好的方法 .
我目前正在努力将一个巨大的CMS从选项1转换为选项3,而且进展顺利 . 我们选择渲染标记服务器端,因为SEO对我们来说是一个大问题,我们希望这些网站在手机上表现良好 .
我正在使用node.js作为客户端的后端和一些模块来帮助我 . 我在这个过程中有点早,但基础已经确定,这是一个重复数据的问题,确保一切正确 . 这是我正在使用的:
Express为应用程序的基础 .
(https://github.com/visionmedia/express)
请求获取数据 .
(https://github.com/mikeal/request)
渲染服务器端的下划线模板 . 我在客户端重用这些 .
(https://github.com/documentcloud/underscore)
UTML包装下划线的模板,使它们与Express一起使用 .
(https://github.com/mikefrey/utml)
Upfront收集模板,让您选择哪些模板发送到客户端 .
(https://github.com/mrDarcyMurphy/upfront)
Express Expose将获取的数据,一些模块和模板传递给前端 .
(https://github.com/visionmedia/express-expose)
Backbone在吞下传递的数据后在前端创建模型和视图 .
(https://github.com/documentcloud/backbone)
这是堆栈的核心 . 我发现其他一些有用的模块:
fleck(https // github.com / trek / fleck)
时刻(https // github.com / timrwood / moment)
手写笔(https // github.com / LearnBoost / stylus)
smoosh(https // github.com / fat / smoosh)
...虽然我正在调查grunt(https // github.com / cowboy / grunt)
console trace(//github.com/LearnBoost/console-trace) .
不,我没有使用coffeescript .
这个选项对我来说非常好用 . 后端的模型是不存在的,因为我们从API获得的数据结构良好,我将它逐字传递给前端 . 唯一的例外是我们的布局模型,其中我添加了一个使渲染更智能和更轻的属性 . 我没有使用任何花哨的模型库,只是一个在初始化时添加我需要的函数并返回自身 .
(对不起奇怪的链接,我太多了n00b堆栈溢出让我发布那么多)
同构渲染和渐进增强 . 这是我认为你在第三选项中的目标 .
isomorphic rendering 表示在客户端代码中使用相同的模板生成标记服务器端 . 选择一个好的模板语言服务器端和客户端实现 . 为您的用户创建完全烘焙的html并将其发送到网上 . 也使用缓存 .
progressive enhancement 表示一旦下载了所有资源,就可以开始执行客户端执行和渲染以及事件监听,并且可以确定客户端功能 . 尽可能降低功能性客户端脚本功能,以实现可访问性和向后兼容性 .
是的,当然为这个应用程序功能编写一个独立的json api . 但是,为了能够将静态html文档正常工作的东西写成json api,请不要这么做 .
我们使用以下#3的变体:创建一个仅限JSON的REST API服务器 . 制作HTML网站服务器 . 与您的变体一样,HTML Web服务器不是REST API服务器的客户端 . 相反,这两个是同行 . 在表面不远处,有一个内部API,提供两个服务器所需的功能 .
我们不知道任何先例,所以它是一种实验性的 . 到目前为止(即将进入测试阶段),它已经很好地完成了 .
我进入为期3个月的项目大约需要2个月,这是你在这里概述的第二种方法 . 我们在前面使用RESTful API服务器端和backbone.js . Handlebars.js管理模板,jQuery处理AJAX和DOM操作 . 对于较旧的浏览器和搜索蜘蛛,我们已经回到服务器端渲染,但我们使用与使用Mozilla Rhino的Handlebars前端相同的HTML模板 .
我们之所以选择这种方法有很多不同的原因,但我们非常清楚它有一点风险,因为它尚未得到广泛的证明 . 一切都相同,到目前为止一切都很顺利 .
到目前为止,我们刚刚使用了一个API,但在项目的下一阶段,我们将使用第二个API . 第一个用于大量数据,第二个用于通过API更像CMS .
让这两个项目完全相互独立是选择这个基础设施的关键考虑因素 . 如果您正在寻找一种架构来混搭不同的独立资源而没有任何依赖性,那么这种方法值得一看 .
我担心我不是Ruby人,所以我不能对其他方法发表评论 . 有时可以承担风险 . 其他时候最好安全地玩 . 你会根据项目的类型自己做 .
祝你好运 . 热衷于了解其他人分享的内容 .
我已经采用了混合方法,我们将Sinatra用作基础,ActiveRecord / Postgress等用于提供页面路由(超薄模板),公开Web应用程序可以使用的REST API . 在早期开发中,诸如填充选择选项之类的东西是通过帮助程序渲染到slim模板中完成的,但是当我们接近 生产环境 时,随着我们开始关注页面加载速度等等,这将被换出以进行REST API的AJAX调用 .
's easy to render out in Slim gets handled that way, and stuff (populating forms, receiving form POST data from jQuery.Validation' s
submitHandler
等的东西,都是明显的AJAX)测试是一个问题 . 现在我很难过trying to pass JSON data to a Rack::Test POST test .
当我的网站不是我的数据的100%CRUD实现时,我喜欢#3 . 这还没有发生 .
我更喜欢sinatra,只是将应用程序拆分为几个不同用途的机架应用程序 . 我将制作一个API特定的机架应用程序,它将涵盖我对API的需求 . 然后可能是一个用户机架应用程序,它将显示我的网页 . 有时,如果需要,该版本将查询API,但通常只关注html网站 .
我不担心它,只是在需要时从用户端进行持久层查询 . 我并不过分关注创建完全分离,因为它们通常最终用于不同的目的 .
这是使用多个机架应用程序的一个非常简单的示例 . 我在那里添加了一个快速的jquery示例,以便您看到它与API应用程序相匹配 . 你可以看到sinatra有多么简单,并且可以安装多个不同用途的机架应用程序 .
https://github.com/dusty/multi-rack-app-app