使用Rails构建一个TO-DO应用的JSON API (Part I)

第一部分包括,介绍,配置并建立应用,基本业务逻辑与测试

介绍:众所周知Rails最初是为了迅速构建Web应用而建立的框架,但是技术总是会随着发展而变化,移动端的应用不需要很多富文本信息,作为服务端只要提供纯粹的JSON API就够了。所以去年Rails5发行以来,
rails-api(https://github.com/rails-api/rails-api)这个gem被整合到Rails内核中。对比于同样使用Rails建立的普通的Web App,他们的区别是:

1. 应用的中间件(middleware)减少了

2. ApplicationController 继承自ActionController::API,而不是ActionController::Base

3. 不需要建立的对应的视图文件,不需要HTML,CSS,嵌入式Ruby什么的那一堆东西

接下去,我们来建立这个应用,检查下环境:

整理下,我们需要的RESTful API,给自己一个小目标😊:

好的,开始建立应用

–api 是说明应用只是支持JSON API,那些Web应用的中间件我们不要。-T是说,我们不要Rails自带的测试框架Minitest,因为我们要测试Request,还有他的返回值,RSpec是首选。看下我们需要的gem,并给出list:

这是最后的Gemfile:

完了bundle install,我们在本地使用sqlite3数据库,但是heroku不支持,换成了Postgres。接下来我们配置下Rspec

你会发现增加了以下三个文件:.rspec, spec/spec_helper.rb, spec/rails_helper.rb

再增加一个factories目录:

然后我们配置这些添加的Gem

打开spec/rails_helper.rb

现在创建Models,开始书写基本的业务内容

Model的名字叫Todo, 有两个属性title, created_by, 顺便检查下生成的迁移文件,db/migrate/[timestamp]_create_todos.rb

同样的,我们增加另外一个Model叫做Item

reference是添加外键,一个item点开来以后是多个todo待办事项对吧,所以他们的关系也是1:n。打开迁移文件,确认外键关系:

最后记得,把model映射到数据库,Rails有专业术语叫migrate

好吧,测试驱动,我们要开始写测试了,看到spec/models/todo_spec.rb

其实我不加注释,也应该能看懂,因为太显而易见了😄。不得不说,Rspec是非常具有表现力的DSL(Domain Specific Language)。继续看到spec/models/item_spec.rb

看到shoulda matchers在Rspec中的作用了对吧,字面意思就是item应该属于todo,验证name字段的存在性,就是普通的英语短句。

如果现在运行测试用例,当然不可能通过,不信自己试下:

一片红的对吧😄

开始让他们变绿,看到app/models/todo.rb

app/models/item.rb

再次运行spec,都变绿了对吧,必须的嘛

现在来写Controller

我们不会写controller的测试,而是要写request的测试,因为覆盖得更加多,包括路径,请求完成以后的回调。创建文件夹和相关的文件

记得不能写成todos_spec.rb,会引起重复引用的错误:in `method_missing’: Factory already registered: item (FactoryGirl::DuplicateDefinitionError)

增加固件测试,就是跑测试用例时候的样本文件:

编辑文件spec/factories/todos.rb,加上两个假数据

再看spec/factories/items.rb,类似的,先不管外键

最后写关键的Request测试部分,看到spec/requests/todos_spec.rb

一个describe对应一个Request测试,各种断言,一次返回10条todos,json数据不能为空,而且状态码是200,太明显了对吧,Rspec确实语法简练。然后我们要定义json方法,解析JSON数据到Ruby hash,创建

写入spec/support/request_spec_helper

support目录不是自动添加到工程的,打开这个文件spec/rails_helper.rb写入

然后我们配置跳转的路由,打开config/routes.rb

对,就是这么神奇,一个循环😄

看下路由对不对,然后配置controller中的方法,app/controllers/todos_controller.rb

还记得那个返回状态码的json_response方法,配置下,app/controllers/concerns/response.rb

还有统一的异常处理,app/controllers/concerns/exception_handler.rb

在TodosController中我们使用create!,而不是create方法,这样就直接抛出异常ActiveRecord::RecordInvalid,在ExceptionHandler中实现异常的复用。然后在app/controllers/application_controller.rb加入帮助文件,让他们生效

最后测试下,是不是都变绿了😄

接下去类似的写下item的测试,app/requests/items_spec.rb

编辑 app/controllers/items_controller.rb

所有测试变绿,没问题吧



发表评论

电子邮件地址不会被公开。 必填项已用*标注