Rails 开发者零成本上手的 RESTful API 框架.
Lina 是基于 Ruby on Rails
, JSON Schema, jbuilder
的 RESTful API 开发框架, 整合 Ruby on Rails 开发 API 的最佳实践, 并添加 API 文档, 校验等必备功能.
它的特点:
- Rails 开发者零成本上手
- 自动生成 API 文档
- 自动校验入口参数
- 自动校验返回值参数
与 Ruby on Rails
几乎体验一致, 与 grape
相比, 更加易于上手.
在 Rails 项目的 Gemfile 中添加
# Gemfile
gem 'lina'
bundle install
之后, 安装
$ rails g lina:install
# 生成对应的 API
$ rails g lina:api posts index
启动 Rails 后, 访问 http://localhost:3000/apidoc
得到你的 API 文档.
ps: 目前仅支持 Rails 4.1
, Rails4.2
, 如果你有更低版本的支持需求, 请告诉我.
Rails 新手 Lina 使用说明: Rails 新手?( TODO )
使用方法
自动 APIDOC
Lina
会遍历所有 API 控制器, 自动生成项目的 APIDOC, 供前端或客户端 APP 使用.
APIDOC 中包括:
- 路径
- API 名称与描述
- 参数说明
- 返回值说明
无须重启服务, APIDOC 会自行更新.
默认情况下, 访问 http://localhost:3000/apidoc
即可.
挂载点可以在 config/routes.rb
中调整:
api_for '/apidoc'
控制器
-
继承
Lina::ApplicationController
. -
使用
define_action(action_name, api_spec, &block)
定义 API.-
action_name
: 方法名 -
api_spec
: API 描述信息, 如下代码所示. 它有两个用途:- 参数及返回值校验
- 自动生成 APIDOC
-
&block
: 控制器实际代码
-
你可以使用 Lina API 生成器 rails g lina:api posts index show
来快速生成代码.
Lina
控制器逻辑代码完全兼容 Rails
的控制器, filter
, render
, params
都与 Rails
完全一致.
class UsersController < Lina::ApplicationController
define_action :show, {
# API 名称
name: '显示某个用户的信息',
description: '传入一个ID, 显示这个用户的信息',
# 通过 json-schema( 将在下面详细介绍 ) 描述参数约束
params: {
type: 'object',
required: [ 'id' ],
properties: {
id: {
type: 'string',
description: '用户ID',
}
}
},
return: {
type: 'object',
required: [ 'name', 'id' ],
properties: {
name: {
type: 'string',
},
id: {
type: 'integer',
}
}
}
} do
# 像 Rails 一样获取 params
@user = User.find(params[:id])
render json: { name: @user.name, id: @user.id }
end
end
参数声明
params
与 return
都是使用 json-schema
来描述参数的约束条件.
Lina
会在参数传入控制器之前, 进行 params
参数检查, 失败时抛出 Lina::ParamsCheckError
. return
在返回的JSON同样进行检查, 对应抛出 Lina::ReturnCheckError
. 这些行为可以在 config/initializers/lina.rb
中调整.
json-schema
是一个声明 JSON 格式规范的标准. 假如我们要定义一个 API, 参数要求:
name: 必填, string 类型, 不少于 3 个字符, 不超过 10 个字符.
city: 必填, string 类型, 只能在 [ '深圳', '上海', '北京' ] 中选取其一.
roles: 必填, array 类型, 在 [ '老师', '学生', '浏览者' ] 至少选一个.
gender: 非必填, boolean 类型.
bio: 非必填, string 类型.
json-schema
写法如下:
{
type: 'object',
required: [ 'name', 'city', 'roles' ],
properties: {
name: {
type: 'string',
description: '用户名, 3-10个字符',
maxLength: 10,
minLength: 3,
},
city: {
type: 'string',
description: '城市',
enum: [ '深圳', '上海', '北京' ],
},
roles: {
type: 'array',
description: '角色',
minItems: 1,
items: {
type: 'string',
enum: [ '老师', '学生', '浏览者' ],
}
},
gender: {
type: 'boolean',
description: '性别',
},
bio: {
type: 'string',
description: '个人介绍',
}
}
}
description
是为了 APIDOC 使用, 可选.
Lina
会在入口参数进行校验, 这份约束会同时展示到 APIDOC 里.
return
的写法与 params
一致.
json-schema
非常强大与简洁, 可以很容易地写出既优雅又安全的代码, 更全面的例子参考 json-schema 官方例子
JSON 生成
缺省情况下, Lina
的控制器会尝试渲染对应的 action
的 action.json.jbuilder
, 例如: PostsController#index
将会渲染 app/views/posts/index.json.jbuilder
.
一个例子:
#index.json.jbuilder
json.array! @posts do |post|
json.extract! post, :name, :content, :created_at
end
Lina
整合了 jbuilder
, 请到这里查看更多写法: Jbuilder README
路由与版本
Lina
沿用了 Rails
的路由系统, 建议使用 Rails RESTful Route
写法:
Rails.application.routes.draw do
resources :posts, only: [:index, :show]
resources :labels, only: [:index] do
member do
post :approve
end
end
end
对外的 API 一定要用版本号隔开, 如下:
scope 'api/v1' do
# get 'api/v1/posts', controller: 'PostsController'
resources :posts, only: [:index]
end
scope 'api' do
namespace 'v2' do
# get 'api/v2/posts', controller: 'V2::PostsController'
resource :posts, only: [:index]
end
end
更复杂的版本号需求, 可参考 stack overflow 讨论
一个非常好的例子: rubygems.org 路由源码
权限与认证
Lina
为了保持简洁, 并不提供这部分的支持, 但整合非常容易.
你可以像 Rails
一样使用 Lina
.
CORS 跨域
推荐使用 rake-cors
整合.
测试
Lina
控制器的测试与 Rails
完全一致(事实上, lina:api 生成器会自动生成对应的测试代码 ), 在 Test::Unit 中, 一个例子如下
class DesksControllerTest < ActionController::TestCase
test "#index" do
get :index
assert_equal [ {'name'=> 'name1'}, {'name'=> 'name2'} ], JSON.parse(response.body)
end
test "#show validate failed" do
assert_raise(Lina::ParamsCheckError) { get :show, id: 1, filter_name: 'x' * 6 }
end
test "#update return validate failed" do
assert_raise(Lina::ReturnCheckError) { put :update, id: 1 }
end
end
贡献指南
Lina 做了以下几件事情:
define_action
实际上会将 API 信息存入类变量中, APIDOC 通过Lina::ApplicationController
的子类遍历, 依据这些信息显示的.- 覆写
send_action
, 提供入口检测与返回参数检测. - 提供生成器
lina:install
,lina:api
. - 添加
api_for
路由项. - 一个强大的 APIDOC
lina
使用了 appraisals 测试不同版本 Rails 的支持情况.
首次开发时, 请使用 bundle install
和 appraisal install
来安装各版本 Rails 的依赖.
提交 PR 时, 请确保本地 appraisal rake
通过.
常见问题
访问 APIDOC 时 出现 Lina::ApiSpecError in Lina::ApidocController
-
Lina::ApiSpecError
说明某处的 API 定义出现了问题, 不符合约定, API 声明时, 必须有name
,params
,return
. -
Lina::ApiSpecParamsError
说明 API 定义时params
不符合 JSON Schema 的格式, 请检查. -
Lina::ApiSpecReturnError
说明 API 定义时return
不符合 JSON Schema 的格式, 请检查.
TODOLIST
- Schema Form ( TODO )
- ActiveRecord Validator Helper ( TODO )
贡献者
License
MIT.