如何使用 Rails5 API 模式和 Backbone 构建一个应用 已翻译 100%

Zoker 投递于 2016/07/18 14:27 (共 6 段, 翻译完成于 07-21)
阅读 1532
收藏 0
0
加载中

几周以前,一份声明引述了即将被引入Rails核心的Rails API。到目前为止,Rails API 还是一个独立的项目,而人们要使用它就得通过 rails-api 这个 gem

Santiago Pastorino 和我有段时间致力于将 Rails API 带到 Rails 中去。在进行了一些更加深入的讨论之后,BUG被修复并且进行了最终的修改,对应的提交请求 最终也获得了通过。我们很高兴地确认,所有 Rails API 的功能在 Rails 5 发布时都能使用了!

Rails API 的目标是促进Rails工程的上的API实现,而之前只是 Rails 功能的一个子集是能用的。Rails API 应用程序拥有轻量的控制器,简化的中间件栈以及自定义的生成器。所有这些功能都被预期能在构建应用程序的API时带来更好的体验。

更多有关于 Rails API 项目的详细信息,可以看看这篇Santiago Pastorino的文章。

LeoXu
翻译于 2016/07/19 12:14
0

如何通过一个简单的backbone应用实现一个后端的Rails接口?

让我们来创建一个应用程序的接口吧!本文的其他部分是通过由Backbone实现的一个简单的TODO list应用来一步步讲述如何构建一个后端的Rails接口。

因为我们希望把重点放在后端的实现,以及它与客户端应用程序的集成,我们决定从TODO MVC项目里借鉴Backbone TODO应用

创建一个应用程序的接口

一旦Rail5发布,创建一个应用程序的接口就会在运行时完成。

rails new <application-name> --api

但是,这个功能只是在写的时候合并到主分支,因此我们需要直接的通过最新版本的Rail源代码来生成应用程序。获取代码的最简便的方法就是在我们电脑里把Rail的Github项目克隆下来。

git clone git://github.com/rails/rails.git

现在我们必须在我们之前克隆下来仓库所在的文件夹里运行`rails new`命令。为了我们生成的项目能够指向我们本地复制的Rails源码,我们需要通过以下的方式来运行这个命令:

bundle exec railties/exe/rails new <parent-folder-path>/my_api_app --api --edge

这是一个好点子来指定生成项目的一个路径,因此我们可以避免在Rail源码的文件夹里创建Rail应用程序接口。

这就解释了下面的例子提到的`<parent-folder-path>`占位符。

tv_哇
翻译于 2016/07/19 13:48
0

现在我们可以研究下我们在新项目文件夹里创建的东西。你就会发现几乎所有的东西看起来都和一个常规的Rails应用程序完全一样。不过,让我们来高亮出哪些是不一样的。

生成的Gemfile中有这么一些改变。

source 'https://rubygems.org'

gem 'rails', github: "rails/rails"
gem 'sprockets-rails', github: "rails/sprockets-rails"
gem 'arel', github: "rails/arel"

# Use sqlite3 as the database for Active Record
gem 'sqlite3'
# Use ActiveModel has_secure_password
# gem 'bcrypt', '~> 3.1.7'

# Use Unicorn as the app server
# gem 'unicorn'

# Use Capistrano for deployment
# gem 'capistrano-rails', group: :development

# Use ActiveModelSerializers to serialize JSON responses
gem 'active_model_serializers', '~> 0.10.0.rc1'

# Use Rack CORS for handling Cross-Origin Resource Sharing (CORS), making cross-origin AJAX possible
# gem 'rack-cors'

group :development, :test do
  # Call 'byebug' anywhere in the code to stop execution and get a debugger console
  gem 'byebug'
end

group :development, :test do
  ....
end

我们可以发现那个与asset 管理和模板渲染有关的东西已不再存在(jquery-rails和turbolinks等)。此外,active_model_serializers在默认情况下是包含里面的,因为它负责通过我们的API应用程序返回序列化的JSON响应。

让我们来看看config/application.rb 文件吧

....
....

module TodoRailsApiBackend
  class Application < Rails::Application

    ....
    ....

    # Only loads a smaller set of middleware suitable for API only apps.
    # Middleware like session, flash, cookies can be added back manually.
    # Skip views, helpers and assets when generating a new resource.
    config.api_only = true
  end
end

api_only配置选项使得我们的Rails应用程序有可能和那些不需要应用程序API的中间件和控制器模块一起工作。

最后但也很重要的是,我们的主应用程序的定义略有不同:

class ApplicationController < ActionController::API
end

请注意,ApplicationController是继承自ActionController::API的。同时也要记住,Rails标准应用程序的控制器是继承自ActionController::Base的。

如果你有兴趣把一个已存在的Rails应用程序变成一个应用程序的API,下面提到的差异变化的列表,你需要亲手的来实现它。

tv_哇
翻译于 2016/07/19 23:13
0

这跟一个标准的Rails应用在运行完scaffold命令后的结果完全一样。然而这行代码却仅仅定义了我们API所需要的那些路由,也就是说,新建的路由和修改资源的路由被排除了。我们可以通过执行bin/rake routes(译者注:Rails 5中的rake命令可完全使用rails代替,这里可以执行 bin/rails routes来证实这一点:


Prefix Verb   URI Pattern          Controller#Action
 todos GET    /todos(.:format)     todos#index
       POST   /todos(.:format)     todos#create
  todo GET    /todos/:id(.:format) todos#show
       PATCH  /todos/:id(.:format) todos#update
       PUT    /todos/:id(.:format) todos#update
       DELETE /todos/:id(.:format) todos#destroy
不要忘记执行 bin/rake db:migrate , 现在数据库已经准备好,是时候测试我们的应用了。


TODO项该如何被序列化

我们的API模式的应用会以JSON格式来响应请求,在这里,Active Model Serializers就扮演了重要的角色,它定义了一个TodoSerializer类并且提供响应内所需TODO模型的一系列属性。

Active Model Serializers 提供了一个命令来生成这个serializer

bin/rails g serializer todo title completed order

生成的文件在 app/serializers/todo_serializer.rb:

class TodoSerializer < ActiveModel::Serializer
  attributes :id, :title, :completed, :order
end

这个时候,我们就实现了一个几乎工作量为零的后端应用。我们可以执行bin/rails s来启动这个应用,并且利用curl命令来帮助我们测试API。

新建一个Todo


curl -H "Content-Type:application/json; charset=utf-8" -d '{"title":"something to do","order":1,"completed":false}' http://localhost:3000/todos

返回的结果应该是:

{"id":1,"title":"something to do","completed":false,"order":1}

我们现在可以试下去取所有的Todo:

curl http://localhost:3000/todos

结果应该是:

[{"id":1,"title":"something todo","completed":false,"order":1}]

Zoker
翻译于 2016/07/21 00:23
0

将组件集成一起运行起来

是时候将 Backbone 应用程序同我们的后台实现集成到一起了!

这个TODO列表应用程序的原有实现使用了浏览器的本地存储。而我们想要将 Rails API  应用程序指定为数据新的存储。

让我们对 js/collections/todos.js 中下面几行代码进行替换:

  // Save all of the todo items under the `"todos"` namespace.
  localStorage: new Backbone.LocalStorage('todos-backbone'),

使用我们为TODO项准备的API端点的URL定义:

// Set the rails-api backend endpoint for this specific model
  url: 'http://localhost:3000/todos',

进行了这个修改之后,我们就几乎已经准备好了。最后一个重要的任务就是配置一下跨域策略,以使得组件之间的通信成为可能。当后台和客户端组件在不同的域时,这个就是必要的操作。因为我们是在本地做测试,因此都会是在localhost上运行,但使用的是不同的端口, 所以如果我们没有配置跨域策略的话,在浏览器中就会发生CORS错误。

在 Rails API 中, CORS 的处理默认是没有启用的,不过你可以在 Gemfile中找到 ack-cors 这个gem,不过被注释掉了。

为了修复 CORS 的问题,我们只需要取消对这一行的注释,然后再 Rails API工程中重新运行bundle install就行了。我们也会需要看一眼 config/initializers/cors.rb 这个文件。这个文件有一个关于如何在工程中配置 CORS 的示例。

让我们在这个文件中做一些修改,这样我们就能对两个组件都进行测试, 假设我们要使用端口9000来运行客户端应用程序:

# Avoid CORS issues when API is called from the frontend app
# Handle Cross-Origin Resource Sharing (CORS) in order to accept cross-origin AJAX requests

# Read more: https://github.com/cyu/rack-cors

 Rails.application.config.middleware.insert_before 0, "Rack::Cors" do
   allow do
     origins 'localhost:9000'

     resource '*',
       headers: :any,
       methods: [:get, :post, :put, :patch, :delete, :options, :head]
   end
 end

你可以在这里读到更多关于 rack-cors 这个 gem 以及如何配置策略的内容。

只要我们在后台配置好了跨域策略,就已经准备好对客户端应用程序进行测试了。我们应该启动后台服务器 (bin/rails s) 并且也为 Backbone应用程序运行一个独立的web服务端。

我们可以使用Ruby来简单地运行一个测试服务端,来对前端进行本地测试。在Backbone应用程序的目录中运行下面的命令:

ruby -run -e httpd . -p 9000

试试浏览一下 localhost:9000。你会发现TODO项现在已经被存储到我们的Rail API后台了,而不是浏览器的本地存储中。这样,两个组件相互之间就可以连接起来和通信了。

LeoXu
翻译于 2016/07/21 17:40
0

结 论

本文的目的是怎样使用新的 Rails API 实现一个简单的主干应用程序的后端 API 。Rails API 使用 Rails 的源码,你可以用这个功能计数,下一个版本的 Rails 发布,这个功能就即将来临。

一些东西仍然可以改善。例如,该文件包含 TodoSerializer 类,当 active_model_serializers gem 被包含在项目中时,应该生成脚手架命令的一部分。这个特定的问题我们已经修复,并且 它已经被合并到主分支, 下一个发布版本 ofactive_model_serializers 的发布,已经准备好了。

我们也有其他选项来序列化。实际上,我们已经做好 Rails API 与 JBuilder 的配合。在 Rails 的生态系统内,这个库是一个选择,它允许定义 JSON 响应的模板来替代特殊定义的序列化类并作为 活跃模型序列化 (Active Model Serializers)。

尽管 Rails API 只是被纳入 Rails ,当然,这可以改进,我希望你感觉到 API 的舒适与高效实现,有了这个新功能,下一个 Rails 版本也准备好了。

享受  Rails API 的探索! 

资 源

你可以找到后端,并且前端应用已经在 Github 上发布。

后端应用是基于后端例子的,它被包含在 TodoMVC project 。

溪边九节
翻译于 2016/07/19 20:15
0
本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接。
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。
加载中

评论(2)

在座的各位都是韭菜
在座的各位都是韭菜

引用来自“Zoker”的评论

之前的第四段我翻译了一半,然后错误提交,删除之后,英文原文也没了 @蓝一点
删除的那段添加进去了。
Zoker
Zoker
之前的第四段我翻译了一半,然后错误提交,删除之后,英文原文也没了 @蓝一点
返回顶部
顶部