手动修改 API 文档好麻烦,如果能自动生成那该有多好
用到的 Gem: pry-rails
获取手环数据列表-list_wristband
请求:GET /api/v2/wristbands/list_wristband
参数校验:
# action内的每个#号开头的注释,required optional开头的代码行都会写入文档,你可以写任何东西
required(:b_user_id, :String)
optional(:search_begin_at, :Timestamp) # 数据起始时间
optional(:search_end_at, :Timestamp) # 数据结束时间
参数:
{
"b_user_id": 3793,
"search_begin_at": 1526745600,
"search_end_at": 1529424000
}
返回值:
{
"status_code": "20000",
"status_message": "ok",
"data": {
"wristbands": [
{
"id": 1,
"b_user_id": 3793,
"day_time_stamp": 1529424000,
"distance": 0.0,
"walk_step": 0,
"cardiopul_monary_exercise": 0,
"fat_exercise": 0
},
"timestamp": 1526745600
}
}
......
class Api::V2::WristbandsController < Api::V2::BaseController
def list_wristband
# action内的每个#号开头的注释,required optional开头的代码行都会写入文档,你可以写任何东西
required(:b_user_id, :String)
optional(:search_begin_at, :Timestamp) # 数据起始时间
optional(:search_end_at, :Timestamp) # 数据结束时间
render_json Api::V2::WristbandsService.list_wristband(params)
end
end
require 'test_helper'
class Api::V2::WristbandsControllerTest < ActionDispatch::IntegrationTest
setup do
@wristband = wristbands(:one)
end
test 'list_wristband' do
method = :get
url = list_wristband_api_v2_wristbands_url
params = { b_user_id: 3793, search_begin_at: Time.new(2018, 5, 20).to_i, search_end_at: Time.new(2018, 6, 20).to_i }
send_request(method, url, params)
params = { b_user_id: 3793 }
send_request(method, url, params, generate_doc_flag: false)
end
end
......
class ActionDispatch::IntegrationTest
def doc_logger
@doc_logger = Logger.new("#{Rails.root}/doc/api_v2.textile")
@doc_logger.formatter = proc do |_severity, _datetime, _progname, msg|
"#{msg}\n"
end
@doc_logger
end
def send_request(method, url, params, generate_doc_flag: true, code: '20000')
send(method, url, params: params)
assert_success(code)
generate_doc(method, params) if generate_doc_flag
end
def assert_success(code)
assert_equal code, body['status_code']
end
def body
JSON.parse(@response.body) || {}
end
# NOTE 这一步是关键
def generate_doc(method, params)
# 非生产环境下引入pry-rails gem
method_location = ::MethodSource.source_helper(@controller.class.new.method(@controller.action_name).source_location)
# action内的每个#号开头的注释,required optional开头的代码行都会写入文档,你可以写任何东西
detail = method_location.split("\n").map { |x| x[/^\s+(#.*)|(required.*)|(optional.*)/] }.compact.join("\n")
doc_logger.info <<~HTML
h1. #{I18n.t(@controller.action_name, scope: 'action_name', locale: 'zh-CN')}-#{@controller.action_name}
请求: #{method.upcase} #{@request.path}
参数校验:
<pre>
<code class="ruby">
#{detail}
</code>
</pre>
参数:
<pre>
<code class="json">
#{JSON.pretty_generate(params)}
</code>
</pre>
返回值:
<pre>
<code class="json">
#{JSON.pretty_generate(body) if @response.content_type == 'application/json'}
</code>
</pre>
HTML
end
end
namespace :test do
task doc: :environment do
`echo "{{TOC}}\n" > doc/api_v2.textile`
dir = 'test/controllers/api/v2/'
order_controllers = %w[
wristbands_controller_test.rb
users_controller_test.rb
device_binds_controller_test.rb
feedbacks_controller_test.rb
commons_controller_test.rb
]
order_controllers.each do |x|
`rails test #{dir}#{x}`
end
end
end
Rails 的测试顺序只支持:random 和:alpha,修改为:alpha
# rails test // 最好先测试通过后再生成文档
rails test:doc
这是一种写 api 文档的思路,希望大家喜欢。