Module: SoberSwag::Controller

Extended by:
ActiveSupport::Concern
Defined in:
lib/sober_swag/controller.rb,
lib/sober_swag/controller/route.rb,
lib/sober_swag/controller/undefined_body_error.rb,
lib/sober_swag/controller/undefined_path_error.rb,
lib/sober_swag/controller/undefined_query_error.rb

Overview

This module can be included in any subclass of ActionController or ActionController::API to make it SoberSwag-able. This means that you can use the mechanics of SoberSwag to define a type-safe API, with generated Swagger documentation!

Defined Under Namespace

Modules: ClassMethods, Types Classes: Route, UndefinedBodyError, UndefinedPathError, UndefinedQueryError

Instance Method Summary collapse

Instance Method Details

#body_paramsHash

Obtain a parameters hash of only those parameters which come in the hash. These will be unsafe in the sense that they will all be allowed. This kinda violates the "be liberal in what you accept" principle, but it keeps the docs honest: parameters sent in the body must be in the body.

Returns:

  • (Hash)


174
175
176
# File 'lib/sober_swag/controller.rb', line 174

def body_params
  request.request_parameters
end

#build_parsed_sober_swag(parser, params) ⇒ Object



186
187
188
189
190
191
192
# File 'lib/sober_swag/controller.rb', line 186

def build_parsed_sober_swag(parser, params)
  if parser.respond_to?(:call!)
    parser.call!(params)
  else
    parser.call(params)
  end
end

#current_action_defSoberSwag::Controller::Route

Get the action-definition for the current action. Under the hood, delegates to the :action key of rails params.



182
183
184
# File 'lib/sober_swag/controller.rb', line 182

def current_action_def
  self.class.find_route(params[:action])
end

#parsed_bodyObject

Get the request body, parsed into the type you defined with SoberSwag::Controller::ClassMethods#define.

Raises:

  • (UndefinedBodyError)

    if there's no request body defined for this route

  • (Dry::Struct::Error)

    if we cannot convert the path params to the defined type.



125
126
127
128
129
130
131
132
133
# File 'lib/sober_swag/controller.rb', line 125

def parsed_body
  @parsed_body ||=
    begin
      r = current_action_def
      raise UndefinedBodyError unless r&.request_body_class

      build_parsed_sober_swag(r.request_body_class, body_params)
    end
end

#parsed_pathObject

Get the path parameters, parsed into the type you defined with SoberSwag::Controller::ClassMethods#define

Raises:

  • (UndefinedPathError)

    if there's no path params defined for this route

  • (Dry::Struct::Error)

    if we cannot convert the path params to the defined type.



111
112
113
114
115
116
117
118
119
# File 'lib/sober_swag/controller.rb', line 111

def parsed_path
  @parsed_path ||=
    begin
      r = current_action_def
      raise UndefinedPathError unless r&.path_params_class

      build_parsed_sober_swag(r.path_params_class, request.path_parameters)
    end
end

#parsed_queryObject

Get the query params, parsed into the type you defined with SoberSwag::Controller::ClassMethods#define

Raises:

  • (UndefinedQueryError)

    if there's no query params defined for this route

  • (Dry::Struct::Error)

    if we cannot convert the path params to the defined type.



139
140
141
142
143
144
145
146
147
# File 'lib/sober_swag/controller.rb', line 139

def parsed_query
  @parsed_query ||=
    begin
      r = current_action_def
      raise UndefinedQueryError unless r&.query_params_class

      build_parsed_sober_swag(r.query_params_class, request.query_parameters)
    end
end

#respond!(status, entity, serializer_opts: {}, rails_opts: {}) ⇒ Object

TODO:

figure out how to specify views and other options for the serializer here

Respond with the serialized type that you defined for this route.

Parameters:

  • status (Symbol)

    the HTTP status symbol to use for the status code

  • entity

    the thing to serialize



154
155
156
157
158
159
160
161
162
163
164
# File 'lib/sober_swag/controller.rb', line 154

def respond!(status, entity, serializer_opts: {}, rails_opts: {})
  r = current_action_def
  serializer = r.response_serializers[Rack::Utils.status_code(status)]
  if serializer.respond_to?(:reporting?) && serializer.reporting?
    serializer = serializer.view(serializer_opts[:view].to_sym) if serializer_opts.key?(:view)
    render json: serializer.call(entity), status: status, **rails_opts
  else
    serializer ||= serializer.new if serializer.respond_to?(:new)
    render json: serializer.serialize(entity, serializer_opts), status: status, **rails_opts
  end
end

#swaggerObject

ActiveController action to get the swagger definition for this API. It renders a JSON of the OpenAPI v3 schema for this API.



103
104
105
# File 'lib/sober_swag/controller.rb', line 103

def swagger
  render json: self.class.swagger_info
end