Class: Apipie::SwaggerGenerator
- Inherits:
-
Object
- Object
- Apipie::SwaggerGenerator
- Defined in:
- lib/apipie/swagger_generator.rb
Overview
Instance Attribute Summary collapse
-
#computed_interface_id ⇒ Object
readonly
Returns the value of attribute computed_interface_id.
Instance Method Summary collapse
- #add_headers_from_hash(swagger_params_array, headers) ⇒ Object
- #add_missing_params(method, path) ⇒ Object
- #add_params_from_hash(swagger_params_array, param_defs, prefix = nil, default_value_for_in = nil) ⇒ Object
- #add_resource_description(resource_name, resource) ⇒ Object
- #add_resource_methods(resource_name, resource_defs) ⇒ Object
-
#add_resources(resources) ⇒ Object
————————————————————————– Engine interface methods ————————————————————————–.
-
#add_ruby_method(paths, ruby_method) ⇒ Object
————————————————————————– Create swagger definitions for a ruby method ————————————————————————–.
-
#body_allowed_for_current_method ⇒ Object
————————————————————————– swagger “Params” block generation ————————————————————————–.
- #gen_referenced_block_from_params_array(name, params_array, allow_nulls = false) ⇒ Object
- #generate_from_resources(version, resources, method_name, lang, clear_warnings = false) ⇒ Object
-
#include_op_id_in_computed_interface_id(op_id) ⇒ Object
the @computed_interface_id is a number that is uniquely derived from the list of operations added to the swagger definition (in an order-dependent way).
- #include_warning_tags? ⇒ Boolean
- #info(msg) ⇒ Object
-
#init_swagger_vars(version, lang, clear_warnings = false) ⇒ Object
————————————————————————– Initialization ————————————————————————–.
-
#initialize(apipie) ⇒ SwaggerGenerator
constructor
A new instance of SwaggerGenerator.
-
#json_schema_for_method_response(method, return_code, allow_nulls) ⇒ Object
————————————————————————– Responses ————————————————————————–.
- #json_schema_for_self_describing_class(cls, allow_nulls) ⇒ Object
-
#param_names_from_path(path) ⇒ Object
————————————————————————– Auto-insertion of parameters that are implicitly defined in the path ————————————————————————–.
- #params_in_body? ⇒ Boolean
- #params_in_body_use_reference? ⇒ Boolean
-
#ref_to(name) ⇒ Object
————————————————————————– JSON schema and referenced-object generation ————————————————————————–.
- #remove_colons(str) ⇒ Object
- #response_schema(response, allow_nulls = false) ⇒ Object
- #responses_use_reference? ⇒ Boolean
-
#ruby_name_for_method(method) ⇒ Object
————————————————————————– Logging, debugging and regression-testing utilities ————————————————————————–.
- #swagger_op_id_for_method(method) ⇒ Object
- #swagger_param_type(param_desc) ⇒ Object
- #swagger_params_array_for_method(method, path) ⇒ Object
-
#swagger_path(str) ⇒ Object
————————————————————————– Utilities for conversion of ruby syntax to swagger syntax ————————————————————————–.
- #swagger_responses_hash_for_method(method) ⇒ Object
-
#tag_name_for_resource(resource) ⇒ Object
————————————————————————– Create a tag description for a described resource ————————————————————————–.
- #warn(warning_code, message_attributes = {}) ⇒ Object
- #warn_added_missing_slash(path) ⇒ Object
- #warn_inferring_boolean(name) ⇒ Object
- #warn_missing_method_summary ⇒ Object
- #warn_no_return_codes_specified ⇒ Object
- #warn_optional_param_in_path(param_name) ⇒ Object
- #warn_optional_without_default_value(param_name) ⇒ Object
- #warn_param_ignored_in_form_data(param_name) ⇒ Object
- #warn_path_parameter_not_described(name, path) ⇒ Object
Constructor Details
#initialize(apipie) ⇒ SwaggerGenerator
Returns a new instance of SwaggerGenerator.
14 15 16 17 |
# File 'lib/apipie/swagger_generator.rb', line 14 def initialize(apipie) @apipie = apipie @issued_warnings = [] end |
Instance Attribute Details
#computed_interface_id ⇒ Object (readonly)
Returns the value of attribute computed_interface_id.
12 13 14 |
# File 'lib/apipie/swagger_generator.rb', line 12 def computed_interface_id @computed_interface_id end |
Instance Method Details
#add_headers_from_hash(swagger_params_array, headers) ⇒ Object
518 519 520 521 522 523 524 525 526 527 528 529 530 531 |
# File 'lib/apipie/swagger_generator.rb', line 518 def add_headers_from_hash(swagger_params_array, headers) swagger_headers = headers.map do |header| header_hash = { name: header[:name], in: 'header', required: header[:options][:required], description: header[:description], type: header[:options][:type] || 'string' } header_hash[:default] = header[:options][:default] if header[:options][:default] header_hash end swagger_params_array.push(*swagger_headers) end |
#add_missing_params(method, path) ⇒ Object
424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 |
# File 'lib/apipie/swagger_generator.rb', line 424 def add_missing_params(method, path) param_names_from_method = method.params.map {|name, desc| name} missing = param_names_from_path(path) - param_names_from_method result = method.params missing.each do |name| warn_path_parameter_not_described(name, path) result[name.to_sym] = Apipie::Generator::Swagger::ParamDescription. create_for_missing_param(method, name) end result end |
#add_params_from_hash(swagger_params_array, param_defs, prefix = nil, default_value_for_in = nil) ⇒ Object
534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 |
# File 'lib/apipie/swagger_generator.rb', line 534 def add_params_from_hash(swagger_params_array, param_defs, prefix=nil, default_value_for_in=nil) param_defs.each do |name, desc| if !prefix.nil? name = "#{prefix}[#{name}]" end if swagger_param_type(desc) == "object" if desc.validator.params_ordered params_hash = Hash[desc.validator.params_ordered.map {|desc| [desc.name, desc]}] add_params_from_hash(swagger_params_array, params_hash, name) else warn_param_ignored_in_form_data(desc.name) end else param_entry = Apipie::Generator::Swagger::ParamDescription::Builder. new(desc, in_schema: false, controller_method: @current_method). with_description(language: @current_lang). with_name(prefix: prefix). with_type(with_null: @allow_null). with_in( http_method: @current_http_method, default_in_value: default_value_for_in ).to_swagger if param_entry[:required] swagger_params_array.unshift(param_entry) else swagger_params_array.push(param_entry) end end end end |
#add_resource_description(resource_name, resource) ⇒ Object
219 220 221 222 223 224 225 226 |
# File 'lib/apipie/swagger_generator.rb', line 219 def add_resource_description(resource_name, resource) if resource._full_description @tags << { name: tag_name_for_resource(resource), description: Apipie.app.translate(resource._full_description, @current_lang) } end end |
#add_resource_methods(resource_name, resource_defs) ⇒ Object
114 115 116 117 118 |
# File 'lib/apipie/swagger_generator.rb', line 114 def add_resource_methods(resource_name, resource_defs) resource_defs._methods.each do |apipie_method_name, apipie_method_defs| add_ruby_method(@paths, apipie_method_defs) end end |
#add_resources(resources) ⇒ Object
Engine interface methods
107 108 109 110 111 112 |
# File 'lib/apipie/swagger_generator.rb', line 107 def add_resources(resources) resources.each do |resource_name, resource_defs| add_resource_description(resource_name, resource_defs) add_resource_methods(resource_name, resource_defs) end end |
#add_ruby_method(paths, ruby_method) ⇒ Object
Create swagger definitions for a ruby method
232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 |
# File 'lib/apipie/swagger_generator.rb', line 232 def add_ruby_method(paths, ruby_method) if @only_method return unless ruby_method.method == @only_method else return if !ruby_method.show end for api in ruby_method.apis do # controller: ruby_method.resource.controller.name, path = swagger_path(api.path) paths[path] ||= {} methods = paths[path] @current_method = ruby_method @warnings_issued = false responses = swagger_responses_hash_for_method(ruby_method) if = @warnings_issued ? ['warnings issued'] : [] else = [] end op_id = Apipie::Generator::Swagger::OperationId.from(api).to_s include_op_id_in_computed_interface_id(op_id) method_key = api.http_method.downcase @current_http_method = method_key methods[method_key] = { tags: [tag_name_for_resource(ruby_method.resource)] + + ruby_method.tag_list., consumes: params_in_body? ? ['application/json'] : ['application/x-www-form-urlencoded', 'multipart/form-data'], operationId: op_id, summary: Apipie.app.translate(api.short_description, @current_lang), parameters: swagger_params_array_for_method(ruby_method, api.path), responses: responses, description: Apipie.app.translate(ruby_method.full_description, @current_lang) } if methods[method_key][:summary].nil? methods[method_key].delete(:summary) warn_missing_method_summary end end end |
#body_allowed_for_current_method ⇒ Object
swagger “Params” block generation
470 471 472 |
# File 'lib/apipie/swagger_generator.rb', line 470 def body_allowed_for_current_method !(['get', 'head'].include?(@current_http_method)) end |
#gen_referenced_block_from_params_array(name, params_array, allow_nulls = false) ⇒ Object
448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 |
# File 'lib/apipie/swagger_generator.rb', line 448 def gen_referenced_block_from_params_array(name, params_array, allow_nulls=false) return ref_to(:name) if @definitions.key(:name) schema_obj = Apipie::Generator::Swagger::ParamDescription::Composite.new( params_array, Apipie::Generator::Swagger::Context.new( allow_null: allow_nulls, http_method: @current_http_method, controller_method: @current_method ) ).to_swagger return nil if schema_obj.nil? @definitions[name.to_sym] = schema_obj ref_to(name.to_sym) end |
#generate_from_resources(version, resources, method_name, lang, clear_warnings = false) ⇒ Object
36 37 38 39 40 41 42 43 44 |
# File 'lib/apipie/swagger_generator.rb', line 36 def generate_from_resources(version, resources, method_name, lang, clear_warnings=false) init_swagger_vars(version, lang, clear_warnings) @only_method = method_name add_resources(resources) @swagger[:info]["x-computed-id"] = @computed_interface_id if Apipie.configuration.swagger_generate_x_computed_id_field? return @swagger end |
#include_op_id_in_computed_interface_id(op_id) ⇒ Object
the @computed_interface_id is a number that is uniquely derived from the list of operations added to the swagger definition (in an order-dependent way). it can be used for regression testing, allowing some differentiation between changes that result from changes to the input and those that result from changes to the generation algorithms. note that at the moment, this only takes operation ids into account, and ignores parameter definitions, so it’s only partially useful.
206 207 208 |
# File 'lib/apipie/swagger_generator.rb', line 206 def include_op_id_in_computed_interface_id(op_id) @computed_interface_id = Zlib::crc32("#{@computed_interface_id} #{op_id}") if Apipie.configuration.swagger_generate_x_computed_id_field? end |
#include_warning_tags? ⇒ Boolean
31 32 33 |
# File 'lib/apipie/swagger_generator.rb', line 31 def Apipie.configuration. end |
#info(msg) ⇒ Object
194 195 196 |
# File 'lib/apipie/swagger_generator.rb', line 194 def info(msg) print "--- INFO: [#{ruby_name_for_method(@current_method)}] -- #{msg}\n" end |
#init_swagger_vars(version, lang, clear_warnings = false) ⇒ Object
Initialization
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 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/apipie/swagger_generator.rb', line 51 def init_swagger_vars(version, lang, clear_warnings=false) # docs = { # :name => Apipie.configuration.app_name, # :info => Apipie.app_info(version, lang), # :copyright => Apipie.configuration.copyright, # :doc_url => Apipie.full_url(url_args), # :api_url => Apipie.api_base_url(version), # :resources => _resources # } @swagger = { swagger: '2.0', info: { title: "#{Apipie.configuration.app_name}", description: "#{Apipie.app_info(version, lang)}#{Apipie.configuration.copyright}", version: "#{version}", "x-copyright" => Apipie.configuration.copyright, }, basePath: Apipie.api_base_url(version), consumes: [], paths: {}, definitions: {}, schemes: Apipie.configuration.swagger_schemes, tags: [], securityDefinitions: Apipie.configuration.swagger_security_definitions, security: Apipie.configuration.swagger_global_security } if Apipie.configuration.swagger_api_host @swagger[:host] = Apipie.configuration.swagger_api_host end if params_in_body? @swagger[:consumes] = ['application/json'] @swagger[:info][:title] += " (params in:body)" else @swagger[:consumes] = ['application/x-www-form-urlencoded', 'multipart/form-data'] @swagger[:info][:title] += " (params in:formData)" end @paths = @swagger[:paths] @definitions = @swagger[:definitions] @tags = @swagger[:tags] @issued_warnings = [] if clear_warnings || @issued_warnings.nil? @computed_interface_id = 0 @current_lang = lang end |
#json_schema_for_method_response(method, return_code, allow_nulls) ⇒ Object
Responses
326 327 328 329 330 331 332 333 334 335 |
# File 'lib/apipie/swagger_generator.rb', line 326 def json_schema_for_method_response(method, return_code, allow_nulls) @definitions = {} for response in method.returns next unless response.code.to_s == return_code.to_s schema = response_schema(response, allow_nulls) schema[:definitions] = @definitions if @definitions != {} return schema end nil end |
#json_schema_for_self_describing_class(cls, allow_nulls) ⇒ Object
337 338 339 340 |
# File 'lib/apipie/swagger_generator.rb', line 337 def json_schema_for_self_describing_class(cls, allow_nulls) adapter = ResponseDescriptionAdapter.from_self_describing_class(cls) response_schema(adapter, allow_nulls) end |
#param_names_from_path(path) ⇒ Object
Auto-insertion of parameters that are implicitly defined in the path
418 419 420 421 422 |
# File 'lib/apipie/swagger_generator.rb', line 418 def param_names_from_path(path) path.scan(/:(\w+)/).map do |ar| ar[0].to_sym end end |
#params_in_body? ⇒ Boolean
19 20 21 |
# File 'lib/apipie/swagger_generator.rb', line 19 def params_in_body? Apipie.configuration.swagger_content_type_input == :json end |
#params_in_body_use_reference? ⇒ Boolean
23 24 25 |
# File 'lib/apipie/swagger_generator.rb', line 23 def params_in_body_use_reference? Apipie.configuration.swagger_json_input_uses_refs end |
#ref_to(name) ⇒ Object
JSON schema and referenced-object generation
444 445 446 |
# File 'lib/apipie/swagger_generator.rb', line 444 def ref_to(name) "#/definitions/#{name}" end |
#remove_colons(str) ⇒ Object
296 297 298 |
# File 'lib/apipie/swagger_generator.rb', line 296 def remove_colons(str) str.gsub(":", "_") end |
#response_schema(response, allow_nulls = false) ⇒ Object
342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 |
# File 'lib/apipie/swagger_generator.rb', line 342 def response_schema(response, allow_nulls=false) begin # no need to warn about "missing default value for optional param" when processing response definitions prev_value = @disable_default_value_warning @disable_default_value_warning = true if responses_use_reference? && response.typename schema = { "$ref" => gen_referenced_block_from_params_array( response.typename, response.params_ordered, allow_nulls ) } else schema = Apipie::Generator::Swagger::ParamDescription::Composite.new( response.params_ordered, Apipie::Generator::Swagger::Context.new( allow_null: allow_nulls, http_method: @current_http_method, controller_method: @current_method ) ).to_swagger end ensure @disable_default_value_warning = prev_value end if response.is_array? && schema schema = { type: allow_nulls ? ["array","null"] : "array", items: schema } end if response.allow_additional_properties schema[:additionalProperties] = true end schema end |
#responses_use_reference? ⇒ Boolean
27 28 29 |
# File 'lib/apipie/swagger_generator.rb', line 27 def responses_use_reference? Apipie.configuration.swagger_responses_use_refs? end |
#ruby_name_for_method(method) ⇒ Object
Logging, debugging and regression-testing utilities
125 126 127 128 |
# File 'lib/apipie/swagger_generator.rb', line 125 def ruby_name_for_method(method) return "<no method>" if method.nil? method.resource.controller.name + "#" + method.method end |
#swagger_op_id_for_method(method) ⇒ Object
300 301 302 |
# File 'lib/apipie/swagger_generator.rb', line 300 def swagger_op_id_for_method(method) remove_colons method.resource.controller.name + "::" + method.method end |
#swagger_param_type(param_desc) ⇒ Object
304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 |
# File 'lib/apipie/swagger_generator.rb', line 304 def swagger_param_type(param_desc) if param_desc.blank? raise ArgumentError, 'param_desc is required' end method_id = ruby_name_for_method(@current_method) warning = Apipie::Generator::Swagger::Warning.for_code( Apipie::Generator::Swagger::Warning::INFERRING_BOOLEAN_CODE, method_id, { parameter: param_desc.name } ) Apipie::Generator::Swagger::TypeExtractor.new(param_desc.validator). extract_with_warnings({ boolean: warning }) end |
#swagger_params_array_for_method(method, path) ⇒ Object
474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 |
# File 'lib/apipie/swagger_generator.rb', line 474 def swagger_params_array_for_method(method, path) swagger_result = [] all_params_hash = add_missing_params(method, path) body_param_defs_array = all_params_hash.map {|k, v| v if !param_names_from_path(path).include?(k)}.select{|v| !v.nil?} body_param_defs_hash = all_params_hash.select {|k, v| v if !param_names_from_path(path).include?(k)} path_param_defs_hash = all_params_hash.select {|k, v| v if param_names_from_path(path).include?(k)} path_param_defs_hash.each{|name,desc| desc.required = true} add_params_from_hash(swagger_result, path_param_defs_hash, nil, "path") if params_in_body? && body_allowed_for_current_method if params_in_body_use_reference? swagger_schema_for_body = {"$ref" => gen_referenced_block_from_params_array("#{swagger_op_id_for_method(method)}_input", body_param_defs_array)} else swagger_schema_for_body = Apipie::Generator::Swagger::ParamDescription::Composite.new( body_param_defs_array, Apipie::Generator::Swagger::Context.new( allow_null: false, http_method: @current_http_method, controller_method: @current_method ) ).to_swagger end swagger_body_param = { name: 'body', in: 'body', schema: swagger_schema_for_body } swagger_result.push(swagger_body_param) if !swagger_schema_for_body.nil? else add_params_from_hash(swagger_result, body_param_defs_hash) end add_headers_from_hash(swagger_result, method.headers) if method.headers.present? swagger_result end |
#swagger_path(str) ⇒ Object
Utilities for conversion of ruby syntax to swagger syntax
285 286 287 288 289 290 291 292 293 294 |
# File 'lib/apipie/swagger_generator.rb', line 285 def swagger_path(str) str = str.gsub(/:(\w+)/, '{\1}') str = str.gsub(/\/$/, '') if str[0] != '/' warn_added_missing_slash(str) str = '/' + str end str end |
#swagger_responses_hash_for_method(method) ⇒ Object
385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 |
# File 'lib/apipie/swagger_generator.rb', line 385 def swagger_responses_hash_for_method(method) result = {} for error in method.errors error_block = {description: Apipie.app.translate(error.description, @current_lang)} result[error.code] = error_block end for response in method.returns swagger_response_block = { description: Apipie.app.translate(response.description, @current_lang) } schema = response_schema(response) swagger_response_block[:schema] = schema if schema result[response.code] = swagger_response_block end if result.length == 0 warn_no_return_codes_specified result[200] = {description: 'ok'} end result end |
#tag_name_for_resource(resource) ⇒ Object
Create a tag description for a described resource
214 215 216 217 |
# File 'lib/apipie/swagger_generator.rb', line 214 def tag_name_for_resource(resource) # resource.controller resource._id end |
#warn(warning_code, message_attributes = {}) ⇒ Object
182 183 184 185 186 187 188 189 190 191 192 |
# File 'lib/apipie/swagger_generator.rb', line 182 def warn(warning_code, = {}) Apipie::Generator::Swagger::Warning.for_code( warning_code, ruby_name_for_method(@current_method), ).warn_through_writer @warnings_issued = Apipie::Generator::Swagger::WarningWriter. instance. issued_warnings? end |
#warn_added_missing_slash(path) ⇒ Object
134 135 136 137 138 139 |
# File 'lib/apipie/swagger_generator.rb', line 134 def warn_added_missing_slash(path) warn( Apipie::Generator::Swagger::Warning::ADDED_MISSING_SLASH_CODE, { path: path } ) end |
#warn_inferring_boolean(name) ⇒ Object
173 174 175 176 177 178 |
# File 'lib/apipie/swagger_generator.rb', line 173 def warn_inferring_boolean(name) warn( Apipie::Generator::Swagger::Warning::INFERRING_BOOLEAN_CODE, { name: name } ) end |
#warn_missing_method_summary ⇒ Object
130 131 132 |
# File 'lib/apipie/swagger_generator.rb', line 130 def warn_missing_method_summary warn(Apipie::Generator::Swagger::Warning::MISSING_METHOD_SUMMARY_CODE) end |
#warn_no_return_codes_specified ⇒ Object
141 142 143 |
# File 'lib/apipie/swagger_generator.rb', line 141 def warn_no_return_codes_specified warn(Apipie::Generator::Swagger::Warning::NO_RETURN_CODES_SPECIFIED_CODE) end |
#warn_optional_param_in_path(param_name) ⇒ Object
145 146 147 148 149 150 |
# File 'lib/apipie/swagger_generator.rb', line 145 def warn_optional_param_in_path(param_name) warn( Apipie::Generator::Swagger::Warning::OPTIONAL_PARAM_IN_PATH_CODE, { parameter: param_name } ) end |
#warn_optional_without_default_value(param_name) ⇒ Object
152 153 154 155 156 157 |
# File 'lib/apipie/swagger_generator.rb', line 152 def warn_optional_without_default_value(param_name) warn( Apipie::Generator::Swagger::Warning::OPTIONAL_WITHOUT_DEFAULT_VALUE_CODE, { parameter: param_name } ) end |
#warn_param_ignored_in_form_data(param_name) ⇒ Object
159 160 161 162 163 164 |
# File 'lib/apipie/swagger_generator.rb', line 159 def warn_param_ignored_in_form_data(param_name) warn( Apipie::Generator::Swagger::Warning::PARAM_IGNORED_IN_FORM_DATA_CODE, { parameter: param_name } ) end |
#warn_path_parameter_not_described(name, path) ⇒ Object
166 167 168 169 170 171 |
# File 'lib/apipie/swagger_generator.rb', line 166 def warn_path_parameter_not_described(name, path) warn( Apipie::Generator::Swagger::Warning::PATH_PARAM_NOT_DESCRIBED_CODE, { name: name, path: path } ) end |