Class: Apiwork::API::Resource
- Inherits:
-
Object
- Object
- Apiwork::API::Resource
- Defined in:
- lib/apiwork/api/resource.rb,
lib/apiwork/api/resource/action.rb
Overview
Block context for defining API resources and routes.
Resource provides the DSL available inside ‘resources` and `resource` blocks. Methods include nested resources, custom actions, and concerns.
Defined Under Namespace
Classes: Action
Instance Attribute Summary collapse
- #api_class ⇒ Object readonly
- #constraints ⇒ Object readonly
- #contract_class ⇒ Object
- #contract_class_name ⇒ Object readonly
- #controller ⇒ Object readonly
- #defaults ⇒ Object readonly
- #except ⇒ Object readonly
- #name ⇒ Object readonly
- #only ⇒ Object readonly
- #param ⇒ Object readonly
- #path ⇒ Object readonly
- #singular ⇒ Object readonly
Instance Method Summary collapse
- #actions ⇒ Object
- #add_action(action_name, method:, type:) ⇒ Object
- #add_resource(resource) ⇒ Object
-
#collection {|resource| ... } ⇒ void
Block for defining collection actions.
- #collection_actions ⇒ Object
-
#concern(concern_name, callable = nil) {|resource| ... } ⇒ void
Defines a reusable concern.
-
#concerns(*concern_names, **options) ⇒ void
Includes previously defined concerns.
-
#delete(action_names, on: nil) ⇒ void
Defines a DELETE action.
- #each_resource(&block) ⇒ Object
- #find_resource(resource_name = nil, &block) ⇒ Object
- #find_resource_for_path(resource_path) ⇒ Object
-
#get(action_names, on: nil) ⇒ void
Defines a GET action.
- #index_actions? ⇒ Boolean
-
#initialize(api_class, constraints: nil, contract_class_name: nil, controller: nil, defaults: nil, except: nil, name: nil, only: nil, param: nil, path: nil, singular: false) ⇒ Resource
constructor
A new instance of Resource.
-
#member {|resource| ... } ⇒ void
Block for defining member actions (operate on :id).
- #member_actions ⇒ Object
-
#patch(action_names, on: nil) ⇒ void
Defines a PATCH action.
-
#post(action_names, on: nil) ⇒ void
Defines a POST action.
-
#put(action_names, on: nil) ⇒ void
Defines a PUT action.
- #representation_class ⇒ Object
- #representation_classes ⇒ Object
- #resolve_contract_class ⇒ Object
-
#resource(resource_name, concerns: nil, constraints: nil, contract: nil, controller: nil, defaults: nil, except: nil, only: nil, param: nil, path: nil) {|resource| ... } ⇒ void
Defines a singular resource (no index, no :id in URL).
-
#resources(resource_name = nil, concerns: nil, constraints: nil, contract: nil, controller: nil, defaults: nil, except: nil, only: nil, param: nil, path: nil) {|resource| ... } ⇒ Hash{Symbol => Resource}
Defines a plural resource with standard CRUD actions.
-
#with_options(options = {}) {|resource| ... } ⇒ void
Applies options to all resources defined in the block.
Constructor Details
#initialize(api_class, constraints: nil, contract_class_name: nil, controller: nil, defaults: nil, except: nil, name: nil, only: nil, param: nil, path: nil, singular: false) ⇒ Resource
Returns a new instance of Resource.
41 42 43 44 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 |
# File 'lib/apiwork/api/resource.rb', line 41 def initialize( api_class, constraints: nil, contract_class_name: nil, controller: nil, defaults: nil, except: nil, name: nil, only: nil, param: nil, path: nil, singular: false ) @api_class = api_class @constraints = constraints @contract_class_name = contract_class_name @controller = controller @defaults = defaults @except = except @name = name @only = only @param = param @path = path @singular = singular @crud_actions = name ? determine_crud_actions(singular, except:, only:) : [] @custom_actions = [] @resources = {} @concerns = {} @resource_stack = [] @current_options = nil @in_member_block = false @in_collection_block = false end |
Instance Attribute Details
#api_class ⇒ Object (readonly)
27 28 29 |
# File 'lib/apiwork/api/resource.rb', line 27 def api_class @api_class end |
#constraints ⇒ Object (readonly)
27 28 29 |
# File 'lib/apiwork/api/resource.rb', line 27 def constraints @constraints end |
#contract_class ⇒ Object
39 40 41 |
# File 'lib/apiwork/api/resource.rb', line 39 def contract_class @contract_class end |
#contract_class_name ⇒ Object (readonly)
27 28 29 |
# File 'lib/apiwork/api/resource.rb', line 27 def contract_class_name @contract_class_name end |
#controller ⇒ Object (readonly)
27 28 29 |
# File 'lib/apiwork/api/resource.rb', line 27 def controller @controller end |
#defaults ⇒ Object (readonly)
27 28 29 |
# File 'lib/apiwork/api/resource.rb', line 27 def defaults @defaults end |
#except ⇒ Object (readonly)
27 28 29 |
# File 'lib/apiwork/api/resource.rb', line 27 def except @except end |
#param ⇒ Object (readonly)
27 28 29 |
# File 'lib/apiwork/api/resource.rb', line 27 def param @param end |
#singular ⇒ Object (readonly)
27 28 29 |
# File 'lib/apiwork/api/resource.rb', line 27 def singular @singular end |
Instance Method Details
#actions ⇒ Object
88 89 90 |
# File 'lib/apiwork/api/resource.rb', line 88 def actions @actions ||= build_actions end |
#add_action(action_name, method:, type:) ⇒ Object
100 101 102 |
# File 'lib/apiwork/api/resource.rb', line 100 def add_action(action_name, method:, type:) @custom_actions << Action.new(action_name, method:, type:) end |
#add_resource(resource) ⇒ Object
104 105 106 |
# File 'lib/apiwork/api/resource.rb', line 104 def add_resource(resource) @resources[resource.name] = resource end |
#collection {|resource| ... } ⇒ void
This method returns an undefined value.
Block for defining collection actions.
Collection routes don’t include :id: ‘/invoices/action`
376 377 378 379 380 |
# File 'lib/apiwork/api/resource.rb', line 376 def collection(&block) @in_collection_block = true block.arity.positive? ? yield(self) : instance_eval(&block) @in_collection_block = false end |
#collection_actions ⇒ Object
96 97 98 |
# File 'lib/apiwork/api/resource.rb', line 96 def collection_actions @custom_actions.select(&:collection?).index_by(&:name) end |
#concern(concern_name, callable = nil) {|resource| ... } ⇒ void
This method returns an undefined value.
Defines a reusable concern.
484 485 486 487 488 489 490 491 492 493 |
# File 'lib/apiwork/api/resource.rb', line 484 def concern(concern_name, callable = nil, &block) callable ||= lambda do |resource, | if block.arity.positive? yield(resource, ) else resource.instance_exec(, &block) end end @concerns[concern_name] = callable end |
#concerns(*concern_names, **options) ⇒ void
This method returns an undefined value.
Includes previously defined concerns.
508 509 510 511 512 513 514 515 |
# File 'lib/apiwork/api/resource.rb', line 508 def concerns(*concern_names, **) concern_names.flatten.each do |concern_name| callable = @concerns[concern_name] raise ConfigurationError, "No concern named :#{concern_name} was found" unless callable callable.call(self, ) end end |
#delete(action_names, on: nil) ⇒ void
This method returns an undefined value.
Defines a DELETE action.
456 457 458 |
# File 'lib/apiwork/api/resource.rb', line 456 def delete(action_names, on: nil) capture_actions(action_names, on:, method: :delete) end |
#each_resource(&block) ⇒ Object
135 136 137 138 139 140 |
# File 'lib/apiwork/api/resource.rb', line 135 def each_resource(&block) @resources.each_value do |resource| yield resource resource.each_resource(&block) end end |
#find_resource(resource_name = nil, &block) ⇒ Object
108 109 110 111 112 113 114 115 116 117 118 |
# File 'lib/apiwork/api/resource.rb', line 108 def find_resource(resource_name = nil, &block) return find_resource_by_block(&block) if block return @resources[resource_name] if @resources[resource_name] @resources.each_value do |resource| found = resource.find_resource(resource_name) return found if found end nil end |
#find_resource_for_path(resource_path) ⇒ Object
120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
# File 'lib/apiwork/api/resource.rb', line 120 def find_resource_for_path(resource_path) current = nil resource_path.split('/').each do |part| next if part.empty? resource_name = part.tr('-', '_').to_sym target = current ? current.resources : @resources found = target[resource_name] || target[resource_name.to_s.singularize.to_sym] next unless found current = found end current end |
#get(action_names, on: nil) ⇒ void
This method returns an undefined value.
Defines a GET action.
396 397 398 |
# File 'lib/apiwork/api/resource.rb', line 396 def get(action_names, on: nil) capture_actions(action_names, on:, method: :get) end |
#index_actions? ⇒ Boolean
76 77 78 |
# File 'lib/apiwork/api/resource.rb', line 76 def index_actions? @resources.values.any? { |resource| resource.actions.key?(:index) || resource.index_actions? } end |
#member {|resource| ... } ⇒ void
This method returns an undefined value.
Block for defining member actions (operate on :id).
Member routes include :id in the path: ‘/invoices/:id/action`
350 351 352 353 354 |
# File 'lib/apiwork/api/resource.rb', line 350 def member(&block) @in_member_block = true block.arity.positive? ? yield(self) : instance_eval(&block) @in_member_block = false end |
#member_actions ⇒ Object
92 93 94 |
# File 'lib/apiwork/api/resource.rb', line 92 def member_actions @custom_actions.select(&:member?).index_by(&:name) end |
#patch(action_names, on: nil) ⇒ void
This method returns an undefined value.
Defines a PATCH action.
426 427 428 |
# File 'lib/apiwork/api/resource.rb', line 426 def patch(action_names, on: nil) capture_actions(action_names, on:, method: :patch) end |
#post(action_names, on: nil) ⇒ void
This method returns an undefined value.
Defines a POST action.
411 412 413 |
# File 'lib/apiwork/api/resource.rb', line 411 def post(action_names, on: nil) capture_actions(action_names, on:, method: :post) end |
#put(action_names, on: nil) ⇒ void
This method returns an undefined value.
Defines a PUT action.
441 442 443 |
# File 'lib/apiwork/api/resource.rb', line 441 def put(action_names, on: nil) capture_actions(action_names, on:, method: :put) end |
#representation_class ⇒ Object
84 85 86 |
# File 'lib/apiwork/api/resource.rb', line 84 def representation_class contract_class&.representation_class end |
#representation_classes ⇒ Object
80 81 82 |
# File 'lib/apiwork/api/resource.rb', line 80 def representation_classes @representation_classes ||= collect_all_representation_classes end |
#resolve_contract_class ⇒ Object
142 143 144 145 146 147 148 149 |
# File 'lib/apiwork/api/resource.rb', line 142 def resolve_contract_class return @contract_class if @contract_class return nil unless @contract_class_name @contract_class = @contract_class_name.constantize rescue NameError nil end |
#resource(resource_name, concerns: nil, constraints: nil, contract: nil, controller: nil, defaults: nil, except: nil, only: nil, param: nil, path: nil) {|resource| ... } ⇒ void
This method returns an undefined value.
Defines a singular resource (no index, no :id in URL).
Default actions: :show, :create, :update, :destroy.
266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 |
# File 'lib/apiwork/api/resource.rb', line 266 def resource( resource_name, concerns: nil, constraints: nil, contract: nil, controller: nil, defaults: nil, except: nil, only: nil, param: nil, path: nil, &block ) = { constraints:, contract:, controller:, defaults:, except:, only:, param:, path:, }.compact build_resource(resource_name, options:, singular: true) @resource_stack.push(resource_name) self.concerns(*concerns) if concerns if block block.arity.positive? ? yield(self) : instance_eval(&block) end @resource_stack.pop end |
#resources(resource_name = nil, concerns: nil, constraints: nil, contract: nil, controller: nil, defaults: nil, except: nil, only: nil, param: nil, path: nil) {|resource| ... } ⇒ Hash{Symbol => Resource}
Defines a plural resource with standard CRUD actions.
Default actions: :index, :show, :create, :update, :destroy.
191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 |
# File 'lib/apiwork/api/resource.rb', line 191 def resources( resource_name = nil, concerns: nil, constraints: nil, contract: nil, controller: nil, defaults: nil, except: nil, only: nil, param: nil, path: nil, &block ) return @resources if resource_name.nil? = { constraints:, contract:, controller:, defaults:, except:, only:, param:, path:, }.compact build_resource(resource_name, options:, singular: false) @resource_stack.push(resource_name) self.concerns(*concerns) if concerns if block block.arity.positive? ? yield(self) : instance_eval(&block) end @resource_stack.pop end |
#with_options(options = {}) {|resource| ... } ⇒ void
This method returns an undefined value.
Applies options to all resources defined in the block.
321 322 323 324 325 326 327 328 |
# File 'lib/apiwork/api/resource.rb', line 321 def ( = {}, &block) = @current_options @current_options = () block.arity.positive? ? yield(self) : instance_eval(&block) @current_options = end |