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

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


当前回答

我更倾向于选择第二条和第三条。主要是因为第一条违反了关注点的分离,并且混合了各种各样的东西。最终,你会发现需要有一个没有匹配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个或者它们的混合。

其他回答

这里已经有一些很好的答案了——我肯定会推荐第2条或第3条——分离在概念上很好,在实践中也很好。

很难预测API上的负载和流量模式等事情,而我们看到的那些独立为API提供服务的客户更容易进行配置和扩展。如果你必须在人类的网络访问模式中做到这一点,那就不那么容易了。此外,你的API使用可能会比你的web客户端增长得更快,然后你就可以看到你的努力方向了。

在#2 #3之间,这真的取决于你的目标-我同意#2可能是web应用程序的未来-但也许你想要一些更直接的东西,如果那个频道只是众多频道中的一个!

我目前正致力于将一个巨大的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堆栈溢出让我张贴那么多)

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

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

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

一个非常好的问题,我很惊讶,因为我认为这是一个非常普遍的任务,现在我会有足够的资源来解决这个问题,然而事实并非如此。

我的想法如下: -创建一些在API控制器和HTML控制器之间具有公共逻辑的模块,而不返回json或呈现HTML,并将此模块包含在HTML控制器和API控制器中,然后做任何你想做的事情,例如:

module WebAndAPICommon
    module Products

        def index
            @products = # do some logic here that will set @products variable
        end

    end
end


class ProductsController < ApplicationController
    # default products controlelr, for rendering HMTL pages 
    include WebAndAPICommon

    def index
        super
    end

end



module API
    class ProductsController
        include WebAndAPICommon

        def index
            super
            render json: @products
        end

    end
end

我更倾向于选择第二条和第三条。主要是因为第一条违反了关注点的分离,并且混合了各种各样的东西。最终,你会发现需要有一个没有匹配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个或者它们的混合。