我要从头开始创建一堆网络应用程序。(详见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是非常简单的,而且不是客户密集型的。 弊:没有太多先例。这方面做得好的例子不多。框架也不支持这一点。不知道该怎么处理。

尤其是从经验中寻求建议,而不仅仅是理论上的建议。


当前回答

我采用了一种混合的方法,我们使用Sinatra作为基础,ActiveRecord / Postgress等来提供页面路由(细长模板),公开web应用程序可以使用的REST API。在早期的开发中,像填充选择选项这样的事情是通过helper渲染到精简模板中完成的,但当我们接近生产时,这就变成了对REST API的AJAX调用,因为我们开始更关心页面加载速度等等。

在Slim中很容易渲染出来的东西以这种方式处理,而东西(填充表单,从jQuery接收表单POST数据。验证的submitHandler等显然都是AJAX)

测试是一个问题。现在我正试图将JSON数据传递给Rack::Test POST测试。

其他回答

我喜欢#3,当我的网站不是100%的CRUD实现我的数据。这种情况尚未发生。

我更喜欢sinatra,只会把应用程序分成几个不同的机架应用程序与不同的目的。我会做一个API特定的机架应用程序,将涵盖我需要的API。然后可能是一个用户机架应用程序,将呈现我的网页。有时该版本会在需要时查询API,但通常它只关心html站点。

我不担心它,只要从用户端做一个持久化层查询,如果我需要它。我不太关心创建一个完全的分离,因为他们通常最终服务于不同的目的。

下面是一个使用多个机架应用程序的简单示例。我在那里添加了一个jquery的快速示例,让你看到它击中API应用程序。你可以看到sinatra和安装多个不同用途的机架应用程序是多么简单。

https://github.com/dusty/multi-rack-app-app

我们使用#3的以下变体: 制作一个JSON-only REST API服务器。制作一个HTML网站服务器。HTML web服务器不是REST API服务器的客户端。相反,这两家公司是同行。在表面下不远的地方,有一个内部API提供两个服务器所需的功能。

我们不知道有任何先例,所以这是一种实验。到目前为止(即将进入测试阶段),它的效果相当不错。

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 +许多客户端使用它的例子。

我目前正致力于将一个巨大的CMS从选项1转换为选项3,并且进展顺利。我们选择在服务器端呈现标记,因为SEO对我们来说很重要,我们希望网站在移动电话上表现良好。

我使用node.js作为客户端的后端和一些模块来帮助我。我在这个过程中有点早期,但基础已经设置好了,这是一个检查数据确保它全部呈现正确的问题。这是我正在使用的:

Express for the app's foundation. (https://github.com/visionmedia/express) Request to fetch the data. (https://github.com/mikeal/request) Underscore templates that get rendered server side. I reuse these on the client. (https://github.com/documentcloud/underscore) UTML wraps underscore's templates to make them work with Express. (https://github.com/mikefrey/utml) Upfront collects templates and let's you chose which get sent to the client. (https://github.com/mrDarcyMurphy/upfront) Express Expose passes the fetched data, some modules, and templates to the front-end. (https://github.com/visionmedia/express-expose) Backbone creates models and views on the front-end after swallowing the data that got passed along. (https://github.com/documentcloud/backbone)

这是堆栈的核心。我发现其他一些有用的模块:

法立科(https / / github.com/trek/fleck) 时刻(https / / github.com/timrwood/moment) 手写笔(https / / github.com/LearnBoost/stylus) 整合(https / / github.com/fat/smoosh) 虽然我正在寻找grunt (https//github.com/cowboy/grunt) 控制台跟踪(//github.com/LearnBoost/console-trace)。

不,我没有使用coffeescript。

这个选择对我来说非常有效。后端模型是不存在的,因为我们从API获得的数据结构良好,并且我将其逐字传递给前端。唯一的例外是我们的布局模型,我添加了一个属性,使渲染更智能和更轻。我没有使用任何花哨的模型库,只是一个函数,在初始化时添加我需要的东西并返回自己。

(抱歉奇怪的链接,我太n00b堆栈溢出让我张贴那么多)

问得好。+ 1。当然,这对我将来是一个有用的参考。此外,@Aaron和其他人也为讨论提供了价值。 和Ruby一样,这个问题同样适用于其他编程环境。

我使用了前两个选项。第一个用于许多应用程序,第二个用于我的开源项目Cowoop

选项1 这无疑是最受欢迎的一个。但我发现实现是非常http的。每个API的初始代码都用于处理请求对象。所以API代码不仅仅是纯粹的ruby/python/其他语言代码。

Option 2 I always loved this. This option also implies that HTML is not runtime generated on server. This is how option 2 is different from option 3. But are build as static html using a build script. When loaded on client side these HTML would call API server as JS API client. Separation of concerns is great advantage. And very much to your liking (and mine) backend experts implement backend APIs, test them easily like usual language code without worrying about framework/ http request code. This really is not as difficult as it sounds on frontend side. Do API calls and resulting data (mostly json) is available to your client side template or MVC. Less server side processing. It means you may go for commodity hardware/ less expensive server. Easier to test layers independently, easier to generate API docs. It does have some downsides. Many developers find this over engineered and hard to understand. So chances are that architecture may get criticized. i18n/l10n is hard. Since HTML is essentially generated build time are static, one needs multiple builds per supported language (which isn't necessarily a bad thing). But even with that you may have corner cases around l10n/i18n and need to be careful.

Option 3 Backend coding in this case must be same as second option. Most points for option 2 are applicable here as well. Web pages are rendered runtime using server side templates. This makes i18n/l10n much easier with more established/accepted techniques. May be one less http call for some essential context needed for page rendering like user, language, currency etc. So server side processing is increased with rendering but possibly compensated by less http calls to API server. Now that pages are server rendered on server, frontend is now more tied with programming environment. This might not be even a consideration for many applications.

Twitter的情况下

据我所知,Twitter可能会在服务器上进行初始页面渲染,但对于页面更新,它仍然有一些API调用和客户端模板来操作DOM。所以在这种情况下,你需要维护两个模板,这增加了一些开销和复杂性。不是每个人都能负担得起这个选项,不像Twitter。

我们的项目Stack

我碰巧使用Python。我使用JsonRPC 2.0代替REST。我建议使用REST,尽管出于各种原因我喜欢JsonRPC的想法。我使用下面的库。考虑选项2/3的人可能会觉得有用。

一个快速的web微框架- Flask 前端服务器:Nginx 客户端MVC: Knockout.js 其他相关工具/库: Jquery js代表货币 Webshim:跨浏览器填充 director:客户端路由 生成HTML

我的结论和建议

选项3 !

总之,我已经成功地使用了选项2,但现在为了简单起见,我倾向于选项3。使用构建脚本生成静态HTML页面,并使用专门提供静态页面的超高速服务器提供这些页面是非常诱人的(选项2)。