abstract struct Athena::Routing::ParamConverterInterface
- Athena::Routing::ParamConverterInterface
- Struct
- Value
- Object
Overview
A param converter allows applying custom logic in order to convert a primitive request parameter into a more complex type.
A few common examples could be converting a date-time string into a Time
object,
converting a user's id into an actual User
object, or deserializing a request body into an instance of T.
Examples
Defining a custom param converter requires the usage of two (optionally three) things:
- An implementation of
self
to define the conversion logic. - The
ART::ParamConverter
annotation applied to an action to specify what argument should be converted, and what converter should be used. - An optional
ART::ParamConverterInterface::ConfigurationInterface
instance to define extra configuration options that can be used within theART::ParamConverter
annotation.
Param converters are registered as services, and as such, may use any other registered services as a dependency via DI.
require "athena"
# Create a param converter struct to contain our conversion logic.
@[ADI::Register]
struct MultiplyConverter < ART::ParamConverterInterface
# :inherit:
def apply(request : HTTP::Request, configuration : Configuration) : Nil
arg_name = configuration.name
# No need to continue if the request does not have a value for this argument.
# The converter could also be setup to only set a value if it hasn't been set already.
return unless request.attributes.has? arg_name
# Retieve the argument from the request's attributes as an Int32.
# Converters should also handle any errors that may occur,
# such as type conversion, validation, or business logic errors.
value = request.attributes.get arg_name, Int32
# Override the argument's value within the request attributes, restricted to `Int32` values.
request.attributes.set arg_name, value * 2, Int32
end
end
class ParamConverterController < ART::Controller
# Use the ART::ParamConverter annotation to specify we want to use a param converter for the `num` argument, and that we want to use the `MultiplyConverter` for the conversion.
@[ART::Get(path: "/multiply/:num")]
@[ART::ParamConverter("num", converter: MultiplyConverter)]
def multiply(num : Int32) : Int32
num
end
end
ART.run
# GET /multiply/3 # => 6
Additional Configuration
By default, the configuration argument to #apply
contains the name of the argument that should be converted, and a reference to the class of self
.
However, it can be augmented with additional data by using the ART::ParamConverterInterface.configuration
macro.
For example, lets enhance the previous example to allow specifying the multiplier, versus it being hard-coded as 2
.
require "athena"
@[ADI::Register]
struct MultiplyConverter < ART::ParamConverterInterface
# Use the `configuration` macro to define the configuration object that `self` should use.
# Adds an additional argument to allow specifying the multiplier.
#
# Configuration data can be made optional by setting default values.
configuration by : Int32
# :inherit:
def apply(request : HTTP::Request, configuration : Configuration) : Nil
arg_name = configuration.name
return unless request.attributes.has? arg_name
value = request.attributes.get arg_name, Int32
# Use the multiplier from the configuration object.
request.attributes.set arg_name, value * configuration.by, Int32
end
end
class ParamConverterController < ART::Controller
# Specify the multiplier to use for the conversion; in this case `4`.
@[ART::Get(path: "/multiply/:num")]
@[ART::ParamConverter("num", converter: MultiplyConverter, by: 4)]
def multiply(num : Int32) : Int32
num
end
end
ART.run
# GET /multiply/3 # => 12
Direct Known Subclasses
Defined in:
param_converter_interface.crConstant Summary
-
TAG =
"athena.param_converter"
-
The tag name to apply to
self
in order for it to be registered withART::Listeners::ParamConverter
.
Constructors
Instance Method Summary
-
#apply(request : HTTP::Request, configuration : Configuration) : Nil
Applies the conversion logic based on the provided request and configuration.
- #initialize
Macro Summary
-
configuration(*args)
Helper macro for defining an
ART::ParamConverterInterface::ConfigurationInterface
; similar to therecord
macro.
Constructor Detail
Instance Method Detail
Applies the conversion logic based on the provided request and configuration.
Most commonly this involves setting/overriding a value stored in the request's ART::ParameterBag
via request.attributes
.
Macro Detail
Helper macro for defining an ART::ParamConverterInterface::ConfigurationInterface
; similar to the record
macro.
Accepts a variable amount of variable names, types, and optionally default values.
See the Additional Configuration example for more information.