This adds dry-types as a dependency to do runtime type-checking of
serialized response and filters. It will first attempt to coerce the
value, then raise an error if it cannot coerce or is still the wrong
time post-coercion.
Each attribute 'type' is really 4 different types: what we want for
reads, writes, filters, and tests. For example, filters should not
accept null by default, but serialization should accept null.
For tests, we want to assert the final value of DateTime is an iso8601
string, but for serialization we just want DateTime.
The best way to see the behavior of individual types is
spec/serialization_spec.rb and spec/filtering_spec.rb. The general
logic is "lean towards strict, and coerce only as a 'nice to have'".
One issue is that there isn't a common error class. dry-types itself
will sometimes raise ConstraintError, ArgumentError, or TypeError.
While we could rescue these and raise a general exception, it would come
at the cost of hiding real errors for custom types and add a level of
indirection when debugging. So I have chosen to leave as-is for now.
# Default types
attribute :foo, :string
attribute :foo, :integer
# BigDecimal vs Float
# Note json decimals must be strings to preserve precision!
attribute :foo, :decimal
attribute :foo, :float
attribute :foo, :boolean
attribute :foo, :date
attribute :foo, :datetime
attribute :foo, :hash
attribute :foo, :array
# All of these can be arrays
attribute :foo, :array_of_strings
attribute :foo, :array_of_floats
StatusType = Types::Strict::String.enum('draft', 'published', 'archived')
JsonapiCompliable::Types[:status] = StatusType # use for all
# or
JsonapiCompliable::Types[:status] = { read: StatusType, ... }
dry-types supports hash schemas as well for nested json attributes:
meta = Types::Hash.schema({
foo: Dry::Types['strict.string'],
bar: Dry::Types['strict.integer']
})
JsonapiCompliable::Types[:meta] = meta
attribute :foo, :meta
This adds
dry-types
as a dependency to do runtime type-checking of serialized response and filters. It will first attempt to coerce the value, then raise an error if it cannot coerce or is still the wrong time post-coercion.Each attribute 'type' is really 4 different types: what we want for reads, writes, filters, and tests. For example, filters should not accept
null
by default, but serialization should acceptnull
. For tests, we want to assert the final value of DateTime is an iso8601 string, but for serialization we just want DateTime.The best way to see the behavior of individual types is
spec/serialization_spec.rb
andspec/filtering_spec.rb
. The general logic is "lean towards strict, and coerce only as a 'nice to have'".One issue is that there isn't a common error class.
dry-types
itself will sometimes raiseConstraintError
,ArgumentError
, orTypeError
. While we could rescue these and raise a general exception, it would come at the cost of hiding real errors for custom types and add a level of indirection when debugging. So I have chosen to leave as-is for now.Override types:
Provide custom types:
dry-types
supports hash schemas as well for nested json attributes: