web_pipe 0.13.0 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +4 -1
- data/CHANGELOG.md +29 -0
- data/Gemfile +2 -2
- data/README.md +18 -11
- data/docs/building_a_rack_application.md +1 -1
- data/docs/composing_applications.md +4 -4
- data/docs/connection_struct/configuring_the_connection_struct.md +4 -4
- data/docs/connection_struct/halting_the_pipe.md +17 -19
- data/docs/connection_struct/sharing_data_downstream.md +9 -8
- data/docs/connection_struct.md +22 -19
- data/docs/design_model.md +10 -9
- data/docs/dsl_free_usage.md +85 -14
- data/docs/extensions/container.md +9 -10
- data/docs/extensions/cookies.md +4 -2
- data/docs/extensions/dry_schema.md +5 -4
- data/docs/extensions/flash.md +9 -11
- data/docs/extensions/{dry_view.md → hanami_view.md} +20 -22
- data/docs/extensions/not_found.md +40 -0
- data/docs/extensions/params.md +6 -4
- data/docs/extensions/rails.md +31 -38
- data/docs/extensions/redirect.md +5 -4
- data/docs/extensions/router_params.md +5 -5
- data/docs/extensions/session.md +4 -4
- data/docs/extensions/url.md +6 -6
- data/docs/extensions.md +5 -6
- data/docs/introduction.md +7 -7
- data/docs/plugging_operations/composing_operations.md +3 -3
- data/docs/plugging_operations/injecting_operations.md +4 -4
- data/docs/plugging_operations/inspecting_operations.md +24 -0
- data/docs/plugging_operations/resolving_operations.md +3 -3
- data/docs/plugging_operations.md +3 -3
- data/docs/plugs/config.md +1 -1
- data/docs/plugs/content_type.md +2 -1
- data/docs/plugs.md +6 -7
- data/docs/recipes/hanami_2_and_dry_rb_integration.md +12 -0
- data/docs/recipes/hanami_router_integration.md +3 -1
- data/docs/recipes/using_all_restful_methods.md +6 -5
- data/docs/testing.md +64 -0
- data/docs/using_rack_middlewares/composing_middlewares.md +2 -3
- data/docs/using_rack_middlewares/injecting_middlewares.md +6 -6
- data/docs/using_rack_middlewares/inspecting_middlewares.md +35 -0
- data/docs/using_rack_middlewares.md +6 -6
- data/lib/web_pipe/app.rb +22 -25
- data/lib/web_pipe/conn.rb +0 -1
- data/lib/web_pipe/conn_support/builder.rb +0 -7
- data/lib/web_pipe/conn_support/composition.rb +3 -26
- data/lib/web_pipe/conn_support/errors.rb +5 -5
- data/lib/web_pipe/conn_support/headers.rb +1 -50
- data/lib/web_pipe/conn_support/types.rb +3 -3
- data/lib/web_pipe/dsl/builder.rb +10 -19
- data/lib/web_pipe/dsl/class_context.rb +15 -40
- data/lib/web_pipe/dsl/instance_context.rb +53 -0
- data/lib/web_pipe/extensions/container/container.rb +2 -15
- data/lib/web_pipe/extensions/cookies/cookies.rb +2 -31
- data/lib/web_pipe/extensions/dry_schema/dry_schema.rb +2 -56
- data/lib/web_pipe/extensions/flash/flash.rb +2 -32
- data/lib/web_pipe/extensions/hanami_view/hanami_view.rb +67 -0
- data/lib/web_pipe/extensions/not_found/not_found.rb +26 -0
- data/lib/web_pipe/extensions/params/params.rb +2 -63
- data/lib/web_pipe/extensions/rails/rails.rb +2 -123
- data/lib/web_pipe/extensions/redirect/redirect.rb +2 -20
- data/lib/web_pipe/extensions/router_params/router_params.rb +1 -39
- data/lib/web_pipe/extensions/session/session.rb +2 -25
- data/lib/web_pipe/extensions/url/url.rb +2 -5
- data/lib/web_pipe/pipe.rb +229 -0
- data/lib/web_pipe/plug.rb +31 -65
- data/lib/web_pipe/plugs/config.rb +0 -2
- data/lib/web_pipe/plugs/content_type.rb +0 -2
- data/lib/web_pipe/rack_support/app_with_middlewares.rb +3 -26
- data/lib/web_pipe/rack_support/middleware.rb +2 -2
- data/lib/web_pipe/rack_support/middleware_specification.rb +19 -48
- data/lib/web_pipe/test_support.rb +28 -0
- data/lib/web_pipe/types.rb +1 -3
- data/lib/web_pipe/version.rb +1 -1
- data/lib/web_pipe.rb +77 -17
- data/web_pipe.gemspec +1 -2
- metadata +16 -9
- data/docs/recipes/dry_rb_integration.md +0 -18
- data/lib/web_pipe/dsl/dsl_context.rb +0 -85
- data/lib/web_pipe/dsl/instance_methods.rb +0 -114
- data/lib/web_pipe/extensions/dry_view/dry_view.rb +0 -158
@@ -1,21 +1,23 @@
|
|
1
|
-
#
|
1
|
+
# Hanami View
|
2
2
|
|
3
|
-
This
|
4
|
-
|
5
|
-
|
3
|
+
This extension currently works with `hanami-view` v2.0.0.alpha2, which is not
|
4
|
+
still released but available on the gem repository.
|
5
|
+
|
6
|
+
This extension integrates with [hanami-view](https://github.com/hanami/view)
|
7
|
+
rendering system to set a hanami-view output as the response body.
|
6
8
|
|
7
9
|
`WebPipe::Conn#view` method is at the core of this extension. In its basic
|
8
|
-
|
10
|
+
behavior, you provide to it a view instance you want to render and any
|
9
11
|
exposures or options it may need:
|
10
12
|
|
11
13
|
```ruby
|
12
14
|
require 'web_pipe'
|
13
|
-
require '
|
15
|
+
require 'hanami/view'
|
14
16
|
require 'my_context'
|
15
17
|
|
16
|
-
WebPipe.load_extensions(:
|
18
|
+
WebPipe.load_extensions(:hanami_view)
|
17
19
|
|
18
|
-
class SayHelloView <
|
20
|
+
class SayHelloView < Hanami::View
|
19
21
|
config.paths = [File.join(__dir__, '..', 'templates')]
|
20
22
|
config.template = 'say_hello'
|
21
23
|
config.default_context = MyContext
|
@@ -35,17 +37,16 @@ class MyApp
|
|
35
37
|
end
|
36
38
|
end
|
37
39
|
```
|
38
|
-
|
39
|
-
|
40
|
-
extension)[container.md]:
|
40
|
+
However, you can resolve a view from a container if you also use the
|
41
|
+
(`:container` extension)[container.md]:
|
41
42
|
|
42
43
|
```ruby
|
43
|
-
require '
|
44
|
+
require 'hanami_view'
|
44
45
|
require 'my_container'
|
45
46
|
require 'web_pipe'
|
46
47
|
require 'web_pipe/plugs/config'
|
47
48
|
|
48
|
-
WebPipe.load_extensions(:
|
49
|
+
WebPipe.load_extensions(:hanami_view, :container)
|
49
50
|
|
50
51
|
class MyApp
|
51
52
|
include WebPipe
|
@@ -61,20 +62,17 @@ class MyApp
|
|
61
62
|
end
|
62
63
|
```
|
63
64
|
|
64
|
-
As in a standard call to `
|
65
|
-
(`
|
66
|
-
possible to leverage configured default context while being able to inject
|
67
|
-
request specific data to it.
|
65
|
+
As in a standard call to `Hanami::View#call`, you can override the context
|
66
|
+
(`Hanami::View::Context`) to use through the `context:` option. However, it is still possible to leverage the configured default context while injecting specific data to it.
|
68
67
|
|
69
|
-
|
70
|
-
request specific data) to your
|
71
|
-
that is with [`dry-auto_inject`](https://dry-rb.org/gems/dry-auto_inject):
|
68
|
+
To work, you have to specify required dependencies (in this case,
|
69
|
+
request specific data) to your hanami-view's context. A very convenient way to do that is with [`dry-auto_inject`](https://dry-rb.org/gems/dry-auto_inject):
|
72
70
|
|
73
71
|
```ruby
|
74
|
-
require '
|
72
|
+
require 'hanami/view/context'
|
75
73
|
require 'my_import'
|
76
74
|
|
77
|
-
class MyContext <
|
75
|
+
class MyContext < Hanami::View::Context
|
78
76
|
include MyImport::Import[:current_path]
|
79
77
|
|
80
78
|
# Without `dry-auto_inject` you have to manually specify dependencies and
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# Not found
|
2
|
+
|
3
|
+
This extension helps to build a not-found response in a single method
|
4
|
+
invocation. The `WebPipe::Conn#not_found` method will:
|
5
|
+
|
6
|
+
- Set 404 as response status.
|
7
|
+
- Set 'Not found' as the response body, or instead run a step configured in
|
8
|
+
`:not_found_body_step` config key.
|
9
|
+
- Halt the connection struct.
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
require 'web_pipe'
|
13
|
+
require 'web_pipe/plugs/config'
|
14
|
+
|
15
|
+
WebPipe.load_extensions(:params, :not_found)
|
16
|
+
|
17
|
+
class ShowItem
|
18
|
+
include 'web_pipe'
|
19
|
+
|
20
|
+
plug :config, WebPipe::Plugs::Config.(
|
21
|
+
not_found_body_step: ->(conn) { conn.set_response_body('Nothing') }
|
22
|
+
)
|
23
|
+
|
24
|
+
plug :fetch_item do |conn|
|
25
|
+
conn.add(:item, Item[params['id']])
|
26
|
+
end
|
27
|
+
|
28
|
+
plug :check_item do |conn|
|
29
|
+
if conn.fetch(:item)
|
30
|
+
conn
|
31
|
+
else
|
32
|
+
conn.not_found
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
plug :render do |conn|
|
37
|
+
conn.set_response_body(conn.fetch(:item).name)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
```
|
data/docs/extensions/params.md
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
# Params
|
2
2
|
|
3
3
|
This extension adds a `WebPipe::Conn#params` method which returns
|
4
|
-
request parameters as a Hash
|
5
|
-
|
4
|
+
request parameters as a Hash. Then, any number of transformations on it can be
|
5
|
+
configured.
|
6
6
|
|
7
|
-
When no transformations are configured, `#params`
|
7
|
+
When no transformations are configured, `#params` returns GET and POST
|
8
|
+
parameters as a hash:
|
8
9
|
|
9
10
|
```ruby
|
10
11
|
# http://www.example.com?foo=bar
|
@@ -102,7 +103,8 @@ plug(:this) do |conn|
|
|
102
103
|
end
|
103
104
|
# ...
|
104
105
|
```
|
105
|
-
Finally, you can override configured transformations injecting another set
|
106
|
+
Finally, you can override the configured transformations injecting another set
|
107
|
+
at the moment of calling `#params`:
|
106
108
|
|
107
109
|
```ruby
|
108
110
|
# ...
|
data/docs/extensions/rails.md
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
# Rails
|
2
2
|
|
3
|
-
The first two things to keep in mind
|
3
|
+
The first two things to keep in mind to integrate with Rails are
|
4
4
|
that `WebPipe` instances are Rack applications and that rails router can
|
5
|
-
perfectly [dispatch to a rack application](https://guides.rubyonrails.org/routing.html#routing-to-rack-applications).
|
5
|
+
perfectly [dispatch to a rack application](https://guides.rubyonrails.org/routing.html#routing-to-rack-applications).
|
6
6
|
|
7
7
|
```ruby
|
8
8
|
# config/routes.rb
|
@@ -22,31 +22,29 @@ class MyRoute
|
|
22
22
|
end
|
23
23
|
```
|
24
24
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
25
|
+
To do something like the previous example, you don't need to enable this
|
26
|
+
extension. Notice that rails dispatched the request to our `WebPipe` rack
|
27
|
+
application, which was then responsible for generating the response. In this
|
28
|
+
case, it used a simple call to `#set_response_body`.
|
29
29
|
|
30
30
|
It's quite possible that you don't need more than that in terms of rails
|
31
|
-
integration. Of course,
|
31
|
+
integration. Of course, you want something more elaborate to generate
|
32
32
|
responses. For that, you can use the view or template system you like. One
|
33
|
-
option that will play
|
34
|
-
[`
|
35
|
-
|
36
|
-
|
37
|
-
[extension](https://waiting-for-dev.github.io/web_pipe/docs/extensions/dry_view.html).
|
33
|
+
option that will play especially well here is
|
34
|
+
[`hanami-view`](https://github.com/hanami/view). Furthermore, we have a
|
35
|
+
tailored `hanami_view`
|
36
|
+
[extension](https://waiting-for-dev.github.io/web_pipe/docs/extensions/hanami_view.html).
|
38
37
|
|
39
|
-
You need to use `:rails` extension if:
|
38
|
+
You need to use the `:rails` extension if:
|
40
39
|
|
41
|
-
- You want to use `action_view` as rendering system.
|
42
|
-
- You want to use rails
|
40
|
+
- You want to use `action_view` as a rendering system.
|
41
|
+
- You want to use rails URL helpers from your `WebPipe` application.
|
43
42
|
- You want to use controller helpers from your `WebPipe` application.
|
44
43
|
|
45
|
-
Rails responsibilities for controlling the request/response cycle
|
46
|
-
rendering process
|
47
|
-
|
48
|
-
|
49
|
-
some behaviour for the view layer:
|
44
|
+
Rails' responsibilities for controlling the request/response cycle are coupled
|
45
|
+
to the rendering process. For this reason, even if you want to use `WebPipe`
|
46
|
+
applications instead of Rails controller actions you still have to use the
|
47
|
+
typical top `ApplicationController` to define some behavior for the view layer:
|
50
48
|
|
51
49
|
- Which layout is applied to the template.
|
52
50
|
- Which helpers will become available to the templates.
|
@@ -56,11 +54,11 @@ no layout is applied and only built-in helpers (for example,
|
|
56
54
|
`number_as_currency`) are available. You can change it via the
|
57
55
|
`:rails_controller` configuration option.
|
58
56
|
|
59
|
-
The main method that this extension adds to `WebPipe::Conn` is `#render`,
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
57
|
+
The main method that this extension adds to `WebPipe::Conn` is `#render`, which
|
58
|
+
delegates to the [Rails implementation]
|
59
|
+
(https://api.rubyonrails.org/v6.0.1/classes/ActionController/Renderer.html) as
|
60
|
+
you'd do in a typical rails controller. Remember that you can provide template
|
61
|
+
instance variables through the keyword `:assigns`.
|
64
62
|
|
65
63
|
```ruby
|
66
64
|
# config/routes.rb
|
@@ -93,10 +91,10 @@ end
|
|
93
91
|
```
|
94
92
|
|
95
93
|
Notice that we used the keyword `template:` instead of taking advantage of
|
96
|
-
automatic template lookup. We did that way so that we don't have to create
|
97
|
-
|
98
|
-
`ArticlesController
|
99
|
-
|
94
|
+
automatic template lookup. We did that way so that we don't have to create an
|
95
|
+
`ArticlesController`, but it's up to you. In the case of having an
|
96
|
+
`ArticlesController`, we could do `conn.render(:index, assigns: { articles:
|
97
|
+
Article.all })`.
|
100
98
|
|
101
99
|
Besides, this extension provides with two other methods:
|
102
100
|
|
@@ -105,12 +103,7 @@ Besides, this extension provides with two other methods:
|
|
105
103
|
- `helpers` returns the associated [controller
|
106
104
|
helpers](https://api.rubyonrails.org/classes/ActionController/Helpers.html).
|
107
105
|
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
Here you have a link to a very simple and contrived example of a rails
|
113
|
-
application integrating `web_pipe`:
|
114
|
-
|
115
|
-
https://github.com/waiting-for-dev/rails-web_pipe
|
116
|
-
|
106
|
+
We have placed `WebPipe` applications within `app/controllers/` directory in
|
107
|
+
all the examples. However, remember you can put them wherever you like as long
|
108
|
+
as you respect rails
|
109
|
+
[`autoload_paths`](https://guides.rubyonrails.org/autoloading_and_reloading_constants.html#autoload-paths).
|
data/docs/extensions/redirect.md
CHANGED
@@ -1,14 +1,15 @@
|
|
1
1
|
# Redirect
|
2
2
|
|
3
|
-
This extension helps
|
3
|
+
This extension helps create a redirect response.
|
4
4
|
|
5
5
|
Redirect responses consist of two pieces:
|
6
6
|
|
7
|
-
- `Location` response header with the URL to which browsers should
|
7
|
+
- The `Location` response header with the URL to which browsers should
|
8
|
+
redirect.
|
8
9
|
- A 3xx status code.
|
9
10
|
|
10
|
-
A `#redirect(location, code)` method is added to `WebPipe::Conn
|
11
|
-
care of both steps. `code` argument is optional, defaulting to `302`.
|
11
|
+
A `#redirect(location, code)` method is added to `WebPipe::Conn`, which takes
|
12
|
+
care of both steps. The `code` argument is optional, defaulting to `302`.
|
12
13
|
|
13
14
|
```ruby
|
14
15
|
require 'web_pipe'
|
@@ -1,12 +1,12 @@
|
|
1
1
|
# Router params
|
2
2
|
|
3
|
-
This extension can be used
|
3
|
+
This extension can be used to merge placeholder parameters
|
4
4
|
that usually routers support (like `get /users/:id`) to the parameters hash
|
5
|
-
added through [`:params` extension](params.md) (which is
|
6
|
-
automatically loaded).
|
5
|
+
added through the [`:params` extension](params.md) (which is
|
6
|
+
automatically loaded if using `:router_params`).
|
7
7
|
|
8
|
-
|
9
|
-
|
8
|
+
This extension adds a transformation function named `:router_params`to the
|
9
|
+
registry. Internally, it merges what is present in rack env's
|
10
10
|
`router.params` key.
|
11
11
|
|
12
12
|
It automatically integrates with
|
data/docs/extensions/session.md
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
# Session
|
2
2
|
|
3
|
-
Wrapper around `Rack::Session` middleware to help
|
4
|
-
|
3
|
+
Wrapper around `Rack::Session` middleware to help work with sessions in your
|
4
|
+
plugged operations.
|
5
5
|
|
6
|
-
It depends on `Rack::Session` middleware, which is shipped by rack.
|
6
|
+
It depends on the `Rack::Session` middleware, which is shipped by rack.
|
7
7
|
|
8
|
-
It adds following methods to `WebPipe::Conn`:
|
8
|
+
It adds the following methods to `WebPipe::Conn`:
|
9
9
|
|
10
10
|
- `#fetch_session(key)`, `#fetch_session(key, default)` or
|
11
11
|
`#fetch_session(key) { default }`. Returns what is stored under
|
data/docs/extensions/url.md
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
# URL
|
2
2
|
|
3
|
-
`:url` extension
|
4
|
-
|
3
|
+
The `:url` extension adds a few methods that process the raw URL information
|
4
|
+
into something more digestable.
|
5
5
|
|
6
6
|
Specifically, it adds:
|
7
7
|
|
8
|
-
- `#base_url`:
|
9
|
-
- `#path`:
|
10
|
-
- `#full_path`:
|
11
|
-
- `#url`:
|
8
|
+
- `#base_url`: That's schema + host + port (unless it is the default for the scheme). E.g. `'https://example.org'` or `'http://example.org:8000'`.
|
9
|
+
- `#path`: That's script name (if any) + path information. E.g. `'index.rb/users/1'` or `'users/1'`.
|
10
|
+
- `#full_path`: That's path + query string (if any). E.g. `'users/1?view=table'`.
|
11
|
+
- `#url`: That's base url + full path. E.g. `'http://example.org:8000/users/1?view=table'`.
|
data/docs/extensions.md
CHANGED
@@ -1,12 +1,11 @@
|
|
1
1
|
# Extensions
|
2
2
|
|
3
|
-
`WebPipe::Conn` features are by default
|
4
|
-
|
5
|
-
|
6
|
-
want to use.
|
3
|
+
`WebPipe::Conn` features are bare-bones by default: the very minimal you need
|
4
|
+
to be able to build a web application. However, there are several extensions to
|
5
|
+
add just the ingredients you want to use progressively.
|
7
6
|
|
8
|
-
|
9
|
-
|
7
|
+
To load the extensions, you have to call `#load_extensions` method in
|
8
|
+
`WebPipe`:
|
10
9
|
|
11
10
|
```ruby
|
12
11
|
WebPipe.load_extensions(:params, :cookies)
|
data/docs/introduction.md
CHANGED
@@ -6,10 +6,10 @@ It means that with it and a rack router (like
|
|
6
6
|
[`hanami-router`](https://github.com/hanami/router),
|
7
7
|
[`http_router`](https://github.com/joshbuddy/http_router) or plain
|
8
8
|
[rack](https://github.com/rack/rack) routing methods you can build a complete
|
9
|
-
web application. However, the idea behind `web_pipe` is
|
10
|
-
component within a web framework. For this reason, it plays
|
11
|
-
with [dry-rb](https://dry-rb.org/) ecosystem. If it helps, you
|
12
|
-
as a decoupled web controller (as the C in MVC).
|
9
|
+
web application. However, the idea behind `web_pipe` is for it to be a
|
10
|
+
decoupled component within a web framework. For this reason, it plays
|
11
|
+
extremely well with [dry-rb](https://dry-rb.org/) ecosystem. If it helps, you
|
12
|
+
can think of it as a decoupled web controller (as the C in MVC).
|
13
13
|
|
14
14
|
`web_pipe` applications are built as a [pipe of
|
15
15
|
operations](design_model.md) on an [immutable
|
@@ -28,9 +28,9 @@ Following there is a simple example. It is a web application that will check
|
|
28
28
|
the value of a `user` parameter. When it is `Alice` or `Joe`, it will kindly
|
29
29
|
say hello. Otherwise, it will unauthorize:
|
30
30
|
|
31
|
-
>
|
32
|
-
|
33
|
-
will be available
|
31
|
+
> To try this example, you can paste it to a file with the name `config.ru` and
|
32
|
+
launch the rack command `rackup` within the same directory. The application
|
33
|
+
will be available at `http://localhost:9292`.
|
34
34
|
|
35
35
|
```ruby
|
36
36
|
require 'web_pipe'
|
@@ -5,9 +5,9 @@ and returning a connection struct. As a result, a composition of operations is
|
|
5
5
|
an operation in itself (as it also takes a connection struct and returns a
|
6
6
|
connection struct).
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
composition of all operations for given application.
|
8
|
+
We can leverage that to plug a whole `web_pipe` application as an operation to
|
9
|
+
another application. By doing so, you are plugging an operation which is the
|
10
|
+
composition of all operations for a given application.
|
11
11
|
|
12
12
|
```ruby
|
13
13
|
class HtmlApp
|
@@ -1,12 +1,12 @@
|
|
1
1
|
# Injecting operations
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
You can inject operations at the moment an application is initialized. It
|
4
|
+
allows you to override what the definition declares.
|
5
5
|
|
6
6
|
To this effect, you must use `plugs:` keyword argument. It must be a hash where
|
7
|
-
operations are matched by the name you gave them in its definition.
|
7
|
+
the operations are matched by the name you gave them in its definition.
|
8
8
|
|
9
|
-
|
9
|
+
That is mainly useful for testing purposes, where you can switch a heavy
|
10
10
|
operation and use another lighter one.
|
11
11
|
|
12
12
|
In the following example, the response body of the application will be
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# Inspecting operations
|
2
|
+
|
3
|
+
Once a `WebPipe` class is initialized, all its operations get resolved. It
|
4
|
+
happens because they are whether [resolved](resolving_operations.md) or
|
5
|
+
[injected](injecting_operations.md). The final result can be accessed through
|
6
|
+
the `#operations` method:
|
7
|
+
|
8
|
+
```ruby
|
9
|
+
require 'web_pipe'
|
10
|
+
require 'web_pipe/conn_support/builder'
|
11
|
+
|
12
|
+
class MyApp
|
13
|
+
include WebPipe
|
14
|
+
|
15
|
+
plug(:hello) do |conn|
|
16
|
+
conn.set_response_body('Hello world!')
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
app = MyApp.new
|
21
|
+
conn = WebPipe::ConnSupport::Builder.call(Rack::MockRequest.env_for)
|
22
|
+
new_conn = app.operations[:hello].call(con)
|
23
|
+
conn.response_body #=> ['Hello world!']
|
24
|
+
```
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# Resolving operations
|
2
2
|
|
3
|
-
There are several ways you can specify how an operation
|
3
|
+
There are several ways you can specify how to resolve an operation.
|
4
4
|
|
5
5
|
## Instance method
|
6
6
|
|
@@ -53,8 +53,8 @@ end
|
|
53
53
|
Operations can be resolved from a dependency injection container.
|
54
54
|
|
55
55
|
A container is anything that responds to `#[]` (accepting `Symbol` or `String`
|
56
|
-
as argument)
|
57
|
-
moment `WebPipe` module
|
56
|
+
as argument) to resolve a dependency. It can be configured at the
|
57
|
+
moment you include the `WebPipe` module:
|
58
58
|
|
59
59
|
```ruby
|
60
60
|
MyContainer = Hash[
|
data/docs/plugging_operations.md
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
# Plugging operations
|
2
2
|
|
3
|
-
You can plug operations
|
3
|
+
You can plug operations into your application with the DSL method `plug`. The
|
4
4
|
first argument it always takes is a symbol with the name you want
|
5
5
|
to give to the operation (which is needed to allow
|
6
|
-
[injection](plugging_operations/injecting_operations.md)
|
7
|
-
initialization).
|
6
|
+
[injection](plugging_operations/injecting_operations.md) at
|
7
|
+
initialization time).
|
8
8
|
|
9
9
|
```ruby
|
10
10
|
class MyApp
|
data/docs/plugs/config.md
CHANGED
data/docs/plugs/content_type.md
CHANGED
data/docs/plugs.md
CHANGED
@@ -1,13 +1,12 @@
|
|
1
1
|
# Plugs
|
2
2
|
|
3
|
-
Some
|
3
|
+
Some groups of operations can be generalized as following the same pattern. For
|
4
4
|
example, an operation setting `Content-Type` header to `text/html` is very
|
5
|
-
similar to
|
6
|
-
|
7
|
-
|
8
|
-
functions.
|
5
|
+
similar to setting the same header to `application/json`. We name plugs to this
|
6
|
+
level of abstraction on top of operations: plugs are operation builders. In
|
7
|
+
other words, they are higher-order functions that return functions.
|
9
8
|
|
10
|
-
Being just functions, we take as convention that plugs respond to `#call`
|
11
|
-
|
9
|
+
Being just functions, we take as a convention that plugs respond to `#call` to
|
10
|
+
create an operation.
|
12
11
|
|
13
12
|
This library ships with some useful plugs.
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# Hanami 2 and dry-rb integration
|
2
|
+
|
3
|
+
`web_pipe` has been designed to integrate smoothly with
|
4
|
+
the [hanami](https://hanamirb.org/) & [dry-rb](https://dry-rb.org/) ecosystems. It shares the same design
|
5
|
+
principles, and it ships with some extensions that even make this
|
6
|
+
integration painless (like [`:dry-schema`](../extensions/dry_schema.md)
|
7
|
+
extension or [`:hanami_view`](../extensions/hanami_view.md)).
|
8
|
+
|
9
|
+
If you want to use `web_pipe` within a hanami 2 application, you can take
|
10
|
+
inspiration from this sample todo app:
|
11
|
+
|
12
|
+
https://github.com/waiting-for-dev/hanami_2_web_pipe_todo_app
|
@@ -22,4 +22,6 @@ end
|
|
22
22
|
run router
|
23
23
|
```
|
24
24
|
|
25
|
-
|
25
|
+
To perform [string matching with
|
26
|
+
variables](https://github.com/hanami/router#string-matching-with-variables) you
|
27
|
+
just need to load [`:router_params` extension](../extensions/router_params.md).
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# Using all RESTful methods
|
2
2
|
|
3
|
-
As you probably know,
|
3
|
+
As you probably know, most browsers don't support some RESTful
|
4
4
|
methods like `PATCH` or `PUT`. [Rack's `MethodOverride`
|
5
5
|
middleware](https://github.com/rack/rack/blob/master/lib/rack/method_override.rb)
|
6
6
|
provides a workaround for this limitation, allowing to override
|
@@ -9,12 +9,13 @@ request method in rack's env if a magical `_method` parameter or
|
|
9
9
|
|
10
10
|
You have to be aware that if you use this middleware within a
|
11
11
|
`web_pipe` application (through [`use` DSL
|
12
|
-
method](../using_rack_middlewares.md)) it will have no effect.
|
13
|
-
When your `web_pipe` application takes control of the request it
|
14
|
-
has already gone through the router, which is the one
|
12
|
+
method](../using_rack_middlewares.md)), it will have no effect.
|
13
|
+
When your `web_pipe` application takes control of the request, it
|
14
|
+
has already gone through the router, which is the one that should
|
15
15
|
read the request method set by rack.
|
16
16
|
|
17
|
-
The solution for this is
|
17
|
+
The solution for this is straightforward. Just use `MethodOverride` middleware
|
18
|
+
before your router does its work. For example, in `config.ru`:
|
18
19
|
|
19
20
|
```ruby
|
20
21
|
# config.ru
|
data/docs/testing.md
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
# Testing
|
2
|
+
|
3
|
+
## Testing the rack application
|
4
|
+
|
5
|
+
A `WebPipe` instance is a just a rack application, so you can test it as such:
|
6
|
+
|
7
|
+
```ruby
|
8
|
+
require 'web_pipe'
|
9
|
+
require 'rack/mock'
|
10
|
+
require 'rspec'
|
11
|
+
|
12
|
+
class MyApp
|
13
|
+
include WebPipe
|
14
|
+
|
15
|
+
plug :response
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def response(conn)
|
20
|
+
conn
|
21
|
+
.set_response_body('Hello!')
|
22
|
+
.set_status(200)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
RSpec.describe MyApp do
|
27
|
+
it 'responds with 200 status code' do
|
28
|
+
env = Rack::MockRequest.env_for
|
29
|
+
|
30
|
+
status, _headers, _body = described_class.new.call(env)
|
31
|
+
|
32
|
+
expect(status).to be(200)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
```
|
36
|
+
|
37
|
+
## Testing individual operations
|
38
|
+
|
39
|
+
Each operation in a pipe is an isolated function that takes a connection struct
|
40
|
+
as argument. You can leverage [the inspection of
|
41
|
+
operations](docs/plugging_operations/inspecting_operations.md) to unit test them.
|
42
|
+
|
43
|
+
There's also a `WebPipe::TestSupport` module that you can include to get a
|
44
|
+
helper method `#build_conn` to easily create a connection struct.
|
45
|
+
|
46
|
+
```ruby
|
47
|
+
RSpec.describe MyApp do
|
48
|
+
include WebPipe::TestSupport
|
49
|
+
|
50
|
+
describe '#response' do
|
51
|
+
it 'responds with 200 status code' do
|
52
|
+
conn = build_conn
|
53
|
+
operation = described_class.new.operations[:response]
|
54
|
+
|
55
|
+
new_conn = operation.call(conn)
|
56
|
+
|
57
|
+
expect(new_conn.status).to be(200)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
```
|
62
|
+
|
63
|
+
Check the API documentation for the options you can provide to
|
64
|
+
[`#build_conn`](https://www.rubydoc.info/github/waiting-for-dev/web_pipe/master/WebPipe/TestSupport#build_conn).
|
@@ -3,9 +3,8 @@
|
|
3
3
|
In a similar way that you compose plugged operations, you can also compose rack
|
4
4
|
middlewares from another application.
|
5
5
|
|
6
|
-
For that, you just need to `use` another application.
|
7
|
-
|
8
|
-
they had there.
|
6
|
+
For that, you just need to `use` another application. All the middlewares for
|
7
|
+
that application will be added to the stack in the same order.
|
9
8
|
|
10
9
|
```ruby
|
11
10
|
class HtmlApp
|