我要从头开始创建一堆网络应用程序。(详见http://50pop.com/code)我希望他们能够从许多不同的客户端访问:前端网站,智能手机应用程序,后端web服务,等等。所以我真的想为每一个都提供一个JSON REST API。
此外,我更喜欢在后端工作,所以我幻想着我只专注于API,雇佣其他人来制作前端UI,无论是网站、iPhone、Android还是其他应用程序。
请帮助我决定我应该采取哪一种方法:
一起在铁轨上
制作一个非常标准的Rails web应用程序。在控制器中,执行respond_with开关,以提供JSON或HTML。JSON响应就是我的API。
教授:有很多先例。伟大的标准和很多这样做的例子。
缺点:不一定希望API与web应用相同。不喜欢if/then respond_with switch方法。混合两种非常不同的东西(UI + API)。
Rest服务器+ javascript重客户端
制作一个JSON-only REST API服务器。客户端JavaScript使用Backbone或Ember.js直接访问API,在浏览器中显示模板。
利:我喜欢API和客户端的分离。聪明的人说这是正确的选择。理论上很好。看起来很前卫,令人兴奋。
弊:没有太多先例。这方面做得好的例子不多。公开的例子(twitter.com)感觉很迟钝,甚至正在改变这种方法。
休息服务器+服务器端HTML客户端
制作一个JSON-only REST API服务器。做一个基本的HTML网站客户端,只访问REST API。更少的客户端JavaScript。
利:我喜欢API和客户端的分离。但是提供简单的HTML5是非常简单的,而且不是客户密集型的。
弊:没有太多先例。这方面做得好的例子不多。框架也不支持这一点。不知道该怎么处理。
尤其是从经验中寻求建议,而不仅仅是理论上的建议。
REST服务器+ javascript为主的客户端是我在最近的工作中遵循的原则。
REST服务器是在node.js + Express + MongoDB(非常好的写作性能)+ Mongoose ODM(非常适合建模数据,包括验证)+ CoffeeScript(我现在用ES2015代替)中实现的,这对我来说很好。与其他可能的服务器端技术相比,Node.js可能相对年轻,但它使我能够编写集成了支付的可靠API。
我使用Ember.js作为JavaScript框架,大部分应用程序逻辑是在浏览器中执行的。我使用SASS(特别是SCSS)进行CSS预处理。
Ember是由强大的社区支持的成熟框架。它是一个非常强大的框架,最近有很多工作都集中在性能上,比如全新的Glimmer渲染引擎(灵感来自React)。
Ember核心团队正在开发FastBoot,它可以让你在服务器端(node.js具体)执行你的JavaScript Ember逻辑,并发送预渲染的应用程序HTML(通常在浏览器中运行)给用户。这是伟大的搜索引擎优化和用户体验,因为他不会等待那么长时间的页面显示。
Ember CLI是一个很好的工具,可以帮助你组织你的代码,它在不断增长的代码库中做得很好。烬也有它自己的插件生态系统,你可以选择从各种烬插件。你可以很容易地抓取Bootstrap(在我的情况下)或Foundation,并将其添加到你的应用程序。
不是通过Express来提供所有的服务,我选择使用nginx来提供图像和javascript较多的客户端。使用nginx代理在我的情况下是有帮助的:
upstream app_appName.com {
# replace 0.0.0.0 with your IP address and 1000 with your port of node HTTP server
server 0.0.0.0:1000;
keepalive 8;
}
server {
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
client_max_body_size 32M;
access_log /var/log/nginx/appName.access.log;
error_log /var/log/nginx/appName.error.log;
server_name appName.com appName;
location / {
# frontend assets path
root /var/www/html;
index index.html;
# to handle Ember routing
try_files $uri $uri/ /index.html?/$request_uri;
}
location /i/ {
alias /var/i/img/;
}
location /api/v1/ {
proxy_pass http://app_appName.com;
proxy_next_upstream error timeout invalid_header http_500 http_502
http_503 http_504;
proxy_redirect off;
proxy_buffering off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
利:我喜欢API和客户端的分离。聪明的人说这是
该走的路。理论上很好。看起来很前卫,令人兴奋。
我可以说它在实践中也很好。分离REST API的另一个优点是,以后可以在其他应用程序中重用它。在理想的情况下,你不仅可以在网页上使用相同的REST API,如果你决定编写一个移动应用程序,也可以在移动应用程序上使用。
弊:没有太多先例。这方面做得好的例子不多。公共
例子(twitter.com)感觉迟钝,甚至切换
这种方法。
现在情况看起来不一样了。有很多使用REST API +许多客户端使用它的例子。
我更倾向于选择第二条和第三条。主要是因为第一条违反了关注点的分离,并且混合了各种各样的东西。最终,你会发现需要有一个没有匹配HTML页面的API端点/等等,你会在同一个代码库中遇到HTML和JSON端点混合的麻烦。它变得一团糟,即使它是MVP,你最终也不得不重写它,因为它太混乱了,甚至不值得挽救。
Going with #2 or #3 allows you to completely have a API that acts the same (for the most part) regardless. This provides great flexibility. I'm not 100% sold on Backbone/ember/whatever/etc.js just yet. I think its great, but as we're seeing with twitter this is not optimal. BUT... Twitter is also a huge beast of a company and has hundreds of millions of users. So any improvement can have a huge impact to bottom line on various areas of various business units. I think there is more to the decision than speed alone and they're not letting us in on that. But thats just my opinion. However, I do not discount backbone and its competitors. These apps are great to use and are very clean and are very responsive (for the most part).
第三种选择也有一定的吸引力。这就是我遵循帕累托原则(80/20规则)的地方,让20%的主标记(反之亦然)在服务器上呈现,然后让一个漂亮的JS客户端(backbone/etc)运行剩下的部分。你可能不会通过JS客户端与REST api进行100%的通信,但如果有必要的话,你会做一些工作来让suer体验更好。
我认为这是一个“视情况而定”的问题,答案是“这取决于”你在做什么,你在为谁服务,以及你希望他们得到什么样的体验。我认为你可以选择2个或3个或者它们的混合。
在Boundless,我们已经深入研究了第2个选项,并将其推广给了数千名学生。我们的服务器是一个JSON REST API (Scala + MongoDB),我们所有的客户端代码都是直接从CloudFront提供的(即:www.boundless.com只是CloudFront的别名)。
优点:
尖端的/令人兴奋
好处多多:API为你自己的web客户端、移动客户端、第三方访问等提供了基础。
非常快的网站加载/页面转换
缺点:
不SEO友好/准备没有更多的工作。
需要一流的web前端人员,他们准备好应对网站体验的现实,70%是javascript和这意味着什么。
我认为这是所有网络应用程序的未来。
对web前端人员的一些想法(这是这个架构所具有的所有新事物/挑战):
CoffeeScript。更容易生成高质量的代码。
骨干。组织逻辑和活跃社区的好方法。
HAMLC。Haml + CoffeeScript模板=> JS。
萨斯
我们已经为我们的前端开发构建了一个名为“Spar”(单页应用Rocketship)的工具,它实际上是Rails为单页应用开发调整的资产管道。我们将在接下来的几周内在我们的github页面上开放源代码,同时还有一篇博客文章解释如何使用它和更详细的整体架构。
更新:
With respect to people's concerns with Backbone, I think they are over-rated. Backbone is far more an organizational principle than it is a deep framework. Twitter's site itself is a giant beast of Javascript covering every corner-case across millions of users & legacy browsers, while loading tweets real-time, garbage collect, display lots of multimedia, etc. Of all the 'pure' js sites I've seen, Twitter is the odd one out. There have been many impressively complicated apps delivered via JS that fare very well.
体系结构的选择完全取决于您的目标。如果您正在寻找支持多个客户端的最快方式,并有机会接触到优秀的前端人才,那么投资一个独立的API是一个很好的方法。
我的3个月项目已经进行了2个月,采用了你在这里概述的第二种方法。我们使用一个RESTful API服务器端,前端是backbone.js。js管理模板,jQuery处理AJAX和DOM操作。对于旧的浏览器和搜索蜘蛛,我们已经退回到服务器端渲染,但是我们使用的是与使用Mozilla Rhino的Handlebars前端相同的HTML模板。
我们选择这种方法有很多不同的原因,但我们非常清楚,因为它还没有在大范围内得到证明,所以它有点冒险。尽管如此,到目前为止一切都进行得很顺利。。
到目前为止,我们一直在使用一个API,但在项目的下一个阶段,我们将使用第二个API。第一个用于大量数据,第二个更像一个通过API的CMS。
让项目的这两个部分彼此完全独立是选择这个基础设施的关键考虑因素。如果您正在寻找一种架构,可以在没有任何依赖的情况下混搭不同的独立资源,那么这种方法值得一试。
恐怕我不是Ruby的人,所以我不能评论其他方法。有时候冒险一下是可以的。其他时候最好谨慎行事。你会根据项目的类型来了解自己。
祝你选对了。也热衷于看别人分享什么。