前后端分离的思考与实践(1)

前后端分离实践的架构设计 前后端分离的项目开发策略已经不是什么新鲜东西了,网上介绍这方面的文章非常多。我自己是在14年的时候接触到的,对这种开发策略一直爱不释手,不管新老项目都会首先用前后端分离的思维先去思考一番。从14年到现在在前后分离上面也实践了近3年的时间,项目大大小小的也差不多4,5个吧,但是却从来没有一个是自己觉得很满意的,其中的原由和心酸可能只有自己才能体会了。 前后端分离实践有感 现在到处都是前后端分离的实践。然而一些项目在从一体化 Web 设计转向前后端分离的架构时,仍然会碰见各种各样的问题。由于层出不穷的问题,甚至 阅读详情

前言

为了解决传统Web开发模式带来的各种问题,我们进行了许多尝试,但由于前/后端的物理鸿沟,尝试的方案都大同小异。痛定思痛,今天我们重新思考了“前后端”的定义,引入前端同学都熟悉的NodeJS,试图探索一条全新的前后端分离模式。

  随着不同终端(Pad/Mobile/PC)的兴起,对开发人员的要求越来越高,纯浏览器端的响应式已经不能满足用户体验的高要求,我们往往需要针对不同的终端开发定制的版本。为了提升开发效率,前后端分离的需求越来越被重视,后端负责业务/数据接口,前端负责展现/交互逻辑,同一份数据接口,我们可以定制开发多个版本。

  这个话题最近被讨论得比较多,阿里有些BU也在进行一些尝试。讨论了很久之后,我们团队决定探索一套基于NodeJS的前后端分离方案,过程中有一些不断变化的认识以及思考,记录在这里,也希望看到的同学参与讨论,帮我们完善。

一、什么是前后端分离?

  最开始组内讨论的过程中我发现,每个人对前后端分离的理解不一样,为了保证能在同一个频道讨论,先就什么是”前后端分离”达成一致。

  大家一致认同的前后端分离的例子就是SPA(Single-page application),所有用到的展现数据都是后端通过异步接口(AJAX/JSONP)的方式提供的,前端只管展现。
从某种意义上来说,SPA确实做到了前后端分离,但这种方式存在两个问题:

  • WEB服务中,SPA类占的比例很少。很多场景下还有同步/同步+异步混合的模式,SPA不能作为一种通用的解决方案。
  • 现阶段的SPA开发模式,接口通常是按照展现逻辑来提供的,有时候为了提高效率,后端会帮我们处理一些展现逻辑,这就意味着后端还是涉足了View层的工作,不是真正的前后端分离。

  SPA式的前后端分离,是从物理层做区分(认为只要是客户端的就是前端,服务器端的就是后端),这种分法已经无法满足我们前后端分离的需求,我们认为从职责上划分才能满足目前我们的使用场景:

  • 前端:负责View和Controller层。
  • 后端:只负责Model层,业务处理/数据等。

  为什么去做这种职责的划分,后面会继续探讨。

二、为什么要前后端分离?

  关于这个问题,玉伯的文章Web研发模式演变中解释得非常全面,我们再大概理一下:

2.1 现有开发模式的适用场景

  玉伯提到的几种开发模式,各有各的适用场景,没有哪一种完全取代另外一种。

  • 比如后端为主的MVC,做一些同步展现的业务效率很高,但是遇到同步异步结合的页面,与后端开发沟通起来就会比较麻烦。
  • Ajax为主SPA型开发模式,比较适合开发APP类型的场景,但是只适合做APP,因为SEO等问题不好解决,对于很多类型的系统,这种开发方式也过重。
2.2 前后端职责不清

  在业务逻辑复杂的系统里,我们最怕维护前后端混杂在一起的代码,因为没有约束,M-V-C每一层都可能出现别的层的代码,日积月累,完全没有维护性可言。
虽然前后端分离没办法完全解决这种问题,但是可以大大缓解。因为从物理层次上保证了你不可能这么做。

2.3 开发效率问题

  淘宝的Web基本上都是基于MVC框架webx,架构决定了前端只能依赖后端。
  所以我们的开发模式依然是,前端写好静态demo,后端翻译成VM模版,这种模式的问题就不说了,被吐槽了很久。
  直接基于后端环境开发也很痛苦,配置安装使用都很麻烦。为了解决这个问题,我们发明了各种工具,比如VMarket,但是前端还是要写VM,而且依赖后端数据,效率依然不高。
  另外,后端也没法摆脱对展现的强关注,从而专心于业务逻辑层的开发。

2.4 对前端发挥的局限

  性能优化如果只在前端做空间非常有限,于是我们经常需要后端合作才能碰撞出火花,但由于后端框架限制,我们很难使用Comet、Bigpipe等技术方案来优化性能。

  为了解决以上提到的一些问题,我们进行了很多尝试,开发了各种工具,但始终没有太多起色,主要是因为我们只能在后端给我们划分的那一小块空间去发挥。只有真正做到前后端分离,我们才能彻底解决以上问题。

三、怎么做前后端分离?

  怎么做前后端分离,其实第一节中已经有了答案:

  • 前端:负责View和Controller层。
  • 后端:负责Model层,业务处理/数据等。

图1

  试想一下,如果前端掌握了Controller,我们可以做url design,我们可以根据场景决定在服务端同步渲染,还是根据view层数据输出json数据,我们还可以根据表现层需求很容易的做Bigpipe,Comet,Socket等等,完全是需求决定使用方式。

3.1 基于NodeJS“全栈”式开发

  如果想实现上图的分层,就必然需要一种web服务帮我们实现以前后端做的事情,于是就有了标题提到的“基于NodeJS的全栈式开发”。

图2

  这张图看起来简单而且很好理解,但没尝试过,会有很多疑问。

  • SPA模式中,后端已供了所需的数据接口,view前端已经可以控制,为什么要多加NodeJS这一层?
  • 多加一层,性能怎么样?
  • 多加一层,前端的工作量是不是增加了?
  • 多加一层就多一层风险,怎么破?
  • NodeJS什么都能做,为什么还要JAVA?

  这些问题要说清楚不容易,下面说下我的认识过程。

3.2 为什么要增加一层NodeJS?

  现阶段我们主要以后端MVC的模式进行开发,这种模式严重阻碍了前端开发效率,也让后端不能专注于业务开发。
  解决方案是让前端能控制Controller层,但是如果在现有技术体系下很难做到,因为不可能让所有前端都学Java,安装后端的开发环境,写VM。
  NodeJS就能很好的解决这个问题,我们无需学习一门新的语言,就能做到以前开发帮我们做的事情,一切都显得那么自然。

3.3 性能问题

  分层就涉及每层之间的通讯,肯定会有一定的性能损耗。但是合理的分层能让职责清晰、也方便协作,会大大提高开发效率。分层带来的损失,一定能在其他方面的收益弥补回来。
  另外,一旦决定分层,我们可以通过优化通讯方式、通讯协议,尽可能把损耗降到最低。

  举个例子:
  淘宝宝贝详情页静态化之后,还是有不少需要实时获取的信息,比如物流、促销等等,因为这些信息在不同业务系统中,所以需要前端发送5,6个异步请求来回填这些内容。
  有了NodeJS之后,前端可以在NodeJS中去代理这5个异步请求,还能很容易的做Bigpipe,这块的优化能让整个渲染效率提升很多。
  可能在PC上你觉得发5,6个异步请求也没什么,但是在无线端,在客户手机上建立一个HTTP请求开销很大,有了这个优化,性能一下提升好几倍。

  淘宝详情基于NodeJS的优化我们正在进行中,上线之后我会分享一下优化的过程。

3.4 前端的工作量是否增加了?

  相对于只切页面/做demo,肯定是增加了一点,但是当前模式下有联调、沟通环节,这个过程非常花时间,也容易出bug,还很难维护。
  所以,虽然工作量会增加一点,但是总体开发效率会提升很多。

  另外,测试成本可以节省很多。以前开发的接口都是针对表现层的,很难写测试用例。如果做了前后端分离,甚至测试都可以分开,一拨人专门测试接口,一拨人专注测试UI(这部分工作甚至可以用工具代替)。

3.5 增加Node层带来的风险怎么控制?

  随着Node大规模使用,系统/运维/安全部门的同学也一定会加入到基础建设中,他们会帮助我们去完善各个环节可能出现的问题,保障系的稳定性。

3.6 Node什么都能做,为什么还要JAVA?

  我们的初衷是做前后端分离,如果考虑这个问题就有点违背我们的初衷了。即使用Node替代Java,我们也没办法保证不出现今天遇到的种种问题,比如职责不清。我们的目的是分层开发,专业的人,专注做专业的事。基于JAVA的基础架构已经非常强大而且稳定,而且更适合做现在架构的事情。

四、淘宝基于Node的前后端分离

图3

  上图是我理解的淘宝基于Node的前后端分离分层,以及Node的职责范围。简单解释下:

  • 最上端是服务端,就是我们常说的后端。后端对于我们来说,就是一个接口的集合,服务端提供各种各样的接口供我们使用。因为有Node层,也不用局限是什么形式的服务。对于后端开发来说,他们只用关心业务代码的接口实现。
  • 服务端下面是Node应用。
  • Node应用中有一层Model Proxy与服务端进行通讯。这一层主要目前是抹平我们对不同接口的调用方式,封装一些view层需要的Model。
  • Node层还能轻松实现原来vmcommon,tms(引用淘宝内容管理系统)等需求。
  • Node层要使用什么框架由开发者自己决定。不过推荐使用express+xTemplate的组合,xTemplate能做到前后端公用。
  • 怎么用Node大家自己决定,但是令人兴奋的是,我们终于可以使用Node轻松实现我们想要的输出方式:JSON/JSONP/RESTful/HTML/BigPipe/Comet/Socket/同步、异步,想怎么整就怎么整,完全根据你的场景决定。
  • 浏览器层在我们这个架构中没有变化,也不希望因为引入Node改变你以前在浏览器中开发的认知。
  • 引入Node,只是把本该就前端控制的部分交由前端掌控。

  这种模式我们已经有两个项目在开发中,虽然还没上线,但是无论是在开发效率,还是在性能优化方面,我们都已经尝到了甜头。

五、我们还需要要做什么?

  • 把Node的开发流程集成到淘宝现有的SCM流程中。
  • 基础设施建设,比如session,logger等通用模块。
  • 最佳开发实践
  • 线上成功案例
  • 大家对Node前后端分离概念的认识
  • 安全
  • 性能
  • …

  技术上不会有太多需要去创新和研究的,已经有非常多现成的积累。其实关键是一些流程的打通和通用解决方案的积累,相信随着更多的项目实践,这块慢慢会变成一个稳定的流程。

六、“中途岛”

  虽然“基于NodeJS的全栈式开发”模式很让人兴奋,但是把基于Node的全栈开发变成一个稳定,让大家都能接受的东西还有很多路要走,我们正在进行的“中途岛”项目就是为了解决这个问题。虽然我们起步不久,但是离目标已经越来越近!!


基于前后端分离的模版探索

前言

  在做前后端分离时,第一个关注到的问题就是渲染,也就是 View 这个层面的工作。

  在传统的开发模式中,浏览器端与服务器端是由不同的前后端两个团队开发,但是模版却又在这两者中间的模糊地带。因此模版上面总不可避免的越来越多复杂逻辑,最终难以维护。

  而我们选择了NodeJS,作为一个前后端的中间层。试图藉由NodeJS,来疏理 View 层面的工作。

  使得前后端分工更明确,让专案更好维护,达成更好的用户体验。

本文

  渲染这块工作,对于前端开发者的日常工作来说,佔了非常大的比例,也是最容易与后端开发纠结不清的地方。

  回首过去前端技术发展的这几年, View 这个层面的工作,经过了许多次的变革,像是:

  1. Form Submit 全页刷新 => AJAX局部刷新
  2. 服务端续染 + MVC => 客户端渲染 + MVC
  3. 传统换页跳转 => 单页面应用

  可以观察到在这几年,大家都倾向将渲染这件事,从服务器端端移向了浏览器端。

  而服务器端则专注于服务化 ,提供数据接口。

浏览器端渲染的好处

  浏览器端渲染的好处,我们都很清楚,像是

  1. 摆脱业务逻辑与呈现逻辑在Java模版引擎中的耦合与混乱。
  2. 针对多终端应用,更容易以接口化的形式。在浏览器端搭配不同的模版,呈现不同的应用。
  3. 页面呈现本来就不仅是html,在前端的渲染可以更轻易的以组件化形式 (html + js + css)提供功能,使得前端组件不需依赖于服务端产生的html结构。
  4. 脱离对于后端开发、发佈流程的依赖。
  5. 方便联调。

浏览器端渲染造成的坏处

  但是在享受好处的同时,我们同样的也面临了浏览器端渲染所带来的坏处,像是:

  1. 模版分离在不同的库。有的模版放在服务端 (JAVA),而有的放在浏览器端 (JS)。前后端模版语言不相通。
  2. 需要等待所有模版与组件在浏览器端载入完成后才能开始渲染,无法即开即看。
  3. 首次进入会有白屏等待渲染的时间,不利于用户体验
  4. 开发单页面应用时,前端Route与服务器端Route不匹配,处理起来很麻烦。
  5. 重要内容都在前端组装,不利于SEO

反思前后端的定义

  其实回头想想,在我们把渲染的工作从服务端(Java) 抽出来放到浏览器端(js) 的时候,我们的目的只是明确的前后端职责划分,并不是非浏览器渲染不可 。

  只是因为在传统的开发模式中,出了服务器就到了浏览器,所以前端的工作内容只能被限制在浏览器端。

  也因此很多人认定了后端 = 服务端,前端 = 浏览器端 ,就像下面这张图。


图4

  而在淘宝UED目前进行的 中途岛Midway 项目中,藉由在 JAVA – Browser中间搭建一个NodeJS中间层,试图把这个前后端的分割线,重新针对工作职责 去区分,而分针对硬体环境去区分(服务器 & 浏览器)。

  因此我们有机会做到模版与路由的共享,也是一个前后端分工中最理想的状态。


淘宝中途岛 Midway

  在中途岛项目中,我们把前后端分界的那条线,从浏览器端移回到了服务器端。


图5

  藉由一个由前端 轻松掌控 且 与浏览器共通 的Nodejs层,可以更清晰的完成了前后端分离。

  也可以让前端开发针对不同的情况,自行决定 最适当的解决方案 。而不是所有事情 都在浏览器端来处理 。

职责划分

  中途岛并不是前端试图抢后端饭碗的项目,目的只是把 模版 这个模糊地带切割清楚,取得更明确的职责划分。

  • 后端 (JAVA),专注于
    1. 服务层
    2. 数据格式、数据稳定
    3. 业务逻辑
  • 前端,专注于
    1. UI层
    2. 控只逻辑、渲染逻辑
    3. 交互、用户体验

 

  而不再拘泥于服务端或浏览器端的差异。

模版共享

  在传统的开发模式中,浏览器端与服务器端是由不同的前后端两个团队开发,但是模版却又在这两者中间的模糊地带。因此模版上面总不可避免的越来越多复杂逻辑,最终难以维护。

  有了NodeJS,后端同学可以在JAVA层专注于业务逻辑与数据的开发。而前端同学则专注于控制逻辑与渲染的开发。并且自行选择这些模版是要在 服务端 (NodeJS) 或是 浏览器端 做渲染。

  用著一样的模版语言 XTemplate ,一样的渲染引擎 JavaScript

  在 不同的渲染环境 (Server-side、PC Browser、Mobile Browser、Web View、etc.) 渲染出一样的结果 。

路由共享

  也因为有了NodeJS这一层,可以更细致的控制路由。

  假如需要在前端做浏览器端路由时,可以同时配置服务器端的路由,使其在 浏览器端换页 或是 服务端换页 ,都可以得到一致的渲染效果。

  同时也处理了SEO的问题。


模版共享的实践

  通常我们在浏览器端渲染一份模版时,流程不外乎是

  1. 在浏览器端載入模版引擎 (xtmpleate, juicer, handlerbar, etc.)
  2. 在浏览器端载入模版档案,方法可能有
    • 使用 <script type="js/tpl"> ... </script> 印在页面上
    • 使用模块载入工具,载入模版档案 (KISSY, requireJS, etc.)
    • 其他
  3. 取得数据,使用模版引擎产生html
  4. 将html插入到指定位置。

  從以上的流程可以觀察到,要想要做到模版的跨端共享,重点其实在 一致的模块选型 这件事。

  市面上流行很多种模块标准,例如 KMD、AMD、CommonJS,只要能将NodeJS的模版档案透过一致模块规范输出到NodeJS端,就可以做基本的模版共享了。

  而后续的系列文章会针对Model的proxy与共享,做进一步的探讨。


案例探讨

  因为有了中途岛这中间层,针对过往的一些问题都有了更好的解答,例如说

案例一 复杂交互应用 (如购物车、下单页面)

  • 状况:全部的HTML都是在前端渲染完成,服务端仅提供接口。
  • 问题:进入页面时,会有短暂白屏。
  • 解答:
    1. 首次进入页面,在NodeJS端进行 全页渲染 ,并在背景下载相关的模版。
    2. 后续交互操作,在浏览器端完成 局部刷新
    3. 用的是 同一份模版 , 产生 一样的结果

案例二 单页面应用

  • 状况:使用Client Side MVC框架,在浏览器换页。
  • 问题:渲染与换页都在浏览器端完成,直接输入网址进入或f5刷新时,无法直接呈现同样的内容。
  • 解答:
    1. 在浏览器端与NodeJS端共享 同样的Route 设定
    2. 浏览器端换页时,在浏览器端进行Route变更与 页面内容渲染
    3. 直接输入同样的网址时,在NodeJS端进行 页面框架 + 页面内容渲染
    4. 不管是浏览器端换页,或直接输入同样的网址,看到的内容都是 一样的 。
    5. 除了增加体验、减少逻辑複杂度外。更解决了 SEO 的问题

案例三 纯浏览型页面

  • 状况:页面仅提供资讯,较少或没有交互
  • 问题:html在服务端产生,css与js放在另外一个位置,彼此间有依赖。
  • 解答:
    1. 透过NodeJS,统一管理html + css + js
    2. 日后若需要扩展成复杂应用或是单页面应用,也可以轻易转移。

案例四 跨终端页面

  • 状况:同样的应用要在不同端点呈现不同的介面与交互
  • 问题:html管理不易,常常会在服务端产生不一样的html,浏览器端又要做不一样的处理
  • 解答:
    1. 跨终端的页面是渲染的问题,统一由前端来处理。
    2. 透过NodeJS层与后端服务化,可以针对这类型复杂应用,设计最佳的解决方案。

总结

  过去的AJAX、Client-side MVC、SPA、Two-way Data Binding 等技术的出现,都是试图要解决当时的前端开发遇到的瓶颈。

  而NodeJS中间层的出现,也是在试图解决现今前端被侷限在浏览器端的一个限制。

  这边文章专注于前后端模版共享,也希望能抛砖引玉,与大家一起讨论如何在NodeJS中间层这个架构下,我们可以怎样的改善我们的工作流程,怎样的跟 后端配合,来把 前端 这个工作做得更好。


Midway-ModelProxy — 轻量级的接口配置建模框架

前言

  使用Node做前后端分离的开发模式带来了一些性能及开发流程上的优势(见《前后端分离的思考与实践 一》), 但同时也面临不少挑战。在淘宝复杂的业务及技术架构下,后端必须依赖Java搭建基础架构,同时提供相关业务接口供前端使用。Node在整个环境中最重要的工作之一就是代理这些业务接口,以方便前端(Node端和浏览器端)整合数据做页面渲染。如何做好代理工作,使得前后端开发分离之后,仍然可以在流程上无缝衔接,是我们需要考虑的问题。本文将就该问题做相关探讨,并提出解决方案。


图6

  由于后端提供的接口方式可能多种多样,同时开发人员在编写Node端代码访问这些接口的方式也有可能多种多样。如果我们在接口访问方式及使用上不做统一架构处理,则会带来以下一些问题:

1. 每一个开发人员使用各自的代码风格编写接口访问代码,造成工程目录及编码风格混乱,维护相对困难。
2. 每一个开发人员编写自己的mock数据方式,开发完毕之后,需要手工修改代码移除mock。
3. 每一个开发人员为了实现接口的不同环境切换(日常,预发,线上),可能各自维护了一些配置文件。
4. 数据接口调用方式无法被各个业务model非常方便地复用。
5. 对于数据接口的描述约定散落在代码的各个角落,有可能跟后端人员约定的接口文档不一致。
6. 整个项目分离开发之后,对于接口的联调或者测试回归成本依然很高,需要涉及到每一个接口提供者和使用者。

  于是我们希望有这样一个框架,通过该框架提供的机制去描述工程项目中依赖的所有外部接口,对他们进行统一管理,同时提供灵活的接口建模及调用方式,并且提供便捷的线上环境和生产环境切换方法,使前后端开发无缝结合。ModelProxy就是满足这样要求的轻量级框架,它是Midway Framework 核心构件之一,也可以单独使用。使用ModelProxy可以带来如下优点:

1. 不同的开发者对于接口访问代码编写方式统一,含义清晰,降低维护难度。
2. 框架内部采用工厂+单例模式,实现接口一次配置多次复用。并且开发者可以随意定制组装自己的业务Model(依赖注入)。
3. 可以非常方便地实现线上,日常,预发环境的切换。
4. 内置 river-mock和 mockjs等mock引擎,提供mock数据非常方便。
5. 使用接口配置文件,对接口的依赖描述做统一的管理,避免散落在各个代码之中。
6. 支持浏览器端共享Model,浏览器端可以使用它做前端数据渲染。整个代理过程对浏览器透明。
7. 接口配置文件本身是结构化的描述文档,可以使用 river工具集合,自动生成文档。也可使用它做相关自动化接口测试,使整个开发过程形成一个闭环。

ModelProxy工作原理图及相关开发过程图览

图7

  在上图中,开发者首先需要将工程项目中所有依赖的后端接口描述,按照指定的json格式,写入interface.json配置文件。必要时,需要对每个接口编写一个规则文件,也即图中interface rules部分。该规则文件用于在开发阶段mock数据或者在联调阶段使用River工具集去验证接口。规则文件的内容取决于采用哪一种mock引擎(比如 mockjs, river-mock 等等)。配置完成之后,即可在代码中按照自己的需求创建自己的业务model。

  下面是一个简单的例子:

  【例一】

  • 第一步 在工程目录中创建接口配置文件interface.json, 并在其中添加主搜接口json定义
[javascript]  view plain  copy
  1. {  
  2.     "title": "pad淘宝项目数据接口集合定义",  
  3.     "version": "1.0.0",  
  4.     "engine": "mockjs",  
  5.     "rulebase": "./interfaceRules/",  
  6.     "status": "online",  
  7.     "interfaces": [ {  
  8.         "name": "主搜索接口",  
  9.         "id": "Search.getItems",  
  10.         "urls": {  
  11.             "online": "http://s.m.taobao.com/client/search.do"  
  12.         }  
  13.     } ]  
  14. }  
  • 第二步 在代码中创建并使用model
[javascript]  view plain  copy
  1. // 引入模块  
  2. var ModelProxy = require( 'modelproxy' );   
  3.   
  4. // 全局初始化引入接口配置文件  (注意:初始化工作有且只有一次)  
  5. ModelProxy.init( './interface.json' );  
  6.   
  7. // 创建model 更多创建模式请参后文  
  8. var searchModel = new ModelProxy( {  
  9.     searchItems: 'Search.getItems'  // 自定义方法名: 配置文件中的定义的接口ID  
  10. } );  
  11.   
  12. // 使用model, 注意: 调用方法所需要的参数即为实际接口所需要的参数。  
  13. searchModel.searchItems( { q: 'iphone6' } )  
  14.     // !注意 必须调用 done 方法指定回调函数,来取得上面异步调用searchItems获得的数据!  
  15.     .done( function( data ) {  
  16.         console.log( data );  
  17.     } )  
  18.     .error( function( err ) {  
  19.         console.log( err );  
  20.     } );  

  ModelProxy的功能丰富性在于它支持各种形式的profile以创建需要业务model:

  • 使用接口ID创建>生成的对象会取ID最后’.'号后面的单词作为方法名
[javascript]  view plain  copy
  1. ModelProxy.create( 'Search.getItem' );  
  • 使用键值JSON对象>自定义方法名: 接口ID
[javascript]  view plain  copy
  1. ModelProxy.create( {  
  2.     getName: 'Session.getUserName',  
  3.     getMyCarts: 'Cart.getCarts'  
  4. } );  
  • 使用数组形式>取最后 . 号后面的单词作为方法名
    下例中生成的方法调用名依次为: Cart_getItem, getItem, suggest, getName
[javascript]  view plain  copy
  1. ModelProxy.create( [ 'Cart.getItem', 'Search.getItem', 'Search.suggest', 'Session.User.getName' ] );  
  • 前缀形式>所有满足前缀的接口ID会被引入对象,并取其后半部分作为方法名
[javascript]  view plain  copy
  1. ModelProxy.create( 'Search.*' );  

  同时,使用这些Model,你可以很轻易地实现合并请求或者依赖请求,并做相关模板渲染

  【例二】 合并请求

[javascript]  view plain  copy
  1. var model = new ModelProxy( 'Search.*' );  
  2.   
  3. // 合并请求 (下面调用的model方法除done之外,皆为配置接口id时指定)  
  4. model.suggest( { q: '女' } )  
  5.     .list( { keyword: 'iphone6' } )  
  6.     .getNav( { key: '流行服装' } )  
  7.     .done( function( data1, data2, data3 ) {  
  8.         // 参数顺序与方法调用顺序一致  
  9.         console.log( data1, data2, data3 );  
  10.     } );  

  【例三】 依赖请求

[javascript]  view plain  copy
  1. var model = new ModelProxy( {  
  2.     getUser: 'Session.getUser',  
  3.     getMyOrderList: 'Order.getOrder'  
  4. } );  
  5. // 先获得用户id,然后再根据id号获得订单列表  
  6. model.getUser( { sid: 'fdkaldjfgsakls0322yf8' } )  
  7.     .done( function( data ) {  
  8.         var uid = data.uid;  
  9.         // 二次数据请求依赖第一次取得的id号  
  10.         this.getMyOrderList( { id: uid } )  
  11.             .done( function( data ) {  
  12.                 console.log( data );  
  13.             } );  
  14.     } );  

  此外ModelProxy不仅在Node端可以使用,也可以在浏览器端使用。只需要在页面中引入官方包提供的modelproxy-client.js即可。
  【例四】浏览器端使用ModelProxy

[javascript]  view plain  copy
  1. <!-- 引入modelproxy模块,该模块本身是由KISSY封装的标准模块-->  
  2. <script src="modelproxy-client.js" ></script>  
[javascript]  view plain  copy
  1. <script type="text/javascript">  
  2.     KISSY.use( "modelproxy", function( S, ModelProxy ) {  
  3.         // !配置基础路径,该路径与第二步中配置的拦截路径一致!  
  4.         // 且全局配置有且只有一次!  
  5.         ModelProxy.configBase( '/model/' );  
  6.   
  7.         // 创建model  
  8.         var searchModel = ModelProxy.create( 'Search.*' );  
  9.         searchModel  
  10.             .list( { q: 'ihpone6' } )  
  11.             .list( { q: '冲锋衣' } )  
  12.             .suggest( { q: 'i' } )  
  13.             .getNav( { q: '滑板' } )  
  14.             .done( function( data1, data2, data3, data4 ) {  
  15.                 console.log( {  
  16.                     "list_ihpone6": data1,  
  17.                     "list_冲锋衣": data2,  
  18.                     "suggest_i": data3,  
  19.                     "getNav_滑板": data4  
  20.                 } );  
  21.             } );  
  22.     } );  
  23. </script>  

  同时,ModelProxy可以配合Midway另一核心组件Midway-XTPL一起使用,实现数据和模板以及相关渲染过程在浏览器端和服务器端的全共享。关于ModelProxy的详细教程及文档请移步https://github.com/purejs/modelproxy

总结

  ModelProxy以一种配置化的轻量级框架存在,提供友好的接口model组装及使用方式,同时很好的解决前后端开发模式分离中的接口使用规范问题。在整个项目开发过程中,接口始终只需要定义描述一次,前端开发人员即可引用,同时使用River工具自动生成文档,形成与后端开发人员的契约,并做相关自动化测试,极大地优化了整个软件工程开发过程。


本文转自:http://ued.taobao.org/blog/2014/04/modelproxy/

personal_site:让我们建立一个网站! 立即下载

相关推荐

解决fetch_california_housing数据集403错误的3种实用方法(附手动下载地址)

本文针对机器学习中常见的fetch_california_housing数据集403 Forbidden错误,提供了三种实用的解决方案。从理解HTTP 403错误的根源出发,详细介绍了修改源码路径、使用国内镜像源以及手动下载并配置数据文件这三种方法,并附带了可靠的手动下载地址,帮助开发者彻底解决数据加载障碍,确保机器学习项目顺利进行。

weixin_29062963的博客 559

前后端分离开发,RESTful 接口应该这样设计

译者 |唐尤华https://dzone.com/refcardz/rest-foundations-restful前言REST(Representational State Tra...

公众号:Java后端 2127

【基于51】红外寻迹智能小车 - 代码篇

这是一个基于C51单片机的红外巡线智能小车,是一个适合嵌入式单片机、C语言初学者练习的小Demo,文章提供完整的项目思路、免费的源代码。

ZER00000001的博客 3万+

前后端分离的思考与实践(转载)

前言   为了解决传统Web开发模式带来的各种问题,我们进行了许多尝试,但由于前/后端的物理鸿沟,尝试的方案都大同小异。痛定思痛,今天我们重新思考了“前后端”的定义,引入前端同学都熟悉的NodeJS,试图探索一条全新的前后端分离模式。   随着不同终端(Pad/Mobile/PC)的兴起,对开发人员的要求越来越高,纯浏览器端的响应式已经不能满足用户体验的高要求,我们往往需要

dazhi_100的专栏 1708

从零构建HFSS连接器仿真模型:以SMP接口的精准复现为例

本文详细介绍了如何从零构建HFSS连接器仿真模型,以SMP接口的精准复现为例。通过获取官方模型、导入技巧、信号路径提取和介质结构复现等步骤,帮助工程师避免常见错误,提升高频电路仿真的准确性。文章特别强调了模型精度对仿真结果的影响,并提供了实用的调试和管理建议。

weixin_29041767的博客 429

cesium 深度图(获取区域最高最低点位)

文章摘要: Cesium深度图技术可用于获取区域地形高程数据,核心实现步骤包括:1)通过离屏相机构建独立渲染环境,使用正交投影确保采样精度;2)采用离屏渲染技术获取均匀分布的地形点数据。关键技术点包含多边形外包矩形计算、后台相机配置(5km高度正交投影)、1024×1024像素离屏视图设置,以及深度数据解析(RGBA格式转换和三维坐标还原)。该方法避免了主视图干扰,可精准获取区域内地形高程信息,为填挖方分析等应用提供基础数据支持。

God's asylum的博客 283

前后台分离的演变史

一后端为主的MVC时代 为了降低开发的复杂度,以后端为出发点,比如:Struts、SpringMVC等框架,就是后端的MVC时代。 SpringMVC的架构图 优点: MVC是一个非常好的协作模式,能够有效降低代码的耦合度,从架构上能够让开发者明白代码应该写在哪里。为了让View更纯粹,还可以使用Thymeleaf、Freemaker等模板引擎,是模板无法写入Java代码,让前后端分工更加清晰。 缺点: 前端开发重度依赖开发环境,开发效率低,这种架构下,前后端协助有两种模式: ...

实践求真知 1287

DeepSeek网页版和DeepSeek Harness

DeepSeek网页版是开箱即用的对话工具,适合快速问答与日常任务;而DeepSeekHarness(dsh)是基于Node.js的开源智能体框架,支持文件操作、命令执行、多工具协同,实现“对话即执行”。二者定位不同:网页版为“大脑”,Harness为“躯体”。前者封闭易用,后者开放可扩展,具备可追溯的执行日志与插件化架构。未来,网页版将聚焦轻量化普及,Harness则致力于构建生态平台。对开发者而言,应将AI作为执行层,守住决策层,深耕垂直领域,并掌握AI工作流设计能力,以构建不可替代的技术优势。

几十年资深高级架构师,技术专家的技术笔记。专注C、Java、Python、微服务、云原生、AI工程化及高并发系统分布式架构实战,分享源码剖析、性能调优与架构治理经验。 863

Web前后端:如何分离,如何解耦?

摘要:在本文中我们一起来探讨一下为什么要在软件开发中进行前后端的分离,如何做到前后端分离,如何解耦。 简单地说,就是要把复杂的问题简单化,把一个从0到N的问题转化为N个0到1的问题。另一个相近的说法就是“解耦”。 举个例子,我们接到一个客户需求,要求写一个应用,这个应用中有页面的切换,有对应页面的数据交互,数据的获取,数据的计算,如果把这些功能放在一个单一的应用中的话,从大局观的角度来看,这个单一的应用是比较复杂的。 为了降低这个复杂度,我们首先要做的就是前后端分开,关于前后端的定义,大体来说是这样的

华为云官方博客 5204

【2026最新版】PCL点云处理算法汇总(C++长期更新版)

PCL学习目录。博客长期更新,最近一次更新时间为:2026年10月4日。

点云侠的博客 63万+

ESP32-CAM 赋能 AI 视觉巡检小车:自主避障与目标追踪实现全解析

本文基于 ESP32-CAM 实现了低成本 AI 视觉巡检小车的核心功能,硬件成本<100 元,兼顾自主避障与目标追踪。算法升级:移植 YOLOv5nano 量化模型(INT8),提升目标检测精度(如识别巡检场景中的 “异常物体”“人员”);无线拓展:通过 MQTT 协议将巡检图像、距离数据上传到阿里云 / 腾讯云,实现远程监控;多传感器融合:增加温湿度(DHT11)、红外测温(MLX90614)模块,扩展巡检维度;路径规划:结合 SLAM 算法,实现自主建图与路径巡检。

weixin_42300449的博客 367

前后端分离实践有感

前后端分离并不是什么新鲜事,到处都是前后端分离的实践。然而一些历史项目在从一体化 Web 设计转向前后端分离的架构时,仍然不可避免的会遇到各种各样的问题。由于层出不穷的问题,甚至会有团队质疑,一体化好好的,为什么要前后端分离? 说到底,并不是前后分离不好,只是可能不适合,或者说……设计思维还没有转变过来…… 一体式 Web 架构示意 前后分离...

weixin_33735077的博客 825

康耐视visionpro-CogBlobTool工具详细说明

康耐视visionpro-CogBlobTool工具详细说明

视觉人机器视觉的博客 1724

前后端分离的思考与实践(一)

前后端分离的思考与实践(一) 也谈基于NodeJS的全栈式开发(基于NodeJS的前后端分离) 前言 为了解决传统Web开发模式带来的各种问题,我们进行了许多尝试,但由于前/后端的物理鸿沟,尝试的方案都大同小异。痛定思痛,今天我们重新思考了“前后端”的定义,引入前端同学都熟悉的NodeJS,试图探索一条全新的前后端分离模式。 随着不同终端(Pad/Mobil

小北哥哥和北妈 1221

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

何为前后端分离?一文搞懂前后端分离发展史

简单讲解前后端分离技术,前后端分离技术的演进过程。

Java之路艰难,要以高内聚低耦合的目标去设计 1万+

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

关于前后端分离的思考和总结

对目前的web来说,前后端分离已经变得越来越流行了,越来越多的企业/网站都开始往这个方向靠拢。那么,为什么要选择前后端分离呢?前后端分离对实际开发有什么好处呢?我之前一直对前后端分离的思想一直很模糊,最近恰好碰上公司的项目进行重构,也采用前后端分离。所以就根据自己在实际项目中的开发,总结自己对于前后端分离中遇到的一些疑惑。 前言 首先在此之前,我跟大多数人一样,心中有如下疑问? 什么是前后端...

bobozai86的博客 1357

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

前后端分离的优缺点

WEB 前后端分离三个最大的优点在于:1:最大的好处就是前端JS可以做很大部分的数据处理工作,对服务器的压力减小到最小2:后台错误不会直接反映到前台,错误接秒较为友好3:由于后台是很难去探知前台页面的分布情况,而这又是JS的强项,而JS又是无法独立和服务器进行通讯的。所以单单用后台去控制整体页面,又或者只靠JS完成效果,都会难度加大,前后台各尽其职可以最大程度的减少开发难度。   为了解决传统...

__静禅__ 4万+

小谈什么是前后端分离?

什么是前后端分离? 学习目标什么是前后端分离?前后端分离初了解为什么要前后端分离?1、前后职责分离2、前后技术分离3、前后分离带来了用户用户体验和业务处理解耦4、前后分离,可以分别归约两端的设计前后分离架构接口设计用户认证基于 Cookie/Session 的认证方案基于 OAuth 的认证方案基于 Token/JWT 的认证方案 前后端分离并不是什么新鲜事,到处都是前后端分离的实践。然而一些历史项目在从一体化 Web 设计转向前后端分离的架构时,仍然不可避免的会遇到各种各样的问题。由于层出不穷的问题,甚至

sxp知识共享 3270

若依前后端分离如何写移动端接口_前后端分离实践的架构设计

前后端分离的项目开发策略已经不是什么新鲜东西了,网上介绍这方面的文章非常多。我自己是在14年的时候接触到的,对这种开发策略一直爱不释手,不管新老项目都会首先用前后端分离的思维先去思考一番。从14年到现在在前后分离上面也实践了近3年的时间,项目大大小小的也差不多4,5个吧,但是却从来没有一个是自己觉得很满意的,其中的原由和心酸可能只有自己才能体会了。前后端分离实践有感现在到处都是前后端分离的实践。然...

weixin_39600291的博客 1098

前后端分离的思考与实践

前言 为了解决传统Web开发模式带来的各种问题,我们进行了许多尝试,但由于前/后端的物理鸿沟,尝试的方案都大同小异。痛定思痛,今天我们重新思考了“前后端”的定义,引入前端同学都熟悉的NodeJS,试图探索一条全新的前后端分离模式。   随着不同终端(Pad/Mobile/PC)的兴起,对开发人员的要求越来越高,纯浏览器端的响应式已经不能满足用户体验的高要求,我们往往需要针对不同的终端开发定制...

莫等闲的博客 564
上一篇: 从MVC到前后端分离
下一篇: Web 研发模式的演变
simon-hacker
博客等级 码龄12年 4粉丝 23原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值