Skip to content

Commit

Permalink
Merge pull request #6 from leikir/develop
Browse files Browse the repository at this point in the history
v1
  • Loading branch information
Fabien authored Jul 16, 2018
2 parents 9d9a14a + 8330477 commit 01ba6a4
Show file tree
Hide file tree
Showing 25 changed files with 650 additions and 130 deletions.
46 changes: 46 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
version: 2
jobs:
build:
docker:
- image: circleci/ruby:2.5.1
working_directory: ~/http_forwarder

steps:
- checkout

# Download and cache dependencies
- restore_cache:
keys:
- v1-dependencies-{{ checksum "Gemfile.lock" }}
# fallback to using the latest cache if no exact match is found
- v1-dependencies-

- run:
name: install dependencies
command: |
bundle install --jobs=4 --retry=3 --path vendor/bundle
- save_cache:
paths:
- ./vendor/bundle
key: v1-dependencies-{{ checksum "Gemfile.lock" }}

# run tests!
- run:
name: run tests
command: |
mkdir /tmp/test-results
TEST_FILES="$(circleci tests glob "spec/**/*_spec.rb" | circleci tests split --split-by=timings)"
bundle exec rspec --format progress \
--format RspecJunitFormatter \
--out /tmp/test-results/rspec.xml \
--format progress \
$TEST_FILES
# collect reports
- store_test_results:
path: /tmp/test-results
- store_artifacts:
path: /tmp/test-results
destination: test-results
13 changes: 13 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# http://editorconfig.org
root = true

[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

[*.md]
trim_trailing_whitespace = false
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@
/spec/dummy/log/
/spec/reports/
/tmp/
.byebug_history
2 changes: 2 additions & 0 deletions .rspec
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
--require spec_helper
--format documentation
--color
93 changes: 93 additions & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# List of all cops and their description/default values is available here:
# https://github.com/bbatsov/rubocop/blob/master/manual/cops.md

AllCops:
TargetRubyVersion: 2.5

# ==================================== Department Bundler ==========================================

Bundler/OrderedGems:
Enabled: true

# ===================================== Department Layout ==========================================

Layout/AlignParameters:
EnforcedStyle: with_fixed_indentation

Layout/CaseIndentation:
EnforcedStyle: end

Layout/DotPosition:
EnforcedStyle: trailing

Layout/EmptyLinesAroundClassBody:
EnforcedStyle: no_empty_lines
SupportedStyles:
- empty_lines
- no_empty_lines

Layout/EmptyLinesAroundModuleBody:
EnforcedStyle: no_empty_lines
SupportedStyles:
- empty_lines
- no_empty_lines

Layout/EmptyLinesAroundBlockBody:
Description: "Keeps track of empty lines around block bodies."
Enabled: false

Layout/EmptyLines:
Description: "Don't use several empty lines in a row."
Enabled: true

Layout/EndOfLine:
Description: 'Use Unix-style line endings.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#crlf'
Enabled: true

Layout/ExtraSpacing:
# When true, allows most uses of extra spacing if the intent is to align
# things with the previous or next line, not counting empty lines or comment
# lines.
AllowForAlignment: true

Layout/MultilineOperationIndentation:
EnforcedStyle: indented

Layout/MultilineMethodCallIndentation:
EnforcedStyle: indented

# ==================================== Department Metrics ==========================================

Metrics/AbcSize:
Max: 15 # Default is 15

Metrics/LineLength:
Max: 100 # Default is 80
Exclude:
- config/schedule.rb

Metrics/MethodLength:
Max: 25 # Default is 10

Metrics/ParameterLists:
Max: 5 # Default is 5

# ===================================== Department Style ===========================================

Style/FrozenStringLiteralComment:
Enabled: false

Style/GlobalVars:
Description: 'Do not introduce global variables.'
StyleGuide: '#instance-vars'
Reference: 'http://www.zenspider.com/Languages/Ruby/QuickRef.html'
AllowedVariables:
- $rollout
- $redis
- $redis_cache
- $redis_rollout
Enabled: true

Style/StringLiterals:
EnforcedStyle: single_quotes
1 change: 1 addition & 0 deletions .ruby-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
2.5.1
14 changes: 14 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ PATH
remote: .
specs:
http_forwarder (0.1.0)
activesupport
http

GEM
Expand Down Expand Up @@ -52,11 +53,13 @@ GEM
public_suffix (>= 2.0.2, < 4.0)
arel (9.0.0)
builder (3.2.3)
byebug (10.0.2)
concurrent-ruby (1.0.5)
crack (0.4.3)
safe_yaml (~> 1.0.0)
crass (1.0.4)
diff-lcs (1.3)
docile (1.3.1)
domain_name (0.5.20180417)
unf (>= 0.0.5, < 1.0.0)
erubi (1.7.1)
Expand All @@ -74,6 +77,7 @@ GEM
http_parser.rb (0.6.0)
i18n (1.0.1)
concurrent-ruby (~> 1.0)
json (2.1.0)
loofah (2.2.2)
crass (~> 1.0.2)
nokogiri (>= 1.5.9)
Expand Down Expand Up @@ -135,7 +139,14 @@ GEM
rspec-mocks (~> 3.7.0)
rspec-support (~> 3.7.0)
rspec-support (3.7.1)
rspec_junit_formatter (0.4.1)
rspec-core (>= 2, < 4, != 2.12.0)
safe_yaml (1.0.4)
simplecov (0.16.1)
docile (~> 1.1)
json (>= 1.8, < 3)
simplecov-html (~> 0.10.0)
simplecov-html (0.10.2)
sprockets (3.7.2)
concurrent-ruby (~> 1.0)
rack (> 1, < 3)
Expand Down Expand Up @@ -163,10 +174,13 @@ PLATFORMS

DEPENDENCIES
bundler (~> 1.16)
byebug
http_forwarder!
rails
rake (~> 10.0)
rspec-rails
rspec_junit_formatter
simplecov
webmock

BUNDLED WITH
Expand Down
21 changes: 21 additions & 0 deletions LICENSE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2018 Leikir Web

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
115 changes: 104 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
# HttpForwarder
# About HttpForwarder
![Build Status](https://circleci.com/gh/leikir/http_forwarder.svg?style=shield)

Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/http_forwarder`. To experiment with that code, run `bin/console` for an interactive prompt.

TODO: Delete this and the text above, and describe your gem
HttpForwarder is a gem that lets you easily forward a request from your app to
a specified target. It also enables you to transform the request before doing so.
For example, it is very handy when it comes to service communications in a microservices architecture.

## Installation

Add this line to your application's Gemfile:

```ruby
gem 'http_forwarder'
gem 'http_forwarder', github: 'leikir/http_forwarder'
```

And then execute:
Expand All @@ -22,14 +23,106 @@ Or install it yourself as:

## Usage

TODO: Write usage instructions here
### Setup

Once you installed the gem, you have to include it in the controller you want to use it in:

```ruby
include HttpForwarder::Forwarder
```

Then you need to set up your routes in a new file `config/initializers/forwarder.rb` like
this:

```ruby
HttpForwarder::Forwarder.configure do |config|
config.router.forward(:dogs).on(:create).to('http://doggy.woof')
config.router.forward(:dogs).on(:index).to('http://doggos.woof')
config.router.forward(:cats).to('http://kittykitty.miaw')
end
```
The argument of the method `forward()`is your controller name, the argument of the method `on()` is your method name and the argument of the method `to()` is the target you want to forward to. For example, in the example above, the method `create` of the dogs controller redirects the request to `http://doggy.woof`.
It is mandatory to specify the controller and the target, whereas if you don't specify the action it will assume that all your controller methods redirect to the same url. In the example above, all the cats controller actions will redirect to `http://kittykitty.miaw`.

### Forwarding

#### Forwarding without modification

If you want to forward the request and render the response without any modification whatsoever, simply user the `forward_and_render` method:

```ruby
def index
forward_and_render
end
```

## Development
It will forward to your configured domain, with the same path as in input.

After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
Examples:
- `:get, http://my-dogs.mine/4` => `:get, http://doggy.woof/4`
- `:post, http://my-cats.meow` => `:post, http://kittykitty.miaw`

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](https://rubygems.org).
Modification is still possible, see below section.

#### Forwarding with response modification

If you want to manipulate the response, simply use the `forward` method, then manipulate the response object :

```ruby
def update
response = forward
parsed_response = JSON.parse(response.body)
parsed_response['data']['name'] = 'droopy'
render json: parsed_response, status: response.status
end
```

#### Modifying the request before forwarding

Sometimes you might want to change the arriving request before forwarding it. To do so, you can pass a proc to our forward method to make the changes you want :

```ruby
class DogsController < ApplicationController

include HttpForwarder::Forwarder

def create
response_from_other_api = forward do |body, _path, _headers|
body = JSON.parse(body)
body['data']['name'] = 'rex'
@body = body.to_json
end
render_response(response_from_other_api)
end
end
```

In the example above we updated a json `body` to alter a key inside it.
We didn't modify the `path` or `headers` so we could have went for:
```ruby
# modify only body
forward do |body|
...
# modify only path
forward do |_body, path|
...
# modify only body and headers
forward do |body, _path, headers|
end
```
**To effectively modify the variable inside the block you must assign value to the instance variable**
```ruby
@body = body.to_json

@body = ''

@body = 'nil'

@path = '/api/another/path'

@headers = headers.select { |header| header == 'Content-Type'}
```

## Contributing
## Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/http_forwarder.
Bug reports and pull requests are welcome on GitHub at https://github.com/leikir/http_forwarder.
Loading

0 comments on commit 01ba6a4

Please sign in to comment.