class OpenApiAnnotator::PathsBuilder

Public Instance Methods

build() click to toggle source
# File lib/open_api_annotator/paths_builder.rb, line 3
def build
  paths = OpenApi::Paths.new
  routes = RoutesFinder.new.find_all
  path_regexp = OpenApiAnnotator.config.path_regexp
  if path_regexp
    routes.select! { |route| route.path.match(path_regexp) }
  end
  routes.group_by(&:path).each do |path_name, routes|
    paths[path_name] = build_path_item(routes)
    puts "Path '#{path_name}' has been created."
  end

  paths
end

Private Instance Methods

build_description(controller_name, action_name) click to toggle source
# File lib/open_api_annotator/paths_builder.rb, line 51
def build_description(controller_name, action_name)
  type = resolve_type(controller_name, action_name)
  return unless type

  case type
  when Array
    name = build_type_name(type.first)
    "Returns an array of #{name}"
  else
    name = build_type_name(type)
    "Returns a #{name}"
  end
end
build_path_item(routes) click to toggle source
# File lib/open_api_annotator/paths_builder.rb, line 20
def build_path_item(routes)
  path_item = OpenApi::PathItem.new
  routes.each do |route|
    media_type = resolve_media_type(route.controller_name, route.action_name)
    description = build_description(route.controller_name, route.action_name)
    next unless media_type
    operation = OpenApi::Operation.new(responses: OpenApi::Responses.new)
    response = OpenApi::Response.new(
      description: description,
      content: {
        "application/json" => media_type,
      }
    )
    operation.responses["200"] = response
    route.parameters.each do |parameter|
      parameter = OpenApi::Parameter.new(
        name: parameter[:name],
        in: :path,
        required: true,
        schema: OpenApi::Schema.new(
          type: :string
        )
      )
      operation.parameters = [] unless operation.parameters
      operation.parameters.push(parameter)
    end
    path_item.operations[route.http_verb.underscore] = operation
  end
  path_item
end
build_type_name(type) click to toggle source
# File lib/open_api_annotator/paths_builder.rb, line 65
def build_type_name(type)
  type = convert_primitive_class_to_data_type(type)
  case type
  when OpenApi::DataType
    "#{type.name}"
  when Class
    "#{type.name}"
  else
    raise "not supported class #{type.class}"
  end
end
convert_primitive_class_to_data_type(type) click to toggle source
# File lib/open_api_annotator/paths_builder.rb, line 104
def convert_primitive_class_to_data_type(type)
  if type == String
    OpenApi::DataType.new(:string, :string, :string)
  elsif type == Integer
    OpenApi::DataType.new(:integer, :integer, :int32)
  elsif type == Float
    OpenApi::DataType.new(:float, :number, :float)
  else
    type
  end
end
resolve_media_type(controller_name, action_name) click to toggle source
# File lib/open_api_annotator/paths_builder.rb, line 77
def resolve_media_type(controller_name, action_name)
  type = resolve_type(controller_name, action_name)
  return unless type

  case type
  when Array
    schema_of_array = resolve_media_type_schema(type.first)
    schema = OpenApi::Schema.new(type: "array", items: schema_of_array)
    OpenApi::MediaType.new(schema: schema)
  else
    schema = resolve_media_type_schema(type)
    OpenApi::MediaType.new(schema: schema)
  end
end
resolve_media_type_schema(type) click to toggle source
# File lib/open_api_annotator/paths_builder.rb, line 92
def resolve_media_type_schema(type)
  type = convert_primitive_class_to_data_type(type)
  case type
  when OpenApi::DataType
    OpenApi::Schema.new(type: type.name, format: type.format)
  when Class
    OpenApi::Reference.new(ref: "#/components/schemas/#{type.name}")
  else
    raise "not supported class #{type.class}"
  end
end
resolve_type(controller_name, action_name) click to toggle source
# File lib/open_api_annotator/paths_builder.rb, line 116
def resolve_type(controller_name, action_name)
  controller_class_name = "#{controller_name}_controller".classify
  begin
    controller_class = controller_class_name.constantize
  rescue NameError => e
    return
  end
  return unless controller_class < OpenApiAnnotator.config.application_controller_class

  controller_class.endpoint_hash[action_name.to_sym]&.type
end