Class: Steppe::Endpoint::BodyParser

Inherits:
Object
  • Object
show all
Includes:
Plumb::Composable
Defined in:
lib/steppe/endpoint.rb

Overview

Internal step that parses request body based on content type. Supports JSON and plain text parsing out of the box. Returns 400 Bad Request if parsing fails.

Constant Summary collapse

MissingParserError =
Class.new(ArgumentError)

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(content_type, parser) ⇒ BodyParser

Returns a new instance of BodyParser.



214
215
216
217
# File 'lib/steppe/endpoint.rb', line 214

def initialize(content_type, parser)
  @content_type = content_type
  @parser = parser
end

Class Method Details

.build(content_type) ⇒ Object

Builds a parser for the given content type

Raises:



207
208
209
210
211
212
# File 'lib/steppe/endpoint.rb', line 207

def self.build(content_type)
  parser = parsers[content_type.media_type]
  raise MissingParserError, "No parser for content type: #{content_type}" unless parser

  new(content_type, parser)
end

.parsersObject

Registry of content type parsers



191
192
193
# File 'lib/steppe/endpoint.rb', line 191

def self.parsers
  @parsers ||= {}
end

Instance Method Details

#call(conn) ⇒ Object



219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
# File 'lib/steppe/endpoint.rb', line 219

def call(conn)
  return conn unless @content_type.media_type == conn.request.media_type

  if conn.request.body
    body = @parser.call(conn.request)
    # Maybe here we can just mutate the request?
    conn.request.env[::Rack::RACK_INPUT] = body
    return conn
    # request = Steppe::Request.new(conn.request.env.merge(::Rack::RACK_INPUT => body))
    # return conn.copy(request:)
  end
  conn
rescue StandardError => e
  conn.respond_with(400).invalid(errors: { body: e.message })
end