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)


82
83
84
85
86
87
88
89
90
# File 'lib/api_blocks/responder.rb', line 82

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.



41
42
43
44
45
46
47
# File 'lib/api_blocks/responder.rb', line 41

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)


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

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

  super
end

#json_sesource_errorsObject



70
71
72
# File 'lib/api_blocks/responder.rb', line 70

def json_sesource_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
31
32
33
34
35
36
# 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 ActiveModel::ValidationError
    [{ errors: resource.model.errors }, :unprocessable_entity]
  when String
    [{ detail: resource }, :internal_server_error]
  when ProblemDetails::Document
    [resource.to_h, resource.status]
  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.



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

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

  super
end