Skip to content
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

Add parent and data references to nodes #138

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,32 @@ operation :post do
end
```

Additionally, many APIs have standard responses based on the path or operation. You can retrieve references to these in order to DRY up code.

```ruby
module SwaggerResponses
module PostResponses
def self.extended(base)
operation = base.operation
path = base.parent.path

return unless operation == :post
base.response 201 do
key :description, dynamic_description_based_on_path
schema do
key :'$ref', dynamic_ref_name_based_on_path
end
end
end
end
end

operation :post do
extend SwaggerResponses::PostResponses
# ...
end
```

## Reference

See the [swagger_v2_blocks_spec.rb](https://github.com/fotinakis/swagger-blocks/blob/master/spec/lib/swagger_v2_blocks_spec.rb) for examples of more complex features and declarations possible.
Expand Down
2 changes: 1 addition & 1 deletion lib/swagger/blocks/class_methods.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def swagger_path(path, &block)
path_node.instance_eval(&block)
else
# First time we've seen this path
@swagger_path_node_map[path] = Swagger::Blocks::Nodes::PathNode.call(version: version, &block)
@swagger_path_node_map[path] = Swagger::Blocks::Nodes::PathNode.call(version: version, path: path.to_s, &block)
end
end

Expand Down
9 changes: 4 additions & 5 deletions lib/swagger/blocks/node.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,16 @@ module Swagger
module Blocks
# Base node for representing every object in the Swagger DSL.
class Node
attr_accessor :name
attr_accessor :parent, :name
attr_writer :version
VERSION_2 = '2.0'
VERSION_3 = '3.0.0'

def self.call(options = {}, &block)
def self.call(parent: nil, name: nil, version: nil, inline_keys: nil, **internal_data, &block)
# Create a new instance and evaluate the block into it.
instance = new
instance.name = options[:name] if options[:name]
instance.version = options[:version]
instance.keys options[:inline_keys]
instance.parent, instance.name, instance.version = parent, name, version
instance.keys inline_keys
instance.instance_eval(&block) if block
instance
end
Expand Down
2 changes: 1 addition & 1 deletion lib/swagger/blocks/nodes/all_of_node.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def key(key, value)
end

def schema(inline_keys = nil, &block)
data << Swagger::Blocks::Nodes::SchemaNode.call(version: version, inline_keys: inline_keys, &block)
data << Swagger::Blocks::Nodes::SchemaNode.call(parent: self, version: version, inline_keys: inline_keys, &block)
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/swagger/blocks/nodes/callback_destination_node.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module Blocks
module Nodes
class CallbackDestinationNode < Node
def method(method_name, inline_keys = nil, &block)
self.data[method_name] = Swagger::Blocks::Nodes::CallbackMethodNode.call(version: version, inline_keys: inline_keys, &block)
self.data[method_name] = Swagger::Blocks::Nodes::CallbackMethodNode.call(parent: self, version: version, inline_keys: inline_keys, &block)
end
end
end
Expand Down
4 changes: 2 additions & 2 deletions lib/swagger/blocks/nodes/callback_method_node.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ module Blocks
module Nodes
class CallbackMethodNode < Node
def request_body(inline_keys = nil, &block)
self.data[:requestBody] = Swagger::Blocks::Nodes::RequestBodyNode.call(version: version, inline_keys: inline_keys, &block)
self.data[:requestBody] = Swagger::Blocks::Nodes::RequestBodyNode.call(parent: self, version: version, inline_keys: inline_keys, &block)
end

def response(resp, inline_keys = nil, &block)
self.data[:responses] ||= {}
self.data[:responses][resp] = Swagger::Blocks::Nodes::ResponseNode.call(version: version, inline_keys: inline_keys, &block)
self.data[:responses][resp] = Swagger::Blocks::Nodes::ResponseNode.call(parent: self, version: version, inline_keys: inline_keys, &block)
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/swagger/blocks/nodes/callback_node.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module Blocks
module Nodes
class CallbackNode < Node
def destination(address, inline_keys = nil, &block)
self.data[address] = Swagger::Blocks::Nodes::CallbackDestinationNode.call(version: version, inline_keys: inline_keys, &block)
self.data[address] = Swagger::Blocks::Nodes::CallbackDestinationNode.call(parent: self, version: version, inline_keys: inline_keys, &block)
end
end
end
Expand Down
14 changes: 7 additions & 7 deletions lib/swagger/blocks/nodes/component_node.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,38 +11,38 @@ def schema(name, inline_keys = nil, &block)
schema_node.instance_eval(&block)
else
# First time we've seen this schema_node
self.data[:schemas][name] = Swagger::Blocks::Nodes::SchemaNode.call(version: '3.0.0', inline_keys: inline_keys, &block)
self.data[:schemas][name] = Swagger::Blocks::Nodes::SchemaNode.call(parent: self, version: '3.0.0', inline_keys: inline_keys, &block)
end
end

def link(name, inline_keys = nil, &block)
self.data[:links] ||= {}
self.data[:links][name] = Swagger::Blocks::Nodes::LinkNode.call(version: version, inline_keys: inline_keys, &block)
self.data[:links][name] = Swagger::Blocks::Nodes::LinkNode.call(parent: self, version: version, inline_keys: inline_keys, &block)
end

def example(name, inline_keys = nil, &block)
self.data[:examples] ||= {}
self.data[:examples][name] = Swagger::Blocks::Nodes::ExampleNode.call(version: version, inline_keys: inline_keys, &block)
self.data[:examples][name] = Swagger::Blocks::Nodes::ExampleNode.call(parent: self, version: version, inline_keys: inline_keys, &block)
end

def security_scheme(name, inline_keys = nil, &block)
self.data[:securitySchemes] ||= {}
self.data[:securitySchemes][name] = Swagger::Blocks::Nodes::SecuritySchemeNode.call(version: version, inline_keys: inline_keys, &block)
self.data[:securitySchemes][name] = Swagger::Blocks::Nodes::SecuritySchemeNode.call(parent: self, version: version, inline_keys: inline_keys, &block)
end

def parameter(name, inline_keys = nil, &block)
self.data[:parameters] ||= {}
self.data[:parameters][name] = Swagger::Blocks::Nodes::ParameterNode.call(version: version, inline_keys: inline_keys, &block)
self.data[:parameters][name] = Swagger::Blocks::Nodes::ParameterNode.call(parent: self, version: version, inline_keys: inline_keys, &block)
end

def request_body(name, inline_keys = nil, &block)
self.data[:requestBodies] ||= {}
self.data[:requestBodies][name] = Swagger::Blocks::Nodes::RequestBodyNode.call(version: version, inline_keys: inline_keys, &block)
self.data[:requestBodies][name] = Swagger::Blocks::Nodes::RequestBodyNode.call(parent: self, version: version, inline_keys: inline_keys, &block)
end

def response(name, inline_keys = nil, &block)
self.data[:responses] ||= {}
self.data[:responses][name] = Swagger::Blocks::Nodes::ResponseNode.call(version: version, inline_keys: inline_keys, &block)
self.data[:responses][name] = Swagger::Blocks::Nodes::ResponseNode.call(parent: self, version: version, inline_keys: inline_keys, &block)
end
end
end
Expand Down
6 changes: 3 additions & 3 deletions lib/swagger/blocks/nodes/content_node.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ module Blocks
module Nodes
class ContentNode < Node
def schema(inline_keys = nil, &block)
self.data[:schema] = Swagger::Blocks::Nodes::SchemaNode.call(version: version, inline_keys: inline_keys, &block)
self.data[:schema] = Swagger::Blocks::Nodes::SchemaNode.call(parent: self, version: version, inline_keys: inline_keys, &block)
end

def example(name = nil, inline_keys = nil, &block)
if name.nil?
self.data[:example] = Swagger::Blocks::Nodes::ExampleNode.call(version: version, inline_keys: inline_keys, &block)
self.data[:example] = Swagger::Blocks::Nodes::ExampleNode.call(parent: self, version: version, inline_keys: inline_keys, &block)
else
self.data[:examples] ||= {}
self.data[:examples][name] = Swagger::Blocks::Nodes::ExampleNode.call(version: version, inline_keys: inline_keys, &block)
self.data[:examples][name] = Swagger::Blocks::Nodes::ExampleNode.call(parent: self, version: version, inline_keys: inline_keys, &block)
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/swagger/blocks/nodes/example_node.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module Blocks
module Nodes
class ExampleNode < Node
def value(inline_keys = nil, &block)
self.data[:value] = Swagger::Blocks::Nodes::ValueNode.call(version: version, inline_keys: inline_keys, &block)
self.data[:value] = Swagger::Blocks::Nodes::ValueNode.call(parent: self, version: version, inline_keys: inline_keys, &block)
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/swagger/blocks/nodes/flow_node.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module Blocks
module Nodes
class FlowNode < Node
def scopes(inline_keys = nil, &block)
self.data[:scopes] = Swagger::Blocks::Nodes::ScopesNode.call(version: version, inline_keys: inline_keys, &block)
self.data[:scopes] = Swagger::Blocks::Nodes::ScopesNode.call(parent: self, version: version, inline_keys: inline_keys, &block)
end
end
end
Expand Down
4 changes: 2 additions & 2 deletions lib/swagger/blocks/nodes/header_node.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ module Nodes
# v2.0: https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#headerObject
class HeaderNode < Node
def items(inline_keys = nil, &block)
self.data[:items] = Swagger::Blocks::Nodes::ItemsNode.call(version: version, inline_keys: inline_keys, &block)
self.data[:items] = Swagger::Blocks::Nodes::ItemsNode.call(parent: self, version: version, inline_keys: inline_keys, &block)
end

def schema(inline_keys = nil, &block)
self.data[:schema] = Swagger::Blocks::Nodes::SchemaNode.call(version: version, inline_keys: inline_keys, &block)
self.data[:schema] = Swagger::Blocks::Nodes::SchemaNode.call(parent: self, version: version, inline_keys: inline_keys, &block)
end
end
end
Expand Down
4 changes: 2 additions & 2 deletions lib/swagger/blocks/nodes/info_node.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ module Nodes
# v2.0: https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#infoObject
class InfoNode < Node
def contact(inline_keys = nil, &block)
self.data[:contact] = Swagger::Blocks::Nodes::ContactNode.call(version: version, inline_keys: inline_keys, &block)
self.data[:contact] = Swagger::Blocks::Nodes::ContactNode.call(parent: self, version: version, inline_keys: inline_keys, &block)
end

def license(inline_keys = nil, &block)
self.data[:license] = Swagger::Blocks::Nodes::LicenseNode.call(version: version, inline_keys: inline_keys, &block)
self.data[:license] = Swagger::Blocks::Nodes::LicenseNode.call(parent: self, version: version, inline_keys: inline_keys, &block)
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/swagger/blocks/nodes/items_node.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ def property(name, inline_keys = nil, &block)
end

def items(inline_keys = nil, &block)
self.data[:items] = Swagger::Blocks::Nodes::ItemsNode.call(version: version, inline_keys: inline_keys, &block)
self.data[:items] = Swagger::Blocks::Nodes::ItemsNode.call(parent: self, version: version, inline_keys: inline_keys, &block)
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/swagger/blocks/nodes/link_node.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module Blocks
module Nodes
class LinkNode < Node
def parameters(inline_keys = nil, &block)
self.data[:parameters] ||= Swagger::Blocks::Nodes::LinkParameterNode.call(version: version, inline_keys: inline_keys, &block)
self.data[:parameters] ||= Swagger::Blocks::Nodes::LinkParameterNode.call(parent: self, version: version, inline_keys: inline_keys, &block)
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/swagger/blocks/nodes/one_of_node.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module Blocks
module Nodes
class OneOfNode < Node
def items(inline_keys = nil, &block)
self.data[:items] = Swagger::Blocks::Nodes::ItemsNode.call(version: version, inline_keys: inline_keys, &block)
self.data[:items] = Swagger::Blocks::Nodes::ItemsNode.call(parent: self, version: version, inline_keys: inline_keys, &block)
end
end
end
Expand Down
22 changes: 15 additions & 7 deletions lib/swagger/blocks/nodes/operation_node.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,41 +3,49 @@ module Blocks
module Nodes
# v2.0: https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#operation-object
class OperationNode < Node
attr_accessor :operation

def self.call(parent: nil, name: nil, version: nil, inline_keys: nil, **internal_data, &block)
instance = super
instance.operation = internal_data[:operation]
instance
end

def parameter(inline_keys = nil, &block)
inline_keys = {'$ref' => "#/parameters/#{inline_keys}"} if inline_keys.is_a?(Symbol)

self.data[:parameters] ||= []
self.data[:parameters] << Swagger::Blocks::Nodes::ParameterNode.call(version: version, inline_keys: inline_keys, &block)
self.data[:parameters] << Swagger::Blocks::Nodes::ParameterNode.call(parent: self, version: version, inline_keys: inline_keys, &block)
end

def response(resp, inline_keys = nil, &block)
# TODO validate 'resp' is as per spec
self.data[:responses] ||= {}
self.data[:responses][resp] = Swagger::Blocks::Nodes::ResponseNode.call(version: version, inline_keys: inline_keys, &block)
self.data[:responses][resp] = Swagger::Blocks::Nodes::ResponseNode.call(parent: self, version: version, inline_keys: inline_keys, &block)
end

def externalDocs(inline_keys = nil, &block)
self.data[:externalDocs] = Swagger::Blocks::Nodes::ExternalDocsNode.call(version: version, inline_keys: inline_keys, &block)
self.data[:externalDocs] = Swagger::Blocks::Nodes::ExternalDocsNode.call(parent: self, version: version, inline_keys: inline_keys, &block)
end

def security(inline_keys = nil, &block)
self.data[:security] ||= []
self.data[:security] << Swagger::Blocks::Nodes::SecurityRequirementNode.call(version: version, inline_keys: inline_keys, &block)
self.data[:security] << Swagger::Blocks::Nodes::SecurityRequirementNode.call(parent: self, version: version, inline_keys: inline_keys, &block)
end

def request_body(inline_keys = nil, &block)
self.data[:requestBody] = Swagger::Blocks::Nodes::RequestBodyNode.call(version: version, inline_keys: inline_keys, &block)
self.data[:requestBody] = Swagger::Blocks::Nodes::RequestBodyNode.call(parent: self, version: version, inline_keys: inline_keys, &block)
end

def callback(event_name, inline_keys = nil, &block)
self.data[:callbacks] ||= {}
self.data[:callbacks][event_name] = Swagger::Blocks::Nodes::CallbackNode.call(version: version, inline_keys: inline_keys, &block)
self.data[:callbacks][event_name] = Swagger::Blocks::Nodes::CallbackNode.call(parent: self, version: version, inline_keys: inline_keys, &block)
end

def server(inline_keys = nil, &block)
raise NotSupportedError unless is_openapi_3_0?
self.data[:servers] ||= []
self.data[:servers] << Swagger::Blocks::Nodes::ServerNode.call(version: version, inline_keys: inline_keys, &block)
self.data[:servers] << Swagger::Blocks::Nodes::ServerNode.call(parent: self, version: version, inline_keys: inline_keys, &block)
end
end
end
Expand Down
6 changes: 3 additions & 3 deletions lib/swagger/blocks/nodes/parameter_node.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@ module Nodes
# v2.0: https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#parameter-object
class ParameterNode < Node
def schema(inline_keys = nil, &block)
self.data[:schema] = Swagger::Blocks::Nodes::SchemaNode.call(version: version, inline_keys: inline_keys, &block)
self.data[:schema] = Swagger::Blocks::Nodes::SchemaNode.call(parent: self, version: version, inline_keys: inline_keys, &block)
end

def items(inline_keys = nil, &block)
self.data[:items] = Swagger::Blocks::Nodes::ItemsNode.call(version: version, inline_keys: inline_keys, &block)
self.data[:items] = Swagger::Blocks::Nodes::ItemsNode.call(parent: self, version: version, inline_keys: inline_keys, &block)
end

def example(name, inline_keys = nil, &block)
self.data[:examples] ||= {}
self.data[:examples][name] = Swagger::Blocks::Nodes::ExampleNode.call(version: version, inline_keys: inline_keys, &block)
self.data[:examples][name] = Swagger::Blocks::Nodes::ExampleNode.call(parent: self, version: version, inline_keys: inline_keys, &block)
end
end
end
Expand Down
14 changes: 11 additions & 3 deletions lib/swagger/blocks/nodes/path_node.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,32 @@ module Nodes
class PathNode < Node
OPERATION_TYPES = [:get, :put, :post, :delete, :options, :head, :patch].freeze

attr_accessor :path

def self.call(parent: nil, name: nil, version: nil, inline_keys: nil, **internal_data, &block)
instance = super
instance.path = internal_data[:path]
instance
end

# TODO support ^x- Vendor Extensions
def operation(op, inline_keys = nil, &block)
op = op.to_sym
raise ArgumentError.new("#{name} not in #{OPERATION_TYPES}") if !OPERATION_TYPES.include?(op)
self.data[op] = Swagger::Blocks::Nodes::OperationNode.call(version: version, inline_keys: inline_keys, &block)
self.data[op] = Swagger::Blocks::Nodes::OperationNode.call(parent: self, version: version, inline_keys: inline_keys, operation: op, &block)
end

def parameter(inline_keys = nil, &block)
inline_keys = {'$ref' => "#/parameters/#{inline_keys}"} if inline_keys.is_a?(Symbol)

self.data[:parameters] ||= []
self.data[:parameters] << Swagger::Blocks::Nodes::ParameterNode.call(version: version, inline_keys: inline_keys, &block)
self.data[:parameters] << Swagger::Blocks::Nodes::ParameterNode.call(parent: self, version: version, inline_keys: inline_keys, &block)
end

def server(inline_keys = nil, &block)
raise NotSupportedError unless is_openapi_3_0?
self.data[:servers] ||= []
self.data[:servers] << Swagger::Blocks::Nodes::ServerNode.call(version: version, inline_keys: inline_keys, &block)
self.data[:servers] << Swagger::Blocks::Nodes::ServerNode.call(parent: self, version: version, inline_keys: inline_keys, &block)
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/swagger/blocks/nodes/properties_node.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module Blocks
module Nodes
class PropertiesNode < Node
def property(name, inline_keys = nil, &block)
self.data[name] = Swagger::Blocks::Nodes::PropertyNode.call(version: version, inline_keys: inline_keys, &block)
self.data[name] = Swagger::Blocks::Nodes::PropertyNode.call(parent: self, version: version, inline_keys: inline_keys, &block)
end
end
end
Expand Down
4 changes: 2 additions & 2 deletions lib/swagger/blocks/nodes/property_node.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module Blocks
module Nodes
class PropertyNode < Node
def items(inline_keys = nil, &block)
self.data[:items] = Swagger::Blocks::Nodes::ItemsNode.call(version: version, inline_keys: inline_keys, &block)
self.data[:items] = Swagger::Blocks::Nodes::ItemsNode.call(parent: self, version: version, inline_keys: inline_keys, &block)
end

def property(name, inline_keys = nil, &block)
Expand All @@ -14,7 +14,7 @@ def property(name, inline_keys = nil, &block)

def one_of(&block)
self.data[:oneOf] ||= []
self.data[:oneOf] << Swagger::Blocks::Nodes::OneOfNode.call(version: version, &block)
self.data[:oneOf] << Swagger::Blocks::Nodes::OneOfNode.call(parent: self, version: version, &block)
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/swagger/blocks/nodes/request_body_node.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ module Nodes
class RequestBodyNode < Node
def content(type, inline_keys = nil, &block)
self.data[:content] ||= {}
self.data[:content][type] = Swagger::Blocks::Nodes::ContentNode.call(version: version, inline_keys: inline_keys, &block)
self.data[:content][type] = Swagger::Blocks::Nodes::ContentNode.call(parent: self, version: version, inline_keys: inline_keys, &block)
end
end
end
Expand Down
Loading