Skip to content

swagger v2 tag feature implemented #344

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 15 commits into from
Closed
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,5 @@ swagger_spec1.2/
ToDo.md
.ruby-version
spec/params_entity_spec.rb
vendor/bundle
.bundle/
27 changes: 27 additions & 0 deletions lib/grape-swagger/endpoint.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ def swagger_object(info, target_class, request, options)
authorizations: options[:authorizations],
host: request.env['HTTP_HOST'] || options[:host],
basePath: request.env['SCRIPT_NAME'] || options[:base_path],
tags: tag_name_description(options),
schemes: options[:scheme]
}.delete_if { |_, value| value.blank? }
end
Expand Down Expand Up @@ -132,6 +133,7 @@ def method_object(route, options)
methods[:produces] = produces_object(route, options)

methods[:parameters] = params_object(route)
methods[:tags] = tag_object(route)
methods[:responses] = response_object(route)

if route.route_aws
Expand Down Expand Up @@ -422,5 +424,30 @@ def parse_entity_name(model)
def primitive?(type)
%w(object integer long float double string byte boolean date dateTime).include? type
end

def tag_name_description(options)
target_class = options[:target_class]
namespaces = target_class.combined_namespaces
namespace_routes = target_class.combined_namespace_routes

namespace_routes_array = namespace_routes.keys.map do |local_route|
next if namespace_routes[local_route].map(&:route_hidden).all? { |value| value.respond_to?(:call) ? value.call : value }

original_namespace_name = target_class.combined_namespace_identifiers.key?(local_route) ? target_class.combined_namespace_identifiers[local_route] : local_route
description = namespaces[original_namespace_name] && namespaces[original_namespace_name].options[:desc]
description ||= "Operations about #{original_namespace_name.pluralize}"

{
name: local_route,
description: description
}
end.compact
end

def tag_object(route)
base_array = route.route_path.split('{')[0].split('/').reject(&:empty?)
tag_name = base_array.delete_if { |i| ((i==route.route_prefix.to_s) || (i[/^[vV][0-9]*/])) }
Array(tag_name.first)
end
end
end
13 changes: 13 additions & 0 deletions spec/support/api_swagger_v2_result.rb
Original file line number Diff line number Diff line change
Expand Up @@ -70,15 +70,21 @@ class ApiError < Grape::Entity
"version"=>"v1"
},
"swagger"=>"2.0",
"tags" => [{"name"=>"other_thing", "description"=>"Operations about other_things"}, {"name"=>"thing", "description"=>"Operations about things"}, {"name"=>"thing2", "description"=>"Operations about thing2s"}, {"name"=>"dummy", "description"=>"Operations about dummies"}],
"produces"=>["application/json"],
"host"=>"example.org",
"tags"=>[{"name"=>"other_thing", "description"=>"Operations about other_things"},
{"name"=>"thing", "description"=>"Operations about things"},
{"name"=>"thing2", "description"=>"Operations about thing2s"},
{"name"=>"dummy", "description"=>"Operations about dummies"}],
"schemes"=>["https", "http"],
"paths"=>{
"/v3/other_thing/{elements}"=>{
"get"=>{
"produces"=>["application/json"],
"parameters"=>[
{"in"=>"array", "name"=>"elements", "description"=>"Set of configuration", "type"=>"string", "required"=>true, "allowMultiple"=>true, "items"=>{"type"=>"string"}}],
"tags"=>["other_thing"],
"responses"=>{"200"=>{"description"=>"nested route inside namespace", "schema"=>{"$ref"=>"#/definitions/QueryInput"}}},
"x-amazon-apigateway-auth"=>{"type"=>"none"},
"x-amazon-apigateway-integration"=>{"type"=>"aws", "uri"=>"foo_bar_uri", "httpMethod"=>"get"}}},
Expand All @@ -90,6 +96,7 @@ class ApiError < Grape::Entity
{"in"=>"query", "name"=>"text", "description"=>"Content of something.", "type"=>"string", "required"=>false, "allowMultiple"=>false},
{"in"=>"query", "name"=>"links", "description"=>nil, "type"=>"link", "required"=>false, "allowMultiple"=>true},
{"in"=>"query", "name"=>"others", "description"=>nil, "type"=>"text", "required"=>false, "allowMultiple"=>false}],
"tags"=>["thing"],
"responses"=>{
"200"=>{"description"=>"This gets Things.", "schema"=>{"$ref"=>"#/definitions/Thing"}},
"401"=>{"description"=>"Unauthorized", "schema"=>{"$ref"=>"#/definitions/ApiError"}}}},
Expand All @@ -98,6 +105,7 @@ class ApiError < Grape::Entity
"parameters"=>[
{"in"=>"formData", "name"=>"text", "description"=>"Content of something.", "type"=>"string", "required"=>true, "allowMultiple"=>false},
{"in"=>"body", "name"=>"links", "description"=>nil, "type"=>"Array", "required"=>true, "allowMultiple"=>true}],
"tags"=>["thing"],
"responses"=>{
"201"=>{"description"=>"This creates Thing.", "schema"=>{"$ref"=>"#/definitions/Something"}},
"422"=>{"description"=>"Unprocessible Entity"}}
Expand All @@ -107,6 +115,7 @@ class ApiError < Grape::Entity
"produces"=>["application/json"],
"parameters"=>[
{"in"=>"path", "name"=>"id", "description"=>nil, "type"=>"integer", "required"=>true, "allowMultiple"=>false, "format"=>"int32"}],
"tags"=>["thing"],
"responses"=>{
"200"=>{"description"=>"getting a single thing", "schema"=>{"$ref"=>"#/definitions/Thing"}},
"401"=>{"description"=>"Unauthorized"}}},
Expand All @@ -116,15 +125,18 @@ class ApiError < Grape::Entity
{"in"=>"path", "name"=>"id", "description"=>nil, "type"=>"integer", "required"=>true, "allowMultiple"=>false, "format"=>"int32"},
{"in"=>"formData", "name"=>"text", "description"=>"Content of something.", "type"=>"string", "required"=>false, "allowMultiple"=>false},
{"in"=>"body", "name"=>"links", "description"=>nil, "type"=>"Array", "required"=>false, "allowMultiple"=>true}],
"tags"=>["thing"],
"responses"=>{"200"=>{"description"=>"This updates Thing.", "schema"=>{"$ref"=>"#/definitions/Something"}}}},
"delete"=>{
"produces"=>["application/json"],
"parameters"=>[{"in"=>"path", "name"=>"id", "description"=>nil, "type"=>"integer", "required"=>true, "allowMultiple"=>false, "format"=>"int32"}],
"tags"=>["thing"],
"responses"=>{"200"=>{"description"=>"This deletes Thing.", "schema"=>{"$ref"=>"#/definitions/Something"}}}
}},
"/thing2"=>{
"get"=>{
"produces"=>["application/json"],
"tags"=>["thing2"],
"responses"=>{
"200"=>{"description"=>"get Horses", "schema"=>{"$ref"=>"#/definitions/Something"}},
"401"=>{"description"=>"HorsesOutError", "schema"=>{"$ref"=>"#/definitions/ApiError"}}}
Expand All @@ -133,6 +145,7 @@ class ApiError < Grape::Entity
"delete"=>{
"produces"=>["application/json"],
"parameters"=>[{"in"=>"path", "name"=>"id", "description"=>nil, "type"=>"integer", "required"=>true, "allowMultiple"=>false, "format"=>"int32"}],
"tags"=>["dummy"],
"responses"=>{"200"=>{"description"=>"dummy route."}, "401"=>{"description"=>"Unauthorized"}}
}}},
"definitions"=>{
Expand Down
4 changes: 4 additions & 0 deletions spec/swagger_v2/api_swagger_v2_response_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,13 @@ def app
"swagger"=>"2.0",
"produces"=>["application/json"],
"host"=>"example.org",
"tags" => [{"name"=>"params_response", "description"=>"Operations about params_responses"}, {"name"=>"entity_response", "description"=>"Operations about entity_responses"}],
"schemes"=>["https", "http"],
"paths"=>{
"/entity_response"=>{
"get"=>{
"produces"=>["application/json"],
"tags"=>["entity_response"],
"responses"=>{
"200"=>{"description"=>"This returns something", "schema"=>{"$ref"=>"#/definitions/UseResponse"}},
"400"=>{"description"=>"NotFound", "schema"=>{"$ref"=>"#/definitions/ApiError"}}}}}},
Expand Down Expand Up @@ -85,6 +87,7 @@ def app
"swagger"=>"2.0",
"produces"=>["application/json"],
"host"=>"example.org",
"tags" => [{"name"=>"params_response", "description"=>"Operations about params_responses"}, {"name"=>"entity_response", "description"=>"Operations about entity_responses"}],
"schemes"=>["https", "http"],
"paths"=>{
"/params_response"=>{
Expand All @@ -93,6 +96,7 @@ def app
"parameters"=>[
{"in"=>"formData", "name"=>"description", "description"=>nil, "type"=>"string", "required"=>false, "allowMultiple"=>false},
{"in"=>"formData", "name"=>"$responses", "description"=>nil, "type"=>"string", "required"=>false, "allowMultiple"=>true}],
"tags"=>["params_response"],
"responses"=>{
"201"=>{"description"=>"This returns something", "schema"=>{"$ref"=>"#/definitions/ParamsResponse"}},
"400"=>{"description"=>"NotFound", "schema"=>{"$ref"=>"#/definitions/ApiError"}}}
Expand Down
4 changes: 4 additions & 0 deletions spec/swagger_v2/default_api_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,13 @@ def app
"swagger"=>"2.0",
"produces"=>["application/json"],
"host"=>"example.org",
"tags" => [{"name"=>"something", "description"=>"Operations about somethings"}],
"schemes" => ["https", "http"],
"paths"=>{
"/something"=>{
"get"=>{
"produces"=>["application/json"],
"tags"=>["something"],
"responses"=>{"200"=>{"description"=>"This gets something."}}}}}}
)
end
Expand Down Expand Up @@ -67,11 +69,13 @@ def app
"swagger"=>"2.0",
"produces"=>["application/json"],
"host"=>"example.org",
"tags" => [{"name"=>"something", "description"=>"Operations about somethings"}],
"schemes" => ["https", "http"],
"paths"=>{
"/something"=>{
"get"=>{
"produces"=>["application/json"],
"tags"=>["something"],
"responses"=>{"200"=>{"description"=>"This gets something."}}}}}
})
end
Expand Down
11 changes: 7 additions & 4 deletions spec/swagger_v2/hide_api_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,11 @@ def app
"swagger"=>"2.0",
"produces"=>["application/xml", "application/json", "application/octet-stream", "text/plain"],
"host"=>"example.org",
"tags" => [{"name"=>"simple", "description"=>"Operations about simples"}, {"name"=>"lazy", "description"=>"Operations about lazies"}],
"schemes" => ["https", "http"],
"paths"=>{
"/simple"=>{"get"=>{"produces"=>["application/json"], "responses"=>{"200"=>{"description"=>"Show this endpoint"}}}},
"/lazy"=>{"get"=>{"produces"=>["application/json"], "responses"=>{"200"=>{"description"=>"Lazily show endpoint"}}}}}
"/simple"=>{"get"=>{"produces"=>["application/json"], "tags"=>["simple"], "responses"=>{"200"=>{"description"=>"Show this endpoint"}}}},
"/lazy"=>{"get"=>{"produces"=>["application/json"], "tags"=>["lazy"], "responses"=>{"200"=>{"description"=>"Lazily show endpoint"}}}}}
})
end
end
Expand Down Expand Up @@ -84,9 +85,10 @@ def app
"swagger"=>"2.0",
"produces"=>["application/xml", "application/json", "application/octet-stream", "text/plain"],
"host"=>"example.org",
"tags" => [{"name"=>"simple", "description"=>"Operations about simples"}],
"schemes" => ["https", "http"],
"paths"=>{
"/simple/show"=>{"get"=>{"produces"=>["application/json"], "responses"=>{"200"=>{"description"=>"Show this endpoint"}}}}}
"/simple/show"=>{"get"=>{"produces"=>["application/json"], "tags"=>["simple"], "responses"=>{"200"=>{"description"=>"Show this endpoint"}}}}}
})
end

Expand All @@ -97,9 +99,10 @@ def app
"swagger"=>"2.0",
"produces"=>["application/xml", "application/json", "application/octet-stream", "text/plain"],
"host"=>"example.org",
"tags" => [{"name"=>"simple", "description"=>"Operations about simples"}],
"schemes" => ["https", "http"],
"paths"=>{
"/simple/show"=>{"get"=>{"produces"=>["application/json"], "responses"=>{"200"=>{"description"=>"Show this endpoint"}}}}}
"/simple/show"=>{"get"=>{"produces"=>["application/json"], "tags"=>["simple"], "responses"=>{"200"=>{"description"=>"Show this endpoint"}}}}}
})
end
end
6 changes: 4 additions & 2 deletions spec/swagger_v2/mounted_target_class_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,11 @@ def app
expect(JSON.parse(last_response.body)).to eq({
"info"=>{"title"=>"API title", "version"=>"v1"},
"swagger"=>"2.0",
"tags" => [{"name"=>"simple", "description"=>"Operations about simples"}],
"produces"=>["application/xml", "application/json", "application/octet-stream", "text/plain"],
"host"=>"example.org",
"schemes" => ["https", "http"],
"paths"=>{"/simple"=>{"get"=>{"produces"=>["application/json"], "responses"=>{"200"=>{"description"=>"This gets something."}}}}}
"paths" => {"/simple"=>{"get"=>{"produces"=>["application/json"], "tags"=>["simple"], "responses"=>{"200"=>{"description"=>"This gets something."}}}}}
})
end

Expand All @@ -43,10 +44,11 @@ def app
expect(JSON.parse(last_response.body)).to eq({
"info"=>{"title"=>"API title", "version"=>"v1"},
"swagger"=>"2.0",
"tags" => [{"name"=>"simple", "description"=>"Operations about simples"}],
"produces"=>["application/xml", "application/json", "application/octet-stream", "text/plain"],
"host"=>"example.org",
"schemes" => ["https", "http"],
"paths"=>{"/simple"=>{"get"=>{"produces"=>["application/json"], "responses"=>{"200"=>{"description"=>"This gets something."}}}}}
"paths" => {"/simple"=>{"get"=>{"produces"=>["application/json"], "tags"=>["simple"], "responses"=>{"200"=>{"description"=>"This gets something."}}}}}
})
end
end
Loading