web_pipe 0.13.0 → 0.16.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b0a90514a384a44456634dd195280291d82ab67eb336f69904c0cdc6bc3518ba
|
4
|
+
data.tar.gz: b2a3295f82715c9bf128d971994667eda13095631349b7cb33e1ccb97777b7e8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b353968992c5d5f2d5952fe3ae55c1a2691e8c852e8dd72525b4fcbb6e35e5fe0741016cc362e1afcdfe217594bdc43adc182c46e752989006fe8a5cc6a694af
|
7
|
+
data.tar.gz: c5d206d3058b7bd83dc3b0634c97d77e0e21bfc1468e6745708e7eaffd8aef1d4c7467a49894de8161d2af1bfd212ce647a7858f61875ed3eabd784e4ed7a101
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -4,6 +4,35 @@ All notable changes to this project will be documented in this file.
|
|
4
4
|
The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
5
5
|
and this project adheres to [Semantic Versioning](http://semver.org/).
|
6
6
|
|
7
|
+
## [0.16.0] - 2021-11-07
|
8
|
+
### Added
|
9
|
+
- Extract the DSL as an optional convenience layer and introduce
|
10
|
+
`WebPipe::Pipe` as top abstraction.
|
11
|
+
[#47](https://github.com/waiting-for-dev/web_pipe/pull/47)
|
12
|
+
- Be able to plug anything responding to `#to_proc`.
|
13
|
+
[#47](https://github.com/waiting-for-dev/web_pipe/pull/47)
|
14
|
+
- Be able to use anything responding to `#to_middlewares`.
|
15
|
+
[#47](https://github.com/waiting-for-dev/web_pipe/pull/47)
|
16
|
+
|
17
|
+
## [0.15.1] - 2021-09-19
|
18
|
+
### Added
|
19
|
+
- `:not_found` extension
|
20
|
+
[#46](https://github.com/waiting-for-dev/web_pipe/pull/46)
|
21
|
+
|
22
|
+
## [0.15.0] - 2021-09-12
|
23
|
+
### Added
|
24
|
+
- **BREAKING**. Switch `dry_view` extension with `hanami_view`.
|
25
|
+
[#45](https://github.com/waiting-for-dev/web_pipe/pull/45)
|
26
|
+
|
27
|
+
## [0.14.0] - 2021-04-14
|
28
|
+
### Added
|
29
|
+
- Inspecting operations
|
30
|
+
[#42](https://github.com/waiting-for-dev/web_pipe/pull/42)
|
31
|
+
- Inspecting middlewares
|
32
|
+
[#43](https://github.com/waiting-for-dev/web_pipe/pull/43)
|
33
|
+
- Testing support
|
34
|
+
[#44](https://github.com/waiting-for-dev/web_pipe/pull/44)
|
35
|
+
|
7
36
|
## [0.13.0] - 2021-01-15
|
8
37
|
### Added
|
9
38
|
- **BREAKING**. Ruby 2.5 deprecated.
|
data/Gemfile
CHANGED
@@ -7,7 +7,7 @@ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
|
|
7
7
|
# Specify your gem's dependencies in web_pipe.gemspec
|
8
8
|
gemspec
|
9
9
|
|
10
|
-
# TODO: Remove when dry-rb 0.8 is released (ruby 3.0 support)
|
11
10
|
group :development do
|
12
|
-
|
11
|
+
# TODO: Move to gemspec when hanami-view 2.0 is available
|
12
|
+
gem 'hanami-view', github: 'hanami/view', tag: 'v2.0.0.alpha2'
|
13
13
|
end
|
data/README.md
CHANGED
@@ -3,15 +3,18 @@
|
|
3
3
|
|
4
4
|
# WebPipe
|
5
5
|
|
6
|
-
`web_pipe` is a
|
7
|
-
|
6
|
+
`web_pipe` is a builder of composable rack applications through a pipe of
|
7
|
+
functions on an immutable struct.
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
> `web_pipe` plays incredibly well with `hanami 2`. If you want to create a
|
10
|
+
> `hanami 2` app with `web_pipe`, you can take inspiration from this sample todo
|
11
|
+
> application:
|
12
|
+
>
|
13
|
+
> https://github.com/waiting-for-dev/hanami_2_web_pipe_todo_app
|
12
14
|
|
13
|
-
|
14
|
-
|
15
|
+
To use in conjunction with [hanami](https://hanamirb.org/) [dry-rb](https://dry-rb.org/) ecosystem,
|
16
|
+
see also
|
17
|
+
[`dry-web-web_pipe`](https://github.com/waiting-for-dev/dry-web-web_pipe).
|
15
18
|
|
16
19
|
1. [Introduction](docs/introduction.md)
|
17
20
|
1. [Design model](docs/design_model.md)
|
@@ -20,9 +23,11 @@ extension](docs/extensions/rails.md).
|
|
20
23
|
1. [Resolving operations](docs/plugging_operations/resolving_operations.md)
|
21
24
|
1. [Injecting operations](docs/plugging_operations/injecting_operations.md)
|
22
25
|
1. [Composing operations](docs/plugging_operations/composing_operations.md)
|
26
|
+
1. [Inspecting operations](docs/plugging_operations/inspecting_operations.md)
|
23
27
|
1. [Using rack middlewares](docs/using_rack_middlewares.md)
|
24
28
|
1. [Injecting middlewares](docs/using_rack_middlewares/injecting_middlewares.md)
|
25
29
|
1. [Composing middlewares](docs/using_rack_middlewares/composing_middlewares.md)
|
30
|
+
1. [Inspecting middlewares](docs/using_rack_middlewares/inspecting_middlewares.md)
|
26
31
|
1. [Composing applications](docs/composing_applications.md)
|
27
32
|
1. [Connection struct](docs/connection_struct.md)
|
28
33
|
1. [Sharing data downstream](docs/connection_struct/sharing_data_downstream.md)
|
@@ -32,12 +37,14 @@ extension](docs/extensions/rails.md).
|
|
32
37
|
1. [Plugs](docs/plugs.md)
|
33
38
|
1. [Config](docs/plugs/config.md)
|
34
39
|
1. [ContentType](docs/plugs/content_type.md)
|
40
|
+
1. [Testing](docs/testing.md)
|
35
41
|
1. [Extensions](docs/extensions.md)
|
36
42
|
1. [Container](docs/extensions/container.md)
|
37
43
|
1. [Cookies](docs/extensions/cookies.md)
|
38
44
|
1. [Flash](docs/extensions/flash.md)
|
39
45
|
1. [Dry Schema](docs/extensions/dry_schema.md)
|
40
|
-
1. [
|
46
|
+
1. [Hanami View](docs/extensions/hanami_view.md)
|
47
|
+
1. [Not found](docs/extensions/not_found.md)
|
41
48
|
1. [Params](docs/extensions/params.md)
|
42
49
|
1. [Rails](docs/extensions/rails.md)
|
43
50
|
1. [Redirect](docs/extensions/redirect.md)
|
@@ -45,7 +52,7 @@ extension](docs/extensions/rails.md).
|
|
45
52
|
1. [Session](docs/extensions/session.md)
|
46
53
|
1. [URL](docs/extensions/url.md)
|
47
54
|
1. Recipes
|
48
|
-
1. [dry-rb integration](docs/recipes/
|
55
|
+
1. [hanami 2 & dry-rb integration](docs/recipes/hanami_2_and_dry_rb_integration.md)
|
49
56
|
1. [hanami-router integration](docs/recipes/hanami_router_integration.md)
|
50
57
|
1. [Using all RESTful methods](docs/recipes/using_all_restful_methods.md)
|
51
58
|
|
@@ -93,8 +100,8 @@ run HelloApp.new
|
|
93
100
|
## Current status
|
94
101
|
|
95
102
|
`web_pipe` is in active development but ready to be used in any environment.
|
96
|
-
|
97
|
-
be
|
103
|
+
Everyday needs are covered, and while you can expect some API changes,
|
104
|
+
they won't be essential, and we'll document everything appropriately.
|
98
105
|
|
99
106
|
## Contributing
|
100
107
|
|
@@ -3,10 +3,10 @@
|
|
3
3
|
Previously, we have seen how to [compose plugged
|
4
4
|
operations](plugging_operations/composing_operations.md) and how to [compose
|
5
5
|
rack middlewares](using_rack_middlewares/composing_middlewares.md). The logical
|
6
|
-
next step is
|
7
|
-
|
6
|
+
next step is composing `web_pipe` applications, which is the same as composing
|
7
|
+
operations and middlewares simultaneously.
|
8
8
|
|
9
|
-
The DSL method `compose` does
|
9
|
+
The DSL method `compose` does precisely that:
|
10
10
|
|
11
11
|
```ruby
|
12
12
|
class HtmlApp
|
@@ -33,7 +33,7 @@ class MyApp
|
|
33
33
|
include WebPipe
|
34
34
|
|
35
35
|
compose :web, HtmlApp.new
|
36
|
-
# It does exactly the same
|
36
|
+
# It does exactly the same as:
|
37
37
|
# use :web, HtmlApp.new
|
38
38
|
# plug :web, HtmlApp.new
|
39
39
|
|
@@ -1,13 +1,13 @@
|
|
1
1
|
# Configuring the connection struct
|
2
2
|
|
3
3
|
[Extensions](../extensions.md) add extra behaviour to the connection struct.
|
4
|
-
Sometimes they need some user
|
5
|
-
|
4
|
+
Sometimes they need some user-provided value to work properly or allow some
|
5
|
+
tweak depending on user needs.
|
6
6
|
|
7
7
|
For this reason, you can add configuration data to a `WebPipe::Conn` instance
|
8
8
|
so that extensions can fetch it. This shared place where extensions look for
|
9
|
-
what they need is `#config` attribute, which is very similar to `#bag`
|
10
|
-
for its more private intention.
|
9
|
+
what they need is the `#config` attribute, which is very similar to `#bag`
|
10
|
+
except for its more private intention.
|
11
11
|
|
12
12
|
In order to interact with `#config`, you can use the method `#add_config(key,
|
13
13
|
value)` or [`Config` plug](../plugs/config.md).
|
@@ -1,36 +1,34 @@
|
|
1
1
|
# Halting the pipe
|
2
2
|
|
3
|
-
Each operation in a pipe takes a single `WebPipe::Conn` instance as argument
|
4
|
-
and returns another (or same) instance
|
5
|
-
|
6
|
-
to the client.
|
3
|
+
Each operation in a pipe takes a single `WebPipe::Conn` instance as an argument
|
4
|
+
and returns another (or the same) instance. A series of operations on the
|
5
|
+
connection struct is propagated until a final response is sent to the client.
|
7
6
|
|
8
7
|
More often than not, you may need to conditionally stop the propagation of a
|
9
|
-
pipe at a given operation.
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
and respond with a 4xx http status code.
|
8
|
+
pipe at a given operation. For example, you could fetch the user requesting a
|
9
|
+
resource. In the case they were granted to perform the required action, you
|
10
|
+
would go on. However, if they weren't, you would like to halt the connection
|
11
|
+
and respond with a 4xx HTTP status code.
|
14
12
|
|
15
|
-
|
16
|
-
struct.
|
13
|
+
To stop the pipe, you have to call `#halt` on the connection struct.
|
17
14
|
|
18
|
-
At implementation level, we must admit that we've not been 100% accurate
|
19
|
-
now. We said that the first operation in the pipe
|
20
|
-
instance. That's true. However, it is more precise
|
21
|
-
`WebPipe::Conn::Ongoing` instance
|
15
|
+
At the implementation level, we must admit that we've not been 100% accurate
|
16
|
+
until now. We said that the first operation in the pipe received a
|
17
|
+
`WebPipe::Conn` instance. That's true. However, it is more precise to say that
|
18
|
+
it gets a `WebPipe::Conn::Ongoing` instance `WebPipe::Conn::Ongoing` being a
|
19
|
+
subclass of
|
22
20
|
`WebPipe::Conn`).
|
23
21
|
|
24
22
|
As long as an operation responds with a `WebPipe::Conn::Ongoing`
|
25
23
|
instance, the propagation will go on. However, when an operation
|
26
24
|
returns a `WebPipe::Conn::Halted` instance (another subclass of
|
27
25
|
`WebPipe::Conn`) then any operation downstream will be ignored.
|
28
|
-
Calling `#halt`
|
26
|
+
Calling `#halt` copies all attributes to a `WebPipe::Conn::Halted`
|
29
27
|
instance and returns it.
|
30
28
|
|
31
|
-
This made-up example checks if the user in the request has an admin role.
|
32
|
-
|
33
|
-
|
29
|
+
This made-up example checks if the user in the request has an admin role. In
|
30
|
+
that case, it returns the solicited resource. Otherwise, they're unauthorized,
|
31
|
+
and they never get it.
|
34
32
|
|
35
33
|
```ruby
|
36
34
|
WebPipe.load_extensions(:params)
|
@@ -1,19 +1,20 @@
|
|
1
1
|
# Sharing data downstream
|
2
2
|
|
3
|
-
Usually you'll find the need to prepare some data in one operation with the
|
3
|
+
Usually, you'll find the need to prepare some data in one operation with the
|
4
4
|
intention for it to be consumed by another downstream operation. The connection
|
5
|
-
struct has a `#bag` attribute which is
|
5
|
+
struct has a `#bag` attribute which is helpful for this purpose.
|
6
6
|
|
7
|
-
`WebPipe::Conn#bag` is a `Hash` with `Symbol` keys where values can
|
8
|
-
|
7
|
+
`WebPipe::Conn#bag` is a `Hash` with `Symbol` keys where the values can be
|
8
|
+
anything you need to share. To help with the process, we have the following
|
9
|
+
methods:
|
9
10
|
|
10
11
|
- `#add(key, value)`: Assigns a value to a key.
|
11
|
-
- `#fetch(key)`, `#fetch(key, default)`: Retrieves value associated
|
12
|
-
to given key. If it is not found, `default` is returned when
|
12
|
+
- `#fetch(key)`, `#fetch(key, default)`: Retrieves the value associated
|
13
|
+
to a given key. If it is not found, `default` is returned when
|
13
14
|
provided.
|
14
15
|
|
15
|
-
This is a simple example of a web application
|
16
|
-
parameter and normalizes it before using in the response body.
|
16
|
+
This is a simple example of a web application that reads a `name`
|
17
|
+
parameter and normalizes it before using it in the response body.
|
17
18
|
|
18
19
|
```ruby
|
19
20
|
# config.ru
|
data/docs/connection_struct.md
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
# Connection struct
|
2
2
|
|
3
|
-
|
4
|
-
`WebPipe::Conn`
|
3
|
+
The first operation you plug in a `web_pipe` application receives an instance of
|
4
|
+
`WebPipe::Conn` automatically created.
|
5
5
|
|
6
|
-
|
7
|
-
web request. In this regard, you can think of it as a
|
8
|
-
hash.
|
6
|
+
`WebPipe::Conn` is just a struct data type that contains all the information
|
7
|
+
from the current web request. In this regard, you can think of it as a
|
8
|
+
structured rack's env hash.
|
9
9
|
|
10
10
|
Request related attributes of this struct are:
|
11
11
|
|
@@ -22,25 +22,27 @@ Request related attributes of this struct are:
|
|
22
22
|
- `#env`: Rack's env hash.
|
23
23
|
- `#request`: Rack::Request instance.
|
24
24
|
|
25
|
-
Your operations must return another (or same) instance of the struct, which
|
26
|
-
will be consumed by next operation downstream.
|
27
|
-
add response data to it:
|
25
|
+
Your operations must return another (or the same) instance of the struct, which
|
26
|
+
will be consumed by the next operation downstream.
|
28
27
|
|
29
|
-
|
30
|
-
|
28
|
+
The struct contains methods to add the response data to it:
|
29
|
+
|
30
|
+
- `#set_status(code)`: makes it accessible in the `#status` attribute.
|
31
|
+
- `#set_response_body(body)`: makes it accessible in the `#response_body`
|
31
32
|
attribute.
|
32
33
|
- `#set_response_headers(headers)`: makes them accessible in
|
33
|
-
`#response_headers` attribute. Besides, there are also
|
34
|
+
the `#response_headers` attribute. Besides, there are also
|
34
35
|
`#add_response_header(key, value)` and `#delete_response_header(key)`
|
35
36
|
methods.
|
36
37
|
|
37
|
-
|
38
|
+
The response in the last struct returned in the pipe will be what is sent to
|
39
|
+
client.
|
38
40
|
|
39
41
|
Every attribute and method is [fully
|
40
42
|
documented](https://www.rubydoc.info/github/waiting-for-dev/web_pipe/master/WebPipe/Conn)
|
41
|
-
in code documentation.
|
43
|
+
in the code documentation.
|
42
44
|
|
43
|
-
Here we have a contrived web application which
|
45
|
+
Here we have a contrived web application which returns as response body
|
44
46
|
the request body it has received:
|
45
47
|
|
46
48
|
```ruby
|
@@ -67,16 +69,17 @@ end
|
|
67
69
|
run DummyApp.new
|
68
70
|
```
|
69
71
|
|
70
|
-
As you can see, default available features are
|
71
|
-
request and to write a response. However, you can pick from several
|
72
|
+
As you can see, by default, the available features are very minimal to read
|
73
|
+
from a request and to write a response. However, you can pick from several
|
72
74
|
(extensions)[extensions.md] which will make your life much easier.
|
73
75
|
|
74
76
|
Immutability is a core design principle in `web_pipe`. All methods in
|
75
|
-
`WebPipe::Conn
|
76
|
-
extensions) return a fresh new instance. It also makes possible chaining
|
77
|
+
`WebPipe::Conn`, which are used to add data to it (both in core behavior and
|
78
|
+
extensions), return a fresh new instance. It also makes possible chaining
|
77
79
|
methods in a very readable way.
|
78
80
|
|
79
|
-
|
81
|
+
If you're using ruby 2.7 or greater, you can pattern match on a `WebPipe::Conn`
|
82
|
+
struct, as in:
|
80
83
|
|
81
84
|
```ruby
|
82
85
|
# GET http://example.org
|
data/docs/design_model.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Design model
|
2
2
|
|
3
|
-
If you are familiar with rack you know that it models a two-way pipe. In it,
|
3
|
+
If you are familiar with rack, you know that it models a two-way pipe. In it,
|
4
4
|
each middleware has the ability to:
|
5
5
|
|
6
6
|
- During the outbound trip modifying the request as it heads to the actual
|
@@ -20,11 +20,12 @@ each middleware has the ability to:
|
|
20
20
|
|
21
21
|
```
|
22
22
|
|
23
|
-
`web_pipe` follows a simpler but equally powerful model: a one-way
|
24
|
-
|
25
|
-
piped
|
26
|
-
argument an instance of the struct and
|
27
|
-
|
23
|
+
`web_pipe` follows a simpler but equally powerful model: a one-way
|
24
|
+
pipe abstracted on top of rack. A struct that contains data from a
|
25
|
+
web request is piped through a stack of operations (functions). Each
|
26
|
+
operation takes as argument an instance of the struct and also
|
27
|
+
returns an instance of it. You can add response data to the struct at
|
28
|
+
any moment in the pipe.
|
28
29
|
|
29
30
|
```
|
30
31
|
|
@@ -35,9 +36,9 @@ Response data can be added to the struct at any moment in the pipe.
|
|
35
36
|
```
|
36
37
|
|
37
38
|
Additionally, any operation in the stack can halt the propagation of the pipe,
|
38
|
-
leaving downstream operations unexecuted. In this way, final
|
39
|
-
one contained in the struct at the moment the pipe was
|
40
|
-
the pipe wasn't halted.
|
39
|
+
leaving downstream operations unexecuted. In this way, the final
|
40
|
+
response is the one contained in the struct at the moment the pipe was
|
41
|
+
halted, or the last one if the pipe wasn't halted.
|
41
42
|
|
42
43
|
As you may know, this is the same model used by Elixir's
|
43
44
|
[`plug`](https://hexdocs.pm/plug/readme.html), from which `web_pipe` takes
|
data/docs/dsl_free_usage.md
CHANGED
@@ -1,26 +1,97 @@
|
|
1
1
|
# DSL free usage
|
2
2
|
|
3
|
-
DSL's (like the one in `web_pipe` with methods like `plug` or
|
4
|
-
`use`) provide developers with a user
|
5
|
-
use a library. However, they usually come at
|
6
|
-
in internal code (which sooner than later translates into some
|
3
|
+
DSL's (like the one in `web_pipe` with class methods like `plug` or
|
4
|
+
`use`) provide developers with a user-friendly way to
|
5
|
+
use a library. However, they usually come at the expense of increasing
|
6
|
+
complexity in internal code (which sooner than later translates into some
|
7
|
+
issue).
|
7
8
|
|
8
|
-
`web_pipe` has tried to
|
9
|
-
reason, DSL in this library is just a layer
|
10
|
-
functionality.
|
9
|
+
`web_pipe` has tried to make an extra effort to minimize these problems. For
|
10
|
+
this reason, the DSL in this library is just a layer providing convenience on
|
11
|
+
top of the independent core functionality.
|
11
12
|
|
12
|
-
|
13
|
-
|
14
|
-
|
13
|
+
The DSL methods delegate transparently to instances of `WebPipe::Pipe`, so you
|
14
|
+
can also work directly with them and forget about magic.
|
15
|
+
|
16
|
+
For instance, the following rack application written through the DSL:
|
15
17
|
|
16
18
|
```ruby
|
17
19
|
# config.ru
|
18
|
-
require 'web_pipe
|
20
|
+
require 'web_pipe'
|
21
|
+
|
22
|
+
WebPipe.load_extensions(:params)
|
23
|
+
|
24
|
+
class HelloApp
|
25
|
+
include WebPipe
|
26
|
+
|
27
|
+
plug :fetch_name
|
28
|
+
plug :render
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def fetch_name(conn)
|
33
|
+
conn.add(:name, conn.params['name'])
|
34
|
+
end
|
35
|
+
|
36
|
+
def render(conn)
|
37
|
+
conn.set_response_body("Hello, #{conn.fetch(:name)}!")
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
run HelloApp.new
|
42
|
+
```
|
43
|
+
|
44
|
+
is exactly equivalent to:
|
45
|
+
|
46
|
+
```ruby
|
47
|
+
# config.ru
|
48
|
+
require 'web_pipe'
|
49
|
+
require 'web_pipe/pipe'
|
50
|
+
|
51
|
+
WebPipe.load_extensions(:params)
|
52
|
+
|
53
|
+
app = WebPipe::Pipe.new
|
54
|
+
.plug(:fetch_name, ->(conn) { conn.add(:name, conn.params['name']) })
|
55
|
+
.plug(:render, ->(conn) { conn.set_response_body("Hello, #{conn.fetch(:name)}") })
|
56
|
+
|
57
|
+
run app
|
58
|
+
```
|
59
|
+
|
60
|
+
As you see, the instance of `WebPipe::Pipe` is itself the rack application.
|
61
|
+
|
62
|
+
As with the DSL, plug operations can be resolved from a container given on
|
63
|
+
initialization.
|
64
|
+
|
65
|
+
```ruby
|
66
|
+
container = {
|
67
|
+
fetch_name: ->(conn) { conn.add(:name, conn.params['name']) },
|
68
|
+
render: ->(conn) { conn.set_response_body("Hello, #{conn.fetch(:name)}") }
|
69
|
+
}
|
70
|
+
|
71
|
+
app = WebPipe::Pipe.new(container: container)
|
72
|
+
.plug(:fetch_name, :fetch_name)
|
73
|
+
.plug(:render, :render)
|
74
|
+
|
75
|
+
run app
|
76
|
+
```
|
77
|
+
|
78
|
+
Likewise, you can provide a context object to resolve methods when only a name
|
79
|
+
is given on `#plug`:
|
80
|
+
|
81
|
+
```ruby
|
82
|
+
class Context
|
83
|
+
def fetch_name(conn)
|
84
|
+
conn.add(:name, conn.params['name'])
|
85
|
+
end
|
19
86
|
|
20
|
-
|
21
|
-
|
87
|
+
def render(conn)
|
88
|
+
conn.set_response_body("Hello, #{conn.fetch(:name)}")
|
89
|
+
end
|
90
|
+
end
|
22
91
|
|
23
|
-
app = WebPipe::
|
92
|
+
app = WebPipe::Pipe.new(context: Context.new)
|
93
|
+
.plug(:fetch_name)
|
94
|
+
.plug(:render)
|
24
95
|
|
25
96
|
run app
|
26
97
|
```
|
@@ -1,18 +1,17 @@
|
|
1
1
|
# Container
|
2
2
|
|
3
|
-
`:container` is a
|
4
|
-
|
5
|
-
instance.
|
3
|
+
`:container` is a simple extension that allows you to configure a dependency
|
4
|
+
injection container to be accessible from a `WebPipe::Conn` instance.
|
6
5
|
|
7
|
-
The container to use must be configured under `:
|
8
|
-
accessible through the `#container` method.
|
6
|
+
The container to use must be configured under the `:container` config key. It
|
7
|
+
will be accessible through the `#container` method.
|
9
8
|
|
10
|
-
You may be
|
9
|
+
You may be wondering why you should worry about configuring a container for a
|
11
10
|
connection instance when you already have access to the container configured
|
12
|
-
for an application (
|
13
|
-
|
14
|
-
|
15
|
-
|
11
|
+
for an application (where you can resolve plugged operations). The idea is
|
12
|
+
decoupling operations from application DSL. If you decide to get rid of the DSL
|
13
|
+
at any time in the future, the process will be straightforward if operations
|
14
|
+
are using the container configured in a connection instance.
|
16
15
|
|
17
16
|
```ruby
|
18
17
|
require 'web_pipe'
|
data/docs/extensions/cookies.md
CHANGED
@@ -24,8 +24,10 @@ This extension adds following methods:
|
|
24
24
|
- `same_site:` must be one of the symbols `:none`, `:lax` or `:strict`.
|
25
25
|
|
26
26
|
- `#delete_cookie(key)` or `#delete_cookie(key, options)`: Instructs browser to
|
27
|
-
delete a previously sent cookie.
|
28
|
-
|
27
|
+
delete a previously sent cookie.
|
28
|
+
|
29
|
+
Deleting a cookie just means setting again the same key with an expiration
|
30
|
+
time in the past.
|
29
31
|
|
30
32
|
It accepts `domain:` and `path:` options (see above for a description of
|
31
33
|
them).
|
@@ -1,20 +1,21 @@
|
|
1
1
|
# Dry Schema
|
2
2
|
|
3
|
-
Extension providing integration for
|
3
|
+
Extension providing integration for every day
|
4
4
|
[`dry-schema`](https://dry-rb.org/gems/dry-schema/) workflow to validate
|
5
5
|
parameters.
|
6
6
|
|
7
7
|
A plug `WebPipe::Plugs::SanitizeParams` is added so that you can use it in your
|
8
8
|
pipe of operations. It takes as arguments a `dry-schema` schema and a handler.
|
9
9
|
On success, it makes output available at `WebPipe::Conn#sanitized_params`. On
|
10
|
-
error, it calls given handler with the connection struct and validation
|
10
|
+
error, it calls the given handler with the connection struct and validation
|
11
|
+
result.
|
11
12
|
|
12
13
|
This extension automatically loads [`:params` extension](params.md),
|
13
14
|
as it takes `WebPipe::Conn#params` as input for the validation schema.
|
14
15
|
|
15
16
|
Instead of providing an error handler as the second argument for the plug, you
|
16
|
-
can configure it under `:param_sanitization_handler` key. In this way, it
|
17
|
-
be reused through composition by
|
17
|
+
can configure it under the `:param_sanitization_handler` key. In this way, it
|
18
|
+
can be reused through composition by other applications.
|
18
19
|
|
19
20
|
```ruby
|
20
21
|
require 'db'
|
data/docs/extensions/flash.md
CHANGED
@@ -1,22 +1,20 @@
|
|
1
1
|
# Flash
|
2
2
|
|
3
|
-
This extension provides
|
4
|
-
users are stored in session
|
5
|
-
redirect.
|
3
|
+
This extension provides the typical flash messages functionality. Messages for
|
4
|
+
users are stored in session to be consumed by another request after a redirect.
|
6
5
|
|
7
6
|
This extension depends on
|
8
7
|
[`Rack::Flash`](https://rubygems.org/gems/rack-flash3) (gem name is
|
9
8
|
`rack-flash3`) and `Rack::Session` (shipped with rack) middlewares.
|
10
9
|
|
11
|
-
`WebPipe::Conn#flash` contains the flash bag.
|
12
|
-
|
10
|
+
`WebPipe::Conn#flash` contains the flash bag. You can use the `#add_flash(key,
|
11
|
+
value)` method to add a message to it.
|
13
12
|
|
14
|
-
There is also an `#add_flash_now(key, value)` method, which
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
messages.
|
13
|
+
There is also an `#add_flash_now(key, value)` method, which adds a message to
|
14
|
+
the bag to consume it in the current request. Be aware that it is, in fact,
|
15
|
+
coupling with the view layer. Something that has to be consumed in the current
|
16
|
+
request should be just data given to the view layer, but it helps when it can
|
17
|
+
treat both scenarios as flash messages.
|
20
18
|
|
21
19
|
```ruby
|
22
20
|
require 'web_pipe'
|