@@ -214,14 +214,16 @@ def register_api(api_class)
214214 build_error_response_body ( api_class , error_serializer_class )
215215 end
216216
217- def register_contract ( contract_class , representation_class , actions )
217+ def register_contract ( contract_class , representation_class , resource : nil )
218+ resource_actions = resource ? resource . actions : { }
219+
218220 capabilities . each do |capability |
219- capability . contract_types ( contract_class , representation_class , actions )
221+ capability . contract_types ( contract_class , representation_class , resource_actions )
220222 end
221223
222224 self . class . resource_serializer . new ( representation_class ) . contract_types ( contract_class )
223225
224- build_action_responses ( contract_class , representation_class , actions )
226+ build_action_responses ( contract_class , representation_class , resource_actions , resource . name ) if resource
225227 end
226228
227229 def apply_request_transformers ( request , phase :)
@@ -250,33 +252,35 @@ def apply_capabilities(data, representation_class, request, wrapper_type:)
250252 )
251253 end
252254
253- def build_action_responses ( contract_class , representation_class , actions )
255+ def build_action_responses ( contract_class , representation_class , actions , resource_name )
254256 actions . each_value do |action |
255- build_action_response ( contract_class , representation_class , action )
257+ build_action_response ( contract_class , representation_class , action , resource_name )
256258 end
257259 end
258260
259- def build_action_response ( contract_class , representation_class , action )
261+ def build_action_response ( contract_class , representation_class , action , resource_name )
260262 contract_action = contract_class . action ( action . name )
261263 return if contract_action . resets_response?
262264
263265 case action . name
264266 when :index
265- build_collection_action_response ( contract_class , representation_class , action , contract_action )
267+ build_collection_action_response ( contract_class , representation_class , action , contract_action , resource_name )
266268 when :show , :create , :update
267- build_member_action_response ( contract_class , representation_class , action , contract_action )
269+ build_member_action_response ( contract_class , representation_class , action , contract_action , resource_name )
268270 when :destroy
269271 contract_action . response { no_content! }
270272 else
271- build_custom_action_response ( contract_class , representation_class , action , contract_action )
273+ build_custom_action_response ( contract_class , representation_class , action , contract_action , resource_name )
272274 end
273275
274- build_request_query_type ( contract_class , action . name , contract_action )
275- build_request_body_type ( contract_class , action . name , contract_action )
276+ build_request_query_type ( contract_class , action . name , contract_action , resource_name )
277+ build_request_body_type ( contract_class , action . name , contract_action , resource_name )
278+ build_request_type ( contract_class , action . name , contract_action , resource_name )
279+ build_response_type ( contract_class , action . name , contract_action , resource_name )
276280 end
277281
278- def build_member_action_response ( contract_class , representation_class , action , contract_action )
279- build_response_body_type ( contract_class , representation_class , action . name , :member )
282+ def build_member_action_response ( contract_class , representation_class , action , contract_action , resource_name )
283+ build_response_body_type ( contract_class , representation_class , action . name , :member , resource_name )
280284 member_shape_class = self . class . member_wrapper . shape_class
281285 data_type = resolve_resource_data_type ( representation_class )
282286
@@ -287,8 +291,8 @@ def build_member_action_response(contract_class, representation_class, action, c
287291 end
288292 end
289293
290- def build_collection_action_response ( contract_class , representation_class , action , contract_action )
291- build_response_body_type ( contract_class , representation_class , action . name , :collection )
294+ def build_collection_action_response ( contract_class , representation_class , action , contract_action , resource_name )
295+ build_response_body_type ( contract_class , representation_class , action . name , :collection , resource_name )
292296 collection_shape_class = self . class . collection_wrapper . shape_class
293297 data_type = resolve_resource_data_type ( representation_class )
294298
@@ -299,19 +303,20 @@ def build_collection_action_response(contract_class, representation_class, actio
299303 end
300304 end
301305
302- def build_custom_action_response ( contract_class , representation_class , action , contract_action )
306+ def build_custom_action_response ( contract_class , representation_class , action , contract_action , resource_name )
303307 if action . method == :delete
304308 contract_action . response { no_content! }
305309 elsif action . collection?
306- build_collection_action_response ( contract_class , representation_class , action , contract_action )
310+ build_collection_action_response ( contract_class , representation_class , action , contract_action , resource_name )
307311 elsif action . member?
308- build_member_action_response ( contract_class , representation_class , action , contract_action )
312+ build_member_action_response ( contract_class , representation_class , action , contract_action , resource_name )
309313 end
310314 end
311315
312- def build_response_body_type ( contract_class , representation_class , action_name , response_type )
313- type_name = [ action_name , 'response_body' ] . join ( '_' ) . to_sym
314- return if contract_class . type? ( type_name )
316+ def build_response_body_type ( contract_class , representation_class , action_name , response_type , resource_name )
317+ type_name = build_action_type_name ( resource_name , action_name , 'response_body' )
318+ api_class = contract_class . api_class
319+ return if api_class . type_registry . key? ( type_name )
315320
316321 shape_class = if response_type == :collection
317322 self . class . collection_wrapper . shape_class
@@ -320,35 +325,74 @@ def build_response_body_type(contract_class, representation_class, action_name,
320325 end
321326 data_type = resolve_resource_data_type ( representation_class )
322327
323- contract_class . object ( type_name ) do |object |
328+ api_class . register_object ( type_name ) do |object |
324329 shape_class . apply ( object , representation_class . root_key , capabilities , representation_class , response_type , data_type :)
325330 end
326331 end
327332
328- def build_request_query_type ( contract_class , action_name , contract_action )
333+ def build_request_query_type ( contract_class , action_name , contract_action , resource_name )
329334 request = contract_action . request
330335 return unless request . query . params . any?
331336
332- type_name = [ action_name , 'request_query' ] . join ( '_' ) . to_sym
333- return if contract_class . type? ( type_name )
337+ type_name = build_action_type_name ( resource_name , action_name , 'request_query' )
338+ api_class = contract_class . api_class
339+ return if api_class . type_registry . key? ( type_name )
334340
335- contract_class . object ( type_name ) do |object |
341+ api_class . register_object ( type_name ) do |object |
336342 request . query . params . each { |name , param | object . param ( name , **normalize_request_param ( param ) ) }
337343 end
338344 end
339345
340- def build_request_body_type ( contract_class , action_name , contract_action )
346+ def build_request_body_type ( contract_class , action_name , contract_action , resource_name )
341347 request = contract_action . request
342348 return unless request . body . params . any?
343349
344- type_name = [ action_name , 'request_body' ] . join ( '_' ) . to_sym
345- return if contract_class . type? ( type_name )
350+ type_name = build_action_type_name ( resource_name , action_name , 'request_body' )
351+ api_class = contract_class . api_class
352+ return if api_class . type_registry . key? ( type_name )
346353
347- contract_class . object ( type_name ) do |object |
354+ api_class . register_object ( type_name ) do |object |
348355 request . body . params . each { |name , param | object . param ( name , **normalize_request_param ( param ) ) }
349356 end
350357 end
351358
359+ def build_request_type ( contract_class , action_name , contract_action , resource_name )
360+ request = contract_action . request
361+ return unless request . query . params . any? || request . body . params . any?
362+
363+ type_name = build_action_type_name ( resource_name , action_name , 'request' )
364+ api_class = contract_class . api_class
365+ return if api_class . type_registry . key? ( type_name )
366+
367+ query_type_name = build_action_type_name ( resource_name , action_name , 'request_query' )
368+ body_type_name = build_action_type_name ( resource_name , action_name , 'request_body' )
369+
370+ api_class . register_object ( type_name ) do |object |
371+ object . param ( :query , type : query_type_name ) if request . query . params . any?
372+ object . param ( :body , type : body_type_name ) if request . body . params . any?
373+ end
374+ end
375+
376+ def build_response_type ( contract_class , action_name , contract_action , resource_name )
377+ type_name = build_action_type_name ( resource_name , action_name , 'response' )
378+ api_class = contract_class . api_class
379+ return if api_class . type_registry . key? ( type_name )
380+
381+ body_type_name = build_action_type_name ( resource_name , action_name , 'response_body' )
382+
383+ if contract_action . response . no_content?
384+ api_class . register_object ( type_name ) { |_object | }
385+ else
386+ api_class . register_object ( type_name ) do |object |
387+ object . param ( :body , type : body_type_name )
388+ end
389+ end
390+ end
391+
392+ def build_action_type_name ( resource_name , action_name , suffix )
393+ [ resource_name , action_name , suffix ] . join ( '_' ) . to_sym
394+ end
395+
352396 def normalize_request_param ( param )
353397 options = param . except ( :name , :custom_type , :union , :partial )
354398 options [ :type ] = param [ :custom_type ] if param [ :custom_type ]
0 commit comments