From ff4ea5fc4c7bd1c5585832e970db268298f47cf6 Mon Sep 17 00:00:00 2001 From: Lawrence Chou Date: Thu, 19 Nov 2020 23:10:52 +0800 Subject: [PATCH] Configurable to skip certain paths via `skip_paths` --- .../incoming_json_formatter.rb | 14 ++++++++------ .../incoming_params_formatter.rb | 8 +++++--- lib/json_key_transformer_middleware/middleware.rb | 14 ++++++++++++++ .../outgoing_json_formatter.rb | 2 ++ lib/json_key_transformer_middleware/railtie.rb | 1 + readme.md | 1 + 6 files changed, 31 insertions(+), 9 deletions(-) diff --git a/lib/json_key_transformer_middleware/incoming_json_formatter.rb b/lib/json_key_transformer_middleware/incoming_json_formatter.rb index fdd96b0..8626e4c 100644 --- a/lib/json_key_transformer_middleware/incoming_json_formatter.rb +++ b/lib/json_key_transformer_middleware/incoming_json_formatter.rb @@ -6,13 +6,15 @@ module JsonKeyTransformerMiddleware class IncomingJsonFormatter < Middleware def call(env) - object = Oj.load(env['rack.input'].read) - transformed_object = HashKeyTransformer.send(middleware_config.incoming_strategy, object, middleware_config.incoming_strategy_options) - result = Oj.dump(transformed_object, mode: :compat) + unless should_skip?(env) + object = Oj.load(env['rack.input'].read) + transformed_object = HashKeyTransformer.send(middleware_config.incoming_strategy, object, middleware_config.incoming_strategy_options) + result = Oj.dump(transformed_object, mode: :compat) - env['rack.input'] = StringIO.new(result) - # Rails uses this elsewhere to parse 'rack.input', it must be updated to avoid truncation - env['CONTENT_LENGTH'] = result.length.to_s + env['rack.input'] = StringIO.new(result) + # Rails uses this elsewhere to parse 'rack.input', it must be updated to avoid truncation + env['CONTENT_LENGTH'] = result.length.to_s + end @app.call(env) end diff --git a/lib/json_key_transformer_middleware/incoming_params_formatter.rb b/lib/json_key_transformer_middleware/incoming_params_formatter.rb index 650d3db..f57beab 100644 --- a/lib/json_key_transformer_middleware/incoming_params_formatter.rb +++ b/lib/json_key_transformer_middleware/incoming_params_formatter.rb @@ -6,9 +6,11 @@ module JsonKeyTransformerMiddleware class IncomingParamsFormatter < Middleware def call(env) - parsed_params = Rack::Utils.parse_nested_query(env['QUERY_STRING']) - transformed_params = HashKeyTransformer.send(middleware_config.incoming_strategy, parsed_params, middleware_config.incoming_strategy_options) - env['QUERY_STRING'] = Rack::Utils.build_nested_query(transformed_params) + unless should_skip?(env) + parsed_params = Rack::Utils.parse_nested_query(env['QUERY_STRING']) + transformed_params = HashKeyTransformer.send(middleware_config.incoming_strategy, parsed_params, middleware_config.incoming_strategy_options) + env['QUERY_STRING'] = Rack::Utils.build_nested_query(transformed_params) + end @app.call(env) end diff --git a/lib/json_key_transformer_middleware/middleware.rb b/lib/json_key_transformer_middleware/middleware.rb index ee153cf..2dfff8f 100644 --- a/lib/json_key_transformer_middleware/middleware.rb +++ b/lib/json_key_transformer_middleware/middleware.rb @@ -6,9 +6,23 @@ def initialize(app, middleware_config) @middleware_config = middleware_config end + protected + + def should_skip?(env) + middleware_config.skip_paths.any? do |skip_path| + case skip_path + when String + skip_path == env['PATH_INFO'] + when Regexp + skip_path.match? env['PATH_INFO'] + end + end + end + private attr_reader :app, :middleware_config + end end diff --git a/lib/json_key_transformer_middleware/outgoing_json_formatter.rb b/lib/json_key_transformer_middleware/outgoing_json_formatter.rb index 8decd01..d6693a2 100644 --- a/lib/json_key_transformer_middleware/outgoing_json_formatter.rb +++ b/lib/json_key_transformer_middleware/outgoing_json_formatter.rb @@ -8,6 +8,8 @@ class OutgoingJsonFormatter < Middleware def call(env) status, headers, body = @app.call(env) + return [status, headers, body] if should_skip?(env) + new_body = build_new_body(body) [status, headers, new_body] diff --git a/lib/json_key_transformer_middleware/railtie.rb b/lib/json_key_transformer_middleware/railtie.rb index ce4f7ef..0600cec 100644 --- a/lib/json_key_transformer_middleware/railtie.rb +++ b/lib/json_key_transformer_middleware/railtie.rb @@ -9,6 +9,7 @@ class Railtie < Rails::Railtie config.json_key_transformer_middleware.incoming_strategy_options = ActiveSupport::OrderedOptions.new config.json_key_transformer_middleware.outgoing_strategy = :transform_underscore_to_camel config.json_key_transformer_middleware.outgoing_strategy_options = ActiveSupport::OrderedOptions.new + config.json_key_transformer_middleware.skip_paths = [] config.app_middleware.insert_after(Rails::Rack::Logger, JsonKeyTransformerMiddleware::IncomingParamsFormatter, config.json_key_transformer_middleware) config.app_middleware.insert_after(Rails::Rack::Logger, JsonKeyTransformerMiddleware::IncomingJsonFormatter, config.json_key_transformer_middleware) diff --git a/readme.md b/readme.md index f2e2ff8..c6c6205 100644 --- a/readme.md +++ b/readme.md @@ -67,6 +67,7 @@ The Railtie provides these configuration options: * `incoming_strategy_options` - no options set by default. * `outgoing_strategy` - default value of `:transform_underscore_to_camel`. * `outgoing_strategy_options` - no options set by default. +* `skip_paths` - skip the transformation if HTTP request path matches. e.g. `[/^\/admin/, '/graphql']` Here is an example Rails initializer which turns on the `outgoing_strategy_options.keep_lead_underscore` option: