/olive_branch

Handle camel/snake/dash case conversion

Primary LanguageRubyMIT LicenseMIT

OliveBranch

Code Climate Build Status

This gem lets your API users pass in and receive camelCased or dash-cased keys, while your Rails app receives and produces snake_cased ones.

Install

  1. Add this to your Gemfile and then bundle install:
gem "olive_branch"
  1. Add this to config/applcation.rb:
config.middleware.use OliveBranch::Middleware

Use

Include a X-Key-Inflection header with values of camel, dash, or snake in your JSON API requests.

For more examples, see our blog post.

Optimizations and configuration

OliveBranch uses multi_json, which will choose the fastest available JSON parsing library and use that. Combined with Oj can speed things up and save ~20% rails response time.

The middleware can be initialized with custom camelize/dasherize implementations, so if you know you have a fixed size set of keys, you can save a considerable amount of time by providing a custom camelize that caches like so:

class FastCamel
  def self.camel_cache
    @camel_cache ||= {}
  end

  def self.camelize(string)
    camel_cache[string] ||= string.underscore.camelize(:lower)
  end
end


...

config.middleware.use OliveBranch::Middleware, camelize: FastCamel.method(:camelize)

A default inflection can be specified so you don't have to include the X-Key-Inflection header on every request.

config.middleware.use OliveBranch::Middleware, inflection: 'camel'

A benchmark of this compared to the standard implementation shows a saving of ~75% rails response times for a complex response payload, or a ~400% improvement, but there is a risk of memory usage ballooning if you have dynamic keys. You can make this method as complex as required, but keep in mind that it will end up being called a lot in a busy app, so it's worth thinking about how to do what you need in the fastest manner possible.

Filtering

Content type

It is also possible to include a custom content type check in the same manner

config.middleware.use OliveBranch::Middleware, content_type_check: -> (content_type) {
  content_type == "my/content-type"
}

Excluding URLs

Additionally you can define a custom check by passing a proc

For params transforming

config.middleware.use OliveBranch::Middleware, exclude_params: -> (env) {
  env['PATH_INFO'].match(/^\/do_not_transform/)
}

Or response transforming

config.middleware.use OliveBranch::Middleware, exclude_response: -> (env) {
  env['PATH_INFO'].match(/^\/do_not_transform/)
}

Troubleshooting

We've seen a few folks raise issues that inbound transformations are not taking place. This is often due to the fact that OliveBranch, by default, is only transforming keys when a request's Content-Type is application/json. If you would like to force inbound transformation on every request, you must define an override for the content_type_check functionality:

config.middleware.use OliveBranch::Middleware, content_type_check: -> (content_type) { true }

OliveBranch is released under the MIT License. See MIT-LICENSE for further details.


Code At Viget

Visit code.viget.com to see more projects from Viget.