使用Rails构建JSON API

前言

随着技术的发展,近年很多的网站、移动应用程序、微信小程序等等,采用前后端分离、使用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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Api::V1::BaseController < ApplicationController
# disable the CSRF token
protect_from_forgery with: :null_session

# disable cookies (no set-cookies header in response)
before_action :destroy_session

# disable the CSRF token
skip_before_action :verify_authenticity_token

# skip devise user authentication
skip_before_action :authenticate_user!

def destroy_session
request.session_options[:skip] = true
end
end

创建好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
2
3
4
5
6
class Api::V1::ArticlesController < Api::V1::BaseController
def show
@article = Article.find(params[:id])
end
end

配置路由

接下来我们对路由config/routes.rb进行配置

1
2
3
4
5
namespace :api do
namespace :v1 do
resources :articles
end
end

配置视图

articles控制器的视图代码位于app/views/api/v1/articles/,我们在其中建立show.json.jbuilder文件,内容如下:

1
2
3
json.article do
json.(@article, :id, :title, :content)
end

上面这段代码,是jbuilder建立json的语句代码,至于jbuilder的用法,可以参考这篇文章http://ohcoder.com/blog/2015/04/19/jbuilder/

访问接口

启动Rails程序,访问/api/v1/articles/1.json,即可看到接口输出的JSON数据。

接口通信

除了从接口获取JSON数据以外,我们还需要向接口POST JSON数据,并希望接口实现数据的解析和保存。
首先像往常一样,需要在控制器中创建create方法,用于新建数据:

1
2
3
def create
@host = Host.create(article_params)
end

呵呵,一行代码,是的,就这么简单。
而article_params,则是个私有方法,大概需要这样实现:

1
2
3
def article_params
params.require(:article).permit(:title, :content)
end

在客户端(或网页中)向该接口发送数据,地址是/api/v1/articles

发送的数据类似下面这样:

1
2
3
4
5
6
{
"article":{
"title":"test",
"content":"a test article from client"
}
}

直接发送这条数据可能会出错,因为在请求的时候需要带上json格式描述

1
2
Content-Type: application/json
Accept: application/json

完整的POST请求,参考下:

1
2
3
4
5
6
7
8
9
10
11
12
POST /api/v1/articles HTTP/1.1
Host: localhost:3000
Content-Type: application/json
Accept: application/json

{
"article":{
"title":"test",
"content":"a test article from client"
}
}

AAPT获取APK名称 Rails Devise 基础案例
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×