lib/auto_gen_doc.rb
# frozen_string_literal: true
require 'open_api/router'
module AutoGenDoc
def self.included(base)
base.extend ClassMethods
end
module ClassMethods
def inherited(subclass)
super
subclass.class_eval do
break unless name.match?(/Controller|Doc/)
route_base name.sub('Doc', '').underscore.gsub('::', '/') if name.match?(/Doc/)
open_api_dry
end
end
private
def open_api_dry
route_base = try(:controller_path) || oas[:route_base]
::OpenApi::Router.get_actions_by_route_base(route_base)&.each do |action|
api_dry action do
# Common :index parameters
if action == 'index'
query :created_from, DateTime, desc: 'YY-MM-DD (HH:MM:SS, optional)', as: :start
query :created_to, DateTime, desc: 'YY-MM-DD (HH:MM:SS, optional)', as: :end
query :search_value, String
query :page, Integer, range: { ge: 1 }, default: 1
query :rows, Integer, desc: 'per page, number of result', range: { ge: 1 }, default: 10
end
# Common :show parameters
if action == 'show'
path! :id, Integer
end
# Common :destroy parameters
if action == 'destroy'
path! :id, Integer
end
# Common :update parameters
if action == 'update'
path! :id, Integer
end
### Common responses
# OAS require at least one response on each api.
# default_response 'default response', :json
# model = Object.const_get(action_path.split('#').first.split('/').last[0..-2].camelize) rescue nil
# type = action.in?(%w[ index show create ]) ? load_schema(model) : String
# TODO: automatically gets `to_builder` format
response 0, 'success', :json, data: {
result: {
code: { type: Integer, default: 0 },
message: { type: String, default: 'success' }
}
}
# automatically generate responses based on the agreed error class.
# api/v1/examples#index => Error::Examples
error_class_name = 'Error::' + action_path.split('#').first.split('/').last.camelize
error_class = Object.const_get(error_class_name) rescue Error::Api
# TODO
cur_api_errs = (error_class.defs&.values_at(action.to_sym, :private, :public) || [ ]).flatten.compact.uniq
cur_api_errs.each do |error|
info = error_class.send(error).info
response info[:code], info[:msg]
end
end
end
end
end
end