class Swagui::YAMLDocHandler

Public Class Methods

new(app) click to toggle source
# File lib/swagui/yaml_doc_handler.rb, line 6
def initialize(app)
  @app = app
  api_docs_content = @app.call("REQUEST_METHOD"=>"GET", "PATH_INFO"=>"/api-docs.yml")
  v = ''; api_docs_content[2].each {|x| v = v +  x}
  @api_json_template = YAML.load(v)['template'] # used to store the template settings that applies to all apis
end

Public Instance Methods

call(env) click to toggle source
# File lib/swagui/yaml_doc_handler.rb, line 13
def call(env)
  env['HTTP_IF_MODIFIED_SINCE'] = nil # disable Last-Modified caching

  @app.call(env).tap do |response|
    if response[0] == 200
      response[1].merge!("Content-Type"=>"application/json")  # response is always json content

      if yaml_response?(response) # yml response needs to be re=processed.
        body = []
        response[2].each do |f|
          body << f
        end

        json_string = YAML::load(body.join('')).tap do |response_hash|
                        if response[2].path.end_with?('api-docs.yml')
                          process_api_docs_api_listing(response_hash, response[2].path )
                        else
                          process_schemas(response_hash)
                          process_base_path(response_hash, response[2].path, env)
                        end
                      end.to_json

        response[2] = [json_string]

        response[1].merge!("Content-Length"=> json_string.size.to_s)
      end
    end
  end
end

Private Instance Methods

deep_merge!(actual, template) click to toggle source
# File lib/swagui/yaml_doc_handler.rb, line 109
def deep_merge!(actual, template)
  merger = proc { |key, v1, v2|
    if (Hash === v1 && Hash === v2)
      v1.merge!(v2, &merger)
    elsif (Array === v2 && Array === v1)
      v1 = v1 + v2
    elsif (Hash === v2 && Array === v1)
      v1.map {|x| x.merge!(v2, &merger)}
    else
      v1
    end
  }
  actual.merge!(template, &merger)
end
merge_schema!(parent_hash, response_hash, name, response_model = false) click to toggle source
# File lib/swagui/yaml_doc_handler.rb, line 70
def merge_schema!(parent_hash, response_hash, name, response_model = false)
  if schema_file = parent_hash.delete('schema')
    schema_file_path = Swagui.file_full_path(schema_file)
    schema = JsonSchemaParser.parse(schema_file_path, name)
    schema.models.each {|m| (response_hash['models'] ||= {})[m['id']] = m }
    parent_hash.merge!(schema_hash(schema, response_model))
  end
end
process_api_docs_api_listing(response_hash, doc_path) click to toggle source
# File lib/swagui/yaml_doc_handler.rb, line 89
def process_api_docs_api_listing(response_hash, doc_path)
  if response_hash['models'].nil? # requesting the root

    dir_path = File.dirname(doc_path)
    files = Dir["#{File.dirname(doc_path)}/*.yml"].map {|x| x.gsub(dir_path, '').gsub('.yml', '')}
    files.each do |file|
      unless file == '/api-docs'
        (response_hash['apis'] ||= []) << {'path' => "/..#{file}"}
      end
    end
  end
end
process_base_path(response_hash, doc_path, env) click to toggle source
# File lib/swagui/yaml_doc_handler.rb, line 102
def process_base_path(response_hash, doc_path, env)
  if response_hash['basePath'].nil?
    request = Rack::Request.new(env)
    response_hash['basePath'] = (request.base_url + request.script_name)
  end
end
process_schemas(response_hash) click to toggle source
# File lib/swagui/yaml_doc_handler.rb, line 49
def process_schemas(response_hash)

  deep_merge!(response_hash, @api_json_template) if @api_json_template

  (response_hash['apis'] || []).each do |api_hash|
    (api_hash['operations'] || []).each do |operations_hash|
      operation_name = operations_hash['nickname']

      merge_schema!(operations_hash, response_hash, operation_name)

      (operations_hash['parameters'] || []).each do |parameters_hash|
        merge_schema!(parameters_hash, response_hash, "#{operation_name}-#{parameters_hash['name']}")
      end

      (operations_hash['responseMessages'] || []).each do |response_messages_hash|
        merge_schema!(response_messages_hash, response_hash, "#{operation_name}-Response-#{response_messages_hash['code']}", true)
      end
    end
  end
end
schema_hash(schema, response_model = false) click to toggle source
# File lib/swagui/yaml_doc_handler.rb, line 79
def schema_hash(schema, response_model = false)
  if response_model
    {'responseModel' => schema.name}
  elsif schema.array?
    {'type' => 'array', 'items' => { '$ref' => schema.name} }
  else
    {'type' => schema.name}
  end
end
yaml_response?(response) click to toggle source
# File lib/swagui/yaml_doc_handler.rb, line 45
def yaml_response?(response)
  response[2].respond_to?(:path) && response[2].path.end_with?('.yml')
end