Add media types supported deserialization using your favourite deserializer, and (when supported and provided) media type validation.
This library will nog longer receive updates because it has been completely obsoleted by changes in the media-types-serialization
. That library now takes care of both input and output.
Add this line to your application's Gemfile:
gem 'media_types-deserialization'
And then execute:
$ bundle
Or install it yourself as:
$ gem install media_types-deserialization
All logic lives in the MediaTypes::Deserialization
and the main method you'll use is media_type_params
. This works
very similarly as params
in Rack
(and therefore Rails
) applications, but only gives back what the implicit or
explicit deserializer gives back.
require 'media_types/deserialization'
class BaseController
include MediaTypes::Deserialization
rescue_from ContentFormatError, with: :bad_request # 400
rescue_from ContentTypeNotRecognised, with: :unsupported_media_type # 415
rescue_from ContentDoesNotMatchContentType, with: :unprocessable_entity # 422
end
If you don't provide the lookup_content_type_symbol
configuration, it requires 'action_dispatch/http/mime_type'
to
be present in order to look-up the content type symbol. This is true for Rails
applications by default.
MediaTypes::Deserialization.configure do
self.lookup_content_type_symbol = lambda do |content_type|
# For example use a lookup map
KNOWN_CONTENT_TYPES_TO_SYMBOL[content_type]
# Or alternatively use matching
content_type.include?('json') ? :json : nil
end
end
See below if you're using the media_types
gem.
If you don't provide the lookup_deserializer_by_symbol
configuration, it currently can only deserialize json
and
will only do so if the symbol is :json
, requiring oj
. If you don't want this behaviour, define it.
MediaTypes::Deserialization.configure do
self.lookup_deserializer_by_symbol = lambda do |symbol|
case symbol
when :json
return CustomJsonDeserializer
when :xml
when :html
when :xhtml
return CustomXmlDeserializer
else
nil
end
end
end
If you want media type validation, for example via the media_types
gem, provide the lookup_media_type_by_symbol
option and return the media types. The easiest way to accomplish this is tracking your registerables when you register
the media types, and creating a Lookup Map like so:
# In some initializer that defines the media types,
# given a module MyDomain::MediaTypes which holds many media types
require 'my_domain/media_types'
require 'media_types/integrations/actionpack'
registerables = []
MyDomain::MediaTypes.module_exec do
registerables.concat self::Author.register
registerables.concat self::Book.register
registerables.concat self::Configuration.register
registerables.concat self::Errors.register
registerables.concat self::Signature.register
# Create lookup table by string (content-type) => media type
lookup = registerables.flatten.each_with_object({}) do |registerable, hash|
[registerable.media_type, *registerable.aliases].each do |type|
hash[String(type)] = registerable
end
end.freeze
# Create lookup table by symbol => media_type
lookup_by_symbol = registerables.flatten.each_with_object({}) do |registerable, hash|
hash[String(registerable.symbol).to_sym] = registerable
end.freeze
const_set(:LOOKUP, lookup)
const_set(:LOOKUP_BY_SYMBOL, lookup_by_symbol)
end
At this point you can re-use those lookup tables for both the media type lookup and the symbol lookup:
MediaTypes::Deserialization.configure do
self.lookup_content_type_symbol = lambda do |content_type|
registerable = MyDomain::MediaTypes.const_get(:Lookup).fetch(content_type) { nil }
registerable&.symbol
end
self.lookup_media_type_by_symbol = lambda do |symbol|
registerable = MyDomain::MediaTypes.const_get(:LOOKUP_BY_SYMBOL).fetch(symbol) { nil }
registerable&.media_type
end
end
MediaTypes
: 💎 Library to create media type definitions, schemes and validationsMediaTypes::Serialization
: 🌀 Add media types supported serialization using your favourite serializerMediaTypes::Validation
: ❗ Response validations according to a media-type
After checking out the repo, run bin/setup
to install dependencies. Then, run rake test
to run the tests. You can
also run bin/console
for an interactive prompt that will allow you to experiment.
To install this gem onto your local machine, run bundle exec rake install
. To release a new version, update the
version number in version.rb
, and then run bundle exec rake release
, which will create a git tag for the version,
push git commits and tags, and push the .gem
file to rubygems.org.
Bug reports and pull requests are welcome on GitHub at XPBytes/media_types-deserialization.