首页 文章

单独的REST JSON API服务器和客户端? [关闭]

提问于
浏览
370

我即将从头开始创建一堆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 回答

  • 1

    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代理是有帮助的:

    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;
      }
    }
    

    Pro:我喜欢API和客户端的分离 . 聪明的人说这是要走的路 . 理论上很棒 . 似乎前卫而令人兴奋 .

    我可以说它在实践中也很棒 . 分离REST API的另一个优点是您可以在以后为其他应用程序重用它 . 在完美世界中,您应该能够使用相同的REST API,不仅适用于网页,还适用于移动应用程序,如果您决定编写一个 .

    骗局:没有多少先例 . 这方面的例子并不多 . 公共示例(twitter.com)感觉迟钝,甚至转向这种方法 .

    现在看起来不一样了 . 有很多做REST API的例子很多客户端都在使用它 .

  • 0

    我个人更喜欢选项(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连接缓存解决方案的产品 . 我没有找到任何连贯的东西:-(

  • 1

    我更喜欢走#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或它们的混合 .

  • 7

    在Rails中构建JSON API是第一类,JSONAPI :: Resources gem为http://jsonapi.org spec'd API做了大量工作 .

  • 6

    对于atyourservice.com.cy,我们使用服务器端呈现的页面模板,尤其是覆盖se部分 . 并在页面加载后使用API进行交互 . 由于我们的框架是MVC,所有控制器函数都复制到json输出和html输出 . 模板很干净,只接收一个对象 . 这可以在几秒钟内转换为js模板 . 我们始终维护服务器端模板,并根据请求重新转换为js .

  • 4

    一个非常好的问题,我很惊讶,因为我认为现在这是一个非常常见的任务,因此我将有足够的资源来解决这个问题,但事实并非如此 .

    我的想法如下: - 创建一些模块,它们在API控制器和HTML控制器之间具有通用逻辑 without 返回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
    
  • 7

    这里有一些很好的答案 - 我肯定会推荐#2或#3 - 分离在概念上也很好,但在实践中也是如此 .

    很难预测API上的负载和流量模式等内容,而我们看到谁独立提供API的客户可以更轻松地进行配置和扩展 . 如果你必须使用人类网络访问模式,那就不那么容易了 . 此外,您的API使用最终可能比您的Web客户端更快地扩展,然后您可以看到在哪里指导您的工作 .

    在#2#3之间它确实取决于你的目标 - 我同意#2可能是webapps的未来 - 但是如果那个 Channels 只是其中之一,你可能想要更直接的东西!

  • 133

    我通常会选择第二个选项,使用Rails构建API,以及JS的主干 . 您甚至可以使用ActiveAdmin免费获得管理面板 . 我用这种后端运送了数十个移动应用程序 . 但是,这在很大程度上取决于您的应用是否具有互动性

    我在最后RubyDay.it做了一个关于这种方法的演讲:http://www.slideshare.net/matteocollina/enter-the-app-era-with-ruby-on-rails-rubyday

    对于第三个选项,为了获得第二个选项的响应,您可能想尝试pajax作为Github .

  • 1

    我们在建造gaug.es时选择了#2 . 我参与了API(ruby,sinatra等)和我的商业伙伴Steve Smith,在前端工作(javascript客户端) .

    优点:

    • 并行快速移动 . 如果我领先于史蒂夫,我可以继续为新功能创建API . 如果他在我之前工作,他可以非常轻松地伪造API并构建UI .

    • API免费 . 对应用程序中的数据进行开放式访问很快就会成为标准功能 . 如果您从头开始使用API,则可以免费获得 .

    • 清洁分离 . 最好将您的应用视为客户端的API . 当然,第一个也是最重要的客户端可能是网络客户端,但它可以帮助您轻松创建其他客户端(iPhone,Android) .

    缺点:

    • 向后兼容性 . 这与API有关,而不是直接问题,但是一旦你的API出现在那里,你就可以意味着你必须放慢速度,但这确实意味着你必须经常让两件事情同时发挥作用 . 添加API或新字段很好,但不应在没有版本控制的情况下进行更改/删除 .

    我现在想不起有任何缺点 .

    结论:如果您计划发布API,API JS客户端就是您的选择 .

    附:我还建议在发布之前完整记录您的API . 记录Gaug.es API的过程确实帮助了我们

    http://get.gaug.es/documentation/api/

  • 1

    很好问 . 1.当然,这对我来说是未来有用的参考 . @Aaron和其他人也为讨论增添了 Value . 与Ruby一样,这个问题同样适用于其他编程环境 .

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

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

    选项2我一直很喜欢这个 . 此选项还意味着HTML不是在服务器上生成的运行时 . 这是选项2与选项3的不同之处 . 但是使用构建脚本构建为静态html . 在客户端加载时,这些HTML会将API服务器称为JS API客户端 . 分离关注点是很大的优势 . 非常喜欢(和我的)后端专家实现后端API,像通常的语言代码一样轻松测试它们,而不用担心框架/ http请求代码 . 这真的不像前端那样困难 . API调用和结果数据(主要是json)可用于客户端模板或MVC . 减少服务器端处理 . 这意味着您可以选择商用硬件/更便宜的服务器 . 更容易独立测试图层,更容易生成API文档 . 它确实有一些缺点 . 许多开发人员发现这个过于设计并且难以理解 . 所以建筑可能会受到批评 . i18n / l10n很难 . 由于HTML本质上是生成的,因此构建时间是静态的,每个支持的语言需要多个构建(这不一定是坏事) . 但即便如此,你可能会在l10n / i18n附近遇到拐角情况,需要小心 .

    选项3在这种情况下,后端编码必须与第二个选项相同 . 选项2的大多数点也适用于此处 . 使用服务器端模板呈现网页运行时 . 这使得i18n / l10n更容易使用更成熟/可接受的技术 . 对于用户,语言,货币等页面呈现所需的一些基本上下文,可能只需少一次http调用 . 因此,服务器端处理随着呈现而增加,但可能通过对API服务器的较少http调用来补偿 . 既然页面是在服务器上呈现的服务器,前端现在更多地与编程环境相关联 . 这可能甚至不是许多应用程序的考虑因素 .

    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) .

  • 1

    我决定为Infiniforms寻找选项#2的架构,因为它提供了一个将UI与业务逻辑分开的好方法 .

    这样做的一个优点是API服务器可以独立于Web服务器进行扩展 . 如果您有多个客户端,那么网站将不需要扩展到与Web服务器相同的程度,因为某些客户端swill是基于手机/平板电脑或基于桌面的 .

    这种方法还为您向用户开放API提供了良好的基础,特别是如果您使用自己的API为您的网站提供所有功能 .

  • 28

    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是一个很好的方法 .

  • 48

    我目前正在努力将一个巨大的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堆栈溢出让我发布那么多)

  • 0

    同构渲染和渐进增强 . 这是我认为你在第三选项中的目标 .

    isomorphic rendering 表示在客户端代码中使用相同的模板生成标记服务器端 . 选择一个好的模板语言服务器端和客户端实现 . 为您的用户创建完全烘焙的html并将其发送到网上 . 也使用缓存 .

    progressive enhancement 表示一旦下载了所有资源,就可以开始执行客户端执行和渲染以及事件监听,并且可以确定客户端功能 . 尽可能降低功能性客户端脚本功能,以实现可访问性和向后兼容性 .

    是的,当然为这个应用程序功能编写一个独立的json api . 但是,为了能够将静态html文档正常工作的东西写成json api,请不要这么做 .

  • 10

    我们使用以下#3的变体:创建一个仅限JSON的REST API服务器 . 制作HTML网站服务器 . 与您的变体一样,HTML Web服务器不是REST API服务器的客户端 . 相反,这两个是同行 . 在表面不远处,有一个内部API,提供两个服务器所需的功能 .

    我们不知道任何先例,所以它是一种实验性的 . 到目前为止(即将进入测试阶段),它已经很好地完成了 .

  • 1

    我进入为期3个月的项目大约需要2个月,这是你在这里概述的第二种方法 . 我们在前面使用RESTful API服务器端和backbone.js . Handlebars.js管理模板,jQuery处理AJAX和DOM操作 . 对于较旧的浏览器和搜索蜘蛛,我们已经回到服务器端渲染,但我们使用与使用Mozilla Rhino的Handlebars前端相同的HTML模板 .

    我们之所以选择这种方法有很多不同的原因,但我们非常清楚它有一点风险,因为它尚未得到广泛的证明 . 一切都相同,到目前为止一切都很顺利 .

    到目前为止,我们刚刚使用了一个API,但在项目的下一阶段,我们将使用第二个API . 第一个用于大量数据,第二个用于通过API更像CMS .

    让这两个项目完全相互独立是选择这个基础设施的关键考虑因素 . 如果您正在寻找一种架构来混搭不同的独立资源而没有任何依赖性,那么这种方法值得一看 .

    我担心我不是Ruby人,所以我不能对其他方法发表评论 . 有时可以承担风险 . 其他时候最好安全地玩 . 你会根据项目的类型自己做 .

    祝你好运 . 热衷于了解其他人分享的内容 .

  • 7

    我已经采用了混合方法,我们将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 .

  • 0

    当我的网站不是我的数据的100%CRUD实现时,我喜欢#3 . 这还没有发生 .

    我更喜欢sinatra,只是将应用程序拆分为几个不同用途的机架应用程序 . 我将制作一个API特定的机架应用程序,它将涵盖我对API的需求 . 然后可能是一个用户机架应用程序,它将显示我的网页 . 有时,如果需要,该版本将查询API,但通常只关注html网站 .

    我不担心它,只是在需要时从用户端进行持久层查询 . 我并不过分关注创建完全分离,因为它们通常最终用于不同的目的 .

    这是使用多个机架应用程序的一个非常简单的示例 . 我在那里添加了一个快速的jquery示例,以便您看到它与API应用程序相匹配 . 你可以看到sinatra有多么简单,并且可以安装多个不同用途的机架应用程序 .

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

相关问题