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/
38 changes: 36 additions & 2 deletions lib/grape-swagger/doc_methods.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,28 @@ def setup(options)
header['Access-Control-Allow-Origin'] = '*'
header['Access-Control-Request-Method'] = '*'

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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Try to refactor the whole description logic out of here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi Daniel, Thank you for the feedback.
#348
I have updated the code and the build is passing now.
looking forward for your feed back.

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
# tag information included
output = swagger_object(
info_object(extra_info.merge(version: api_version)),
target_class,
request,
options
options,
namespace_routes_array
)

target_routes = target_class.combined_namespace_routes
Expand All @@ -59,14 +76,31 @@ def setup(options)
get "#{mount_path}/:name" do
I18n.locale = params[:locale] || I18n.default_locale

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

combined_routes = target_class.combined_namespace_routes[params[:name]]
error!({ error: 'named resource not exist' }, 400) if combined_routes.nil?

output = swagger_object(
info_object(extra_info.merge(version: api_version)),
target_class,
request,
options
options,
namespace_routes_array
)

target_routes = { params[:name] => combined_routes }
Expand Down
4 changes: 3 additions & 1 deletion lib/grape-swagger/endpoint.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,15 @@ def content_types_for(target_class)
# swagger spec2.0 related parts
#
# required keys for SwaggerObject
def swagger_object(info, target_class, request, options)
def swagger_object(info, target_class, request, options, namespace_routes_array)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why wound't the namespace_routes_array be passed with options?

{
info: info,
swagger: '2.0',
produces: content_types_for(target_class),
authorizations: options[:authorizations],
host: request.env['HTTP_HOST'] || options[:host],
basePath: request.env['SCRIPT_NAME'] || options[:base_path],
tags: namespace_routes_array,
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] = Array(route.route_path.split('{')[0].split('/').delete_if { |i| (i==route.route_prefix) || i[/v[0-9]*/] }.reject(&:empty?).first)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be refactored out.

methods[:responses] = response_object(route)

if route.route_aws
Expand Down
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
3 changes: 3 additions & 0 deletions spec/swagger_v2/params_array_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"=>"groups", "description"=>"Operations about groups"}, {"name"=>"type_given", "description"=>"Operations about type_givens"}],
"schemes" => ["https", "http"],
"paths"=>{
"/groups"=>{
"post"=>{
"produces"=>["application/json"],
"tags"=>["groups"],
"responses"=>{"201"=>{"description"=>"created Group"}},
"parameters"=>[
{"in"=>"formData", "name"=>"required_group[][required_param_1]", "description"=>nil, "type"=>"string", "required"=>true, "allowMultiple"=>true},
Expand All @@ -68,6 +70,7 @@ def app
"swagger"=>"2.0",
"produces"=>["application/json"],
"host"=>"example.org",
"tags" => [{"name"=>"groups", "description"=>"Operations about groups"}, {"name"=>"type_given", "description"=>"Operations about type_givens"}],
"schemes" => ["https", "http"],
"paths"=>{
"/type_given"=>{
Expand Down
Loading