JavaScript MVC 和 RESTful Web API

最近 Web 开发的一个趋势是在前端(Javascript)应用 MVC 架构, 主要是让浏览器处理大部分的功能,比如界面展示和交互, 服务器端仅提供数据和服务接口。

JavaScript MVC

JavaScript MVC 架构与使用 Ruby on Rails, Django, Struts 等框架的传统开发的一个主要区别, 是在浏览器端处理 HTML 视图。传统的流程一般在服务器端生成需要显示给用户的 HTML,然后通过 HTTP 响应发送到用户的浏览器直接显示。而 Javascript MVC 的方法一般是提前下载好需要显示的 HTML 视图/模板, 然后根据从服务器得到的数据, 在浏览器里使用 JavaScript 生成对应的 HTML 显示出来。

这种方式比较适合于单页应用(SPA)这种前端交互比较复杂的场景. 另外, 它也让 web 开发的层次更加清晰。传统的开发流程,服务器端代码既要处理业务逻辑,又要负责将数据装入视图模板. 在 JavaScript MVC 的架构中, 后端代码只负责实现 API 接口, 前后端的开发得到了解藕. 通过模拟 API 接口的工具或是使用 HTML5 的 Local Storage, 甚至不需要任何的后端开发工作就能展示网站的基本功能, 这对于快速进行原型开发和演示很有用.

一些 JavaScript MVC 框架会提供 UI Binding 功能,就是当 HTML 元素中的数据发生变化时,不需要手动操作 DOM,HTML 元素的内容就会自动更新。这里有个简单的例子, 可以感受一下。在这个 TODO 应用里,所有操作都没有手动去设置 HTML 元素的内容,而是直接修改 JavaScript 数据, 然后由 JavaScript MVC 框架提供的 UI Binding 功能自动更新。

RESTful Web API

另一方面, 服务器端的 API 接口设计得讲究一点, 因为接口的改变会有牵一发而动全身的后果(前后端都得跟着变). 目前最流行的 Web API 架构模式是 REST, 但是真正理解和遵守 REST 模式的可能并不多. 这里 是一些我收集的 RESTful Web 服务设计相关的资料, 可以参考下.

有的 JavaScript MVC 框架(例如 Ember 和 AngularJS)会提供对 RESTful API 的封装,通过调用 Model 的方法由框架来自动发送 API 请求. 例如(下面的是 CoffeeScript 代码,相当于 JavaScript):

App.NewPostView = Em.View.extend
  # 提交 post 表单时执行
  submit: (event) ->
    event.preventDefault()
    post = @get('post')
    # 这里
    post.saveResource()
      .fail (e) ->
        App.displayError(e)
      .done ->
        App.postsC.pushObject post

其中的 post.saveResource() 会自动调用相应的 API 请求并将新 post 的数据发送给服务器端。例如对于 Rails 默认的 RESTful 设计, 会发送 POST 请求到 /posts; 对于这个 saveResource 方法, 如果 postid 是 1, 那么会发送 PUTPATCH 请求到 URL: /posts/1.

常见的 JavaScript MVC 框架

最有名的 JavaScript MVC 框架要属 Backbone.js 了, 它的优点是轻量灵活, 文档丰富, 缺点是只提供了基本的功能, 可能需要手动组合一些插件一起使用。相对重量一点的有 Ember.jsAngular.js. 可以参考下 这篇比较各种 JavaScript MVC 框架的文章.

对 Ember.js 感兴趣的同学可以参考 这篇英文教学,也可以查看我根据这篇教学写的 ember-rails-demo(主要的 JavaScript 代码在 app/assets/javascripts/app 文件夹)。


更新 (2014-01-18):