Class: ApiBlocks::Responder

Inherits:
ActionController::Responder
  • Object
show all
Includes:
Responders::HttpCacheResponder
Defined in:
lib/api_blocks/responder.rb

Overview

ApiBlocks::Responder provides a responder with better error handling and ‘ApiBlocks::Interactor` through `Dry::Monads::Result` support.

Instance Method Summary collapse

Instance Method Details

#api_behaviorObject

Override ActionController::Responder#api_behavior in order to provide one that matches our API documentation.

The only difference so far is that on POST we do not render ‘status: :created` along with a `Location` header.

Moreover, we display the resource on PUT.

Raises:

  • (MissingRenderer)


76
77
78
79
80
81
82
83
84
# File 'lib/api_blocks/responder.rb', line 76

def api_behavior
  raise(MissingRenderer, format) unless has_renderer?

  if get? || post? || put?
    display resource
  else
    head :no_content
  end
end

#display_errorsObject

Display is just a shortcut to render a resource’s errors with the current format using ‘problem_details` when format is set to JSON.



35
36
37
38
39
40
41
# File 'lib/api_blocks/responder.rb', line 35

def display_errors
  return super unless format == :json

  errors, status = resource_errors

  controller.render problem: errors, status: status
end

#has_errors?Boolean

rubocop:disable Naming/PredicateName

Returns:

  • (Boolean)


58
59
60
61
62
# File 'lib/api_blocks/responder.rb', line 58

def has_errors? # rubocop:disable Naming/PredicateName
  return true if @failure

  super
end

#json_resource_errorsObject



64
65
66
# File 'lib/api_blocks/responder.rb', line 64

def json_resource_errors
  [{ errors: resource.errors }, :unprocessable_entity]
end

#resource_errorsObject

Override resource_errors to handle more error kinds and return a status code.



17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/api_blocks/responder.rb', line 17

def resource_errors
  case resource
  when Dry::Validation::Result
    [{ errors: resource.errors.to_h }, :unprocessable_entity]
  when ActiveRecord::RecordInvalid
    [{ errors: resource.record.errors }, :unprocessable_entity]
  when StandardError
    # propagate the error so it can be handled through the standard rails
    # error handlers.
    raise resource
  else
    super
  end
end

#to_formatObject

All other formats follow the procedure below. First we try to render a template, if the template is not available, we verify if the resource responds to :to_format and display it.

In addition, if the resource is a Dry::Monads::Result we unwrap it and assign the failure instead.



50
51
52
53
54
55
56
# File 'lib/api_blocks/responder.rb', line 50

def to_format
  if resource.is_a?(Dry::Monads::Result)
    unwrap_dry_result
  end

  super
end