Class: SwaggerYard::Operation

Inherits:
Object
  • Object
show all
Defined in:
lib/swagger_yard/operation.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(api) ⇒ Operation

Returns a new instance of Operation.



32
33
34
35
36
37
38
39
# File 'lib/swagger_yard/operation.rb', line 32

def initialize(api)
  @api            = api
  @summary        = nil
  @description    = ""
  @parameters     = []
  @model_names    = []
  @error_messages = []
end

Instance Attribute Details

#descriptionObject

Returns the value of attribute description.



3
4
5
# File 'lib/swagger_yard/operation.rb', line 3

def description
  @description
end

#error_messagesObject (readonly)

Returns the value of attribute error_messages.



5
6
7
# File 'lib/swagger_yard/operation.rb', line 5

def error_messages
  @error_messages
end

#http_methodObject (readonly)

Returns the value of attribute http_method.



5
6
7
# File 'lib/swagger_yard/operation.rb', line 5

def http_method
  @http_method
end

#model_namesObject (readonly)

Returns the value of attribute model_names.



6
7
8
# File 'lib/swagger_yard/operation.rb', line 6

def model_names
  @model_names
end

#parametersObject (readonly)

Returns the value of attribute parameters.



6
7
8
# File 'lib/swagger_yard/operation.rb', line 6

def parameters
  @parameters
end

#pathObject (readonly)

Returns the value of attribute path.



5
6
7
# File 'lib/swagger_yard/operation.rb', line 5

def path
  @path
end

#response_descObject (readonly)

Returns the value of attribute response_desc.



5
6
7
# File 'lib/swagger_yard/operation.rb', line 5

def response_desc
  @response_desc
end

#response_typeObject (readonly)

Returns the value of attribute response_type.



5
6
7
# File 'lib/swagger_yard/operation.rb', line 5

def response_type
  @response_type
end

#ruby_methodObject

Returns the value of attribute ruby_method.



3
4
5
# File 'lib/swagger_yard/operation.rb', line 3

def ruby_method
  @ruby_method
end

#summaryObject



41
42
43
# File 'lib/swagger_yard/operation.rb', line 41

def summary
  @summary || description.split("\n\n").first || ""
end

Class Method Details

.from_yard_object(yard_object, api) ⇒ Object

TODO: extract to operation builder?



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/swagger_yard/operation.rb', line 9

def self.from_yard_object(yard_object, api)
  new(api).tap do |operation|
    operation.ruby_method = yard_object.name(false)
    operation.description = yard_object.docstring
    yard_object.tags.each do |tag|
      case tag.tag_name
      when "path"
        operation.add_path_params_and_method(tag)
      when "parameter"
        operation.add_parameter(tag)
      when "response_type"
        operation.add_response_type(Type.from_type_list(tag.types), tag.text)
      when "error_message"
        operation.add_error_message(tag)
      when "summary"
        operation.summary = tag.text
      end
    end

    operation.sort_parameters
  end
end

Instance Method Details

#add_error_message(tag) ⇒ Object



130
131
132
133
134
135
136
# File 'lib/swagger_yard/operation.rb', line 130

def add_error_message(tag)
  @error_messages << {
    "code" => Integer(tag.name),
    "message" => tag.text,
    "responseModel" => Array(tag.types).first
  }.reject {|_,v| v.nil?}
end

#add_or_update_parameter(parameter) ⇒ Object



110
111
112
113
114
115
116
117
118
119
# File 'lib/swagger_yard/operation.rb', line 110

def add_or_update_parameter(parameter)
  if existing = @parameters.detect {|param| param.name == parameter.name }
    existing.description    = parameter.description unless parameter.from_path?
    existing.param_type     = parameter.param_type if parameter.from_path?
    existing.required     ||= parameter.required
    existing.allow_multiple = parameter.allow_multiple
  else
    @parameters << parameter
  end
end

#add_parameter(tag) ⇒ Object

Example: [Array] status Filter by status. (e.g. status[]=1&status=2&status[]=3) Example: [Array] status(required) Filter by status. (e.g. status[]=1&status=2&status[]=3) Example: [Array] status(required, body) Filter by status. (e.g. status[]=1&status=2&status[]=3) Example: [Integer] media ID of the desired media type.



106
107
108
# File 'lib/swagger_yard/operation.rb', line 106

def add_parameter(tag)
  add_or_update_parameter Parameter.from_yard_tag(tag, self)
end

#add_path_params_and_method(tag) ⇒ Object

Example: [GET] /api/v2/ownerships Example: [PUT] /api/v1/accounts/account_id



92
93
94
95
96
97
98
99
# File 'lib/swagger_yard/operation.rb', line 92

def add_path_params_and_method(tag)
  @path = tag.text
  @http_method = tag.types.first

  parse_path_params(tag.text).each do |name|
    add_or_update_parameter Parameter.from_path_param(name)
  end
end

#add_response_type(type, desc) ⇒ Object

Example:



124
125
126
127
128
# File 'lib/swagger_yard/operation.rb', line 124

def add_response_type(type, desc)
  model_names << type.model_name
  @response_type = type
  @response_desc = desc
end

#sort_parametersObject



138
139
140
# File 'lib/swagger_yard/operation.rb', line 138

def sort_parameters
  @parameters.sort_by! {|p| p.name}
end

#to_hObject



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/swagger_yard/operation.rb', line 45

def to_h
  params      = parameters.map(&:to_h)
  responses   = { "default" => { "description" => response_desc || summary } }

  if response_type
    responses["default"]["schema"] = response_type.to_h
  end

  unless error_messages.empty?
    error_messages.each do |err|
      responses[err["code"].to_s] = {}.tap do |h|
        h["description"] = err["message"]
        h["schema"] = Type.from_type_list(Array(err["responseModel"])).to_h if err["responseModel"]
      end
    end
  end

  api_decl = @api.api_declaration

  {
    "tags"        => [api_decl.resource].compact,
    "operationId" => "#{api_decl.resource}-#{ruby_method}",
    "parameters"  => params,
    "responses"   => responses,
  }.tap do |h|
    h["description"] = description unless description.empty?
    h["summary"]     = summary unless summary.empty?

    authorizations = api_decl.authorizations
    unless authorizations.empty?
      h["security"] = authorizations.map {|k,v| { k => v} }
    end

    # Rails controller/action: if constantize/controller_path methods are
    # unavailable or constant is not defined, catch exception and skip these
    # attributes.
    begin
      h["x-controller"] = api_decl.class_name.constantize.controller_path.to_s
      h["x-action"]     = ruby_method.to_s
    rescue NameError, NoMethodError
    end
  end
end