前言
随着技术的发展,近年很多的网站、移动应用程序、微信小程序等等,采用前后端分离、使用JSON API数据传递这种方式来设计和开发。如此,前端程序可以保持独立、并且相对来说比较完整,后端程序逻辑复杂、性能强劲。前端可以有丰富的对数据的展现方式(图表、动画等等),后端也只需要完善相应的对模型的控制,同时输出一份前端所需要的数据,采用Ajax+JSON方式传递,从而让前后端的开发相对而言都更为轻松,在结构合理、技术完备的情况下,工程层面也能实现较大程度的规模上的突破。
Rails作为一种流行的MVC框架,本身在API的开发上已经有了很成熟的配套设施了。Rails的模板支持.json.jbuilder形式的JSON数据渲染,配合jbuilder从模型对象数组直接创建JSON数据,在开发上有着无与伦比的便利。在此之前,如果使用php开发程序,从数组创建JSON,需要先整理好数组,再json_encode(Array)进行输出,很是麻烦。当然身为PHP程序员的你可能要说,PHP也有很强大的API构建框架,可以很方便的构建出健壮的API,是的,我承认有这些框架的存在,只是限于本人的水平和喜好,在PHP开发方面并没有走的那么深远,也就不熟悉其中的一些高级操作了。如果有兴趣,也可以发邮件就这方面进行一些探讨。
近期由于一个项目的需要,需要从已有的Rails应用中开辟出一个新的独立接口,供客户端程序调用,因此学习了一下Rails API的构建方法,也顺便留下此文,作为记录。关于Rails API的构建,我参考了这篇文章 https://blog.csdn.net/li_001/article/details/65937664
以下就是如何使用Rails构建JSON API
我当前采用的环境是 Ruby 2.4.1 + Rails 5.2.0
配置控制器
首先假设我们的应用已经创建好了,并且建立一个Article模型,包含两个字段,title和content,运行迁移并创建种子数据。
此时进入项目根目录,新建一个控制器:
1 | rails g controller api/v1/base --no-assets |
这个控制器的代码就会位于app/controllers/api/v1/base_controller.rb,我们需要在其中完善一些权限有关的配置。
由于Rails默认的安全属性,以及我们如果之前自定义了一些控制器中的过滤方法,我们需要在该控制器中跳过它,例如我们首先禁用rails自带的CSRF 保护和CSRF token的输出,以及去除掉返回包中的set-cookies头,由于我的应用还使用了devise作为用户认证的模块,所以还要在此禁用掉authenticate_user方法。
完整的代码如下:
1 | class Api::V1::BaseController < ApplicationController |
创建好base控制器以后,我们需要在这个控制器的基础上派生出一些新的控制器,这里我们新建一个articles控制器
1 | rails g controller api/v1/articles --no-assets |
此时除了会生成控制器代码以外,还会在app/views/api/v1目录下创建articles目录,作为模板存放的目录。
articles控制器的代码位于app/controllers/api/v1/users_controller.rb,内容如下
先在其中定义一个show方法:
1 | class Api::V1::ArticlesController < Api::V1::BaseController |
配置路由
接下来我们对路由config/routes.rb进行配置
1 | namespace :api do |
配置视图
articles控制器的视图代码位于app/views/api/v1/articles/,我们在其中建立show.json.jbuilder文件,内容如下:
1 | json.article do |
上面这段代码,是jbuilder建立json的语句代码,至于jbuilder的用法,可以参考这篇文章http://ohcoder.com/blog/2015/04/19/jbuilder/
访问接口
启动Rails程序,访问/api/v1/articles/1.json,即可看到接口输出的JSON数据。
接口通信
除了从接口获取JSON数据以外,我们还需要向接口POST JSON数据,并希望接口实现数据的解析和保存。
首先像往常一样,需要在控制器中创建create方法,用于新建数据:
1 | def create |
呵呵,一行代码,是的,就这么简单。
而article_params,则是个私有方法,大概需要这样实现:
1 | def article_params |
在客户端(或网页中)向该接口发送数据,地址是/api/v1/articles
发送的数据类似下面这样:
1 | { |
直接发送这条数据可能会出错,因为在请求的时候需要带上json格式描述
1 | Content-Type: application/json |
完整的POST请求,参考下:
1 | POST /api/v1/articles HTTP/1.1 |