web_pipe 0.15.1 → 0.16.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (77) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +1 -1
  3. data/CHANGELOG.md +10 -0
  4. data/README.md +13 -10
  5. data/docs/building_a_rack_application.md +1 -1
  6. data/docs/composing_applications.md +4 -4
  7. data/docs/connection_struct/configuring_the_connection_struct.md +4 -4
  8. data/docs/connection_struct/halting_the_pipe.md +17 -19
  9. data/docs/connection_struct/sharing_data_downstream.md +9 -8
  10. data/docs/connection_struct.md +22 -19
  11. data/docs/design_model.md +10 -9
  12. data/docs/dsl_free_usage.md +85 -14
  13. data/docs/extensions/container.md +9 -10
  14. data/docs/extensions/cookies.md +4 -2
  15. data/docs/extensions/dry_schema.md +5 -4
  16. data/docs/extensions/flash.md +9 -11
  17. data/docs/extensions/hanami_view.md +10 -14
  18. data/docs/extensions/params.md +6 -4
  19. data/docs/extensions/rails.md +28 -34
  20. data/docs/extensions/redirect.md +5 -4
  21. data/docs/extensions/router_params.md +5 -5
  22. data/docs/extensions/session.md +4 -4
  23. data/docs/extensions/url.md +6 -6
  24. data/docs/extensions.md +5 -6
  25. data/docs/introduction.md +7 -7
  26. data/docs/plugging_operations/composing_operations.md +3 -3
  27. data/docs/plugging_operations/injecting_operations.md +4 -4
  28. data/docs/plugging_operations/inspecting_operations.md +1 -2
  29. data/docs/plugging_operations/resolving_operations.md +3 -3
  30. data/docs/plugging_operations.md +3 -3
  31. data/docs/plugs/config.md +1 -1
  32. data/docs/plugs/content_type.md +2 -1
  33. data/docs/plugs.md +6 -7
  34. data/docs/recipes/hanami_2_and_dry_rb_integration.md +12 -0
  35. data/docs/recipes/hanami_router_integration.md +3 -1
  36. data/docs/recipes/using_all_restful_methods.md +6 -5
  37. data/docs/using_rack_middlewares/composing_middlewares.md +2 -3
  38. data/docs/using_rack_middlewares/injecting_middlewares.md +6 -6
  39. data/docs/using_rack_middlewares/inspecting_middlewares.md +7 -6
  40. data/docs/using_rack_middlewares.md +6 -6
  41. data/lib/web_pipe/app.rb +22 -25
  42. data/lib/web_pipe/conn.rb +0 -1
  43. data/lib/web_pipe/conn_support/builder.rb +0 -7
  44. data/lib/web_pipe/conn_support/composition.rb +3 -26
  45. data/lib/web_pipe/conn_support/errors.rb +5 -5
  46. data/lib/web_pipe/conn_support/headers.rb +1 -50
  47. data/lib/web_pipe/conn_support/types.rb +3 -3
  48. data/lib/web_pipe/dsl/builder.rb +10 -19
  49. data/lib/web_pipe/dsl/class_context.rb +15 -40
  50. data/lib/web_pipe/dsl/instance_context.rb +53 -0
  51. data/lib/web_pipe/extensions/container/container.rb +2 -15
  52. data/lib/web_pipe/extensions/cookies/cookies.rb +2 -31
  53. data/lib/web_pipe/extensions/dry_schema/dry_schema.rb +2 -56
  54. data/lib/web_pipe/extensions/flash/flash.rb +2 -32
  55. data/lib/web_pipe/extensions/hanami_view/hanami_view.rb +2 -93
  56. data/lib/web_pipe/extensions/not_found/not_found.rb +2 -40
  57. data/lib/web_pipe/extensions/params/params.rb +2 -63
  58. data/lib/web_pipe/extensions/rails/rails.rb +2 -119
  59. data/lib/web_pipe/extensions/redirect/redirect.rb +2 -20
  60. data/lib/web_pipe/extensions/router_params/router_params.rb +1 -39
  61. data/lib/web_pipe/extensions/session/session.rb +2 -25
  62. data/lib/web_pipe/extensions/url/url.rb +2 -5
  63. data/lib/web_pipe/pipe.rb +229 -0
  64. data/lib/web_pipe/plug.rb +30 -75
  65. data/lib/web_pipe/plugs/config.rb +0 -2
  66. data/lib/web_pipe/plugs/content_type.rb +0 -2
  67. data/lib/web_pipe/rack_support/app_with_middlewares.rb +3 -26
  68. data/lib/web_pipe/rack_support/middleware.rb +2 -2
  69. data/lib/web_pipe/rack_support/middleware_specification.rb +17 -55
  70. data/lib/web_pipe/types.rb +1 -3
  71. data/lib/web_pipe/version.rb +1 -1
  72. data/lib/web_pipe.rb +77 -21
  73. data/web_pipe.gemspec +1 -0
  74. metadata +7 -6
  75. data/docs/recipes/dry_rb_integration.md +0 -17
  76. data/lib/web_pipe/dsl/dsl_context.rb +0 -85
  77. data/lib/web_pipe/dsl/instance_methods.rb +0 -114
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8148f2a5701baf60d74d238ed32b6fcdaadaaf5006431322222a081d005caa01
4
- data.tar.gz: 90a38228ba60cd9637584b85cffd06d0271df5bd2d3d9bc721b3d3cb7de61287
3
+ metadata.gz: b0a90514a384a44456634dd195280291d82ab67eb336f69904c0cdc6bc3518ba
4
+ data.tar.gz: b2a3295f82715c9bf128d971994667eda13095631349b7cb33e1ccb97777b7e8
5
5
  SHA512:
6
- metadata.gz: 4bd1b21978116a5743d53106cc4c2b8f042dba4cbe63804adbc370174bf08a9221f563561b123a10445e5cb3f87b7672d9cf0ef8c1161e53a9b54f83ae3aba13
7
- data.tar.gz: a0028185e4bfe8858206fc90c8e355891d3e9a14db81fad7076fd8c05960f01abd1418fc05bece3c6fe73585a5732e2f13318a6529e9d6fef75f4e86181da376
6
+ metadata.gz: b353968992c5d5f2d5952fe3ae55c1a2691e8c852e8dd72525b4fcbb6e35e5fe0741016cc362e1afcdfe217594bdc43adc182c46e752989006fe8a5cc6a694af
7
+ data.tar.gz: c5d206d3058b7bd83dc3b0634c97d77e0e21bfc1468e6745708e7eaffd8aef1d4c7467a49894de8161d2af1bfd212ce647a7858f61875ed3eabd784e4ed7a101
data/.rubocop.yml CHANGED
@@ -1,5 +1,5 @@
1
1
  AllCops:
2
- TargetRubyVersion: 2.7.2
2
+ TargetRubyVersion: 3.0
3
3
  NewCops: enable
4
4
  SuggestExtensions: false
5
5
  Exclude:
data/CHANGELOG.md CHANGED
@@ -4,6 +4,16 @@ 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
+
7
17
  ## [0.15.1] - 2021-09-19
8
18
  ### Added
9
19
  - `:not_found` extension
data/README.md CHANGED
@@ -3,15 +3,18 @@
3
3
 
4
4
  # WebPipe
5
5
 
6
- `web_pipe` is a modular rack application builder through a pipe of
7
- operations on an immutable struct.
6
+ `web_pipe` is a builder of composable rack applications through a pipe of
7
+ functions on an immutable struct.
8
8
 
9
- In order to use in conjunction with [dry-rb](https://dry-rb.org/)
10
- ecosystem, see also
11
- [`dry-web-web_pipe`](https://github.com/waiting-for-dev/dry-web-web_pipe).
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
- If you want to use it with a Rails project, don't miss docs for the [rails
14
- extension](docs/extensions/rails.md).
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)
@@ -49,7 +52,7 @@ extension](docs/extensions/rails.md).
49
52
  1. [Session](docs/extensions/session.md)
50
53
  1. [URL](docs/extensions/url.md)
51
54
  1. Recipes
52
- 1. [dry-rb integration](docs/recipes/dry_rb_integration.md)
55
+ 1. [hanami 2 & dry-rb integration](docs/recipes/hanami_2_and_dry_rb_integration.md)
53
56
  1. [hanami-router integration](docs/recipes/hanami_router_integration.md)
54
57
  1. [Using all RESTful methods](docs/recipes/using_all_restful_methods.md)
55
58
 
@@ -97,8 +100,8 @@ run HelloApp.new
97
100
  ## Current status
98
101
 
99
102
  `web_pipe` is in active development but ready to be used in any environment.
100
- Common needs are covered and while you can expect some API changes, they won't
101
- be very important and everything will be properly documented.
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.
102
105
 
103
106
  ## Contributing
104
107
 
@@ -1,6 +1,6 @@
1
1
  # Building a rack application
2
2
 
3
- In order to build a rack application with `web_pipe` you have to include
3
+ To build a rack application with `web_pipe`, you have to include
4
4
  `WebPipe` module in a class:
5
5
 
6
6
  ```ruby
@@ -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 thinking about composing `web_pipe` applications, which is exactly
7
- the same as composing both operations and middlewares at the same time.
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 exactly that:
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 than:
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 provided value to work properly or they may allow
5
- some tweak depending on user needs.
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` except
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 of it. In this way, a series of
5
- operations on the connection struct is propagated until final response is sent
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. A lot of times the requirement to do something like
10
- that will be authorization policies. For example, you could fetch the user
11
- requesting a resource. In the case she was granted to perform required action
12
- you would go on. However, if she wasn't you would like to halt the connection
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
- In order to stop the pipe, you simply have to call `#halt` on the connection
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 until
19
- now. We said that the first operation in the pipe recerived a `WebPipe::Conn`
20
- instance. That's true. However, it is more precise saying that it gets a
21
- `WebPipe::Conn::Ongoing` instance (`WebPipe::Conn::Ongoing` being a subclass of
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` simply copies all attributes to a `WebPipe::Conn::Halted`
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. If
32
- she has, it returns solicited resource. Otherwise she is unauthorized and never
33
- gets the resource.
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 useful for this purpose.
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
- be anything you need to share. To help with the process we have following methods:
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 which reads a `name`
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
@@ -1,11 +1,11 @@
1
1
  # Connection struct
2
2
 
3
- First operation you plug in a `web_pipe` application receives an instance of
4
- `WebPipe::Conn` which has been automatically created.
3
+ The first operation you plug in a `web_pipe` application receives an instance of
4
+ `WebPipe::Conn` automatically created.
5
5
 
6
- This is just a struct data type which contains all the information from current
7
- web request. In this regard, you can think of it as a structured rack's env
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. The struct contains methods to
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
- - `#set_status(code)`: makes it accessible in `#status` attribute.
30
- - `#set_response_body(body)`: makes it accessible in `#response_body`
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
- Response in last struct returned in the pipe will be what is sent to client.
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 just returns as response body
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 the very minimal to read from a
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` which are used to add data to it (both in core behaviour and
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
- You can use ruby 2.7 pattern matching on a `WebPipe::Conn` struct, as in:
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 pipe which
24
- is abstracted on top of rack. A struct that contains data from a web request is
25
- piped trough a stack of operations (functions). Each operation takes as
26
- argument an instance of the struct and returns also an instance of it.
27
- Response data can be added to the struct at any moment in the pipe.
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 response is the
39
- one contained in the struct at the moment the pipe was halted, or last one if
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
@@ -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 friendly and ergonomic way to
5
- use a library. However, they usually come at expenses of increasing complexity
6
- in internal code (which sooner than later translates into some kind of issue).
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 do an extra effort to minimize these problems. For this
9
- reason, DSL in this library is just a layer on top of an independent core
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
- To use `web_pipe` without its DSL layer, you just need to initialize a
13
- `WebPipe::App` instance with an array of all the operations that otherwise
14
- you'd `plug`. That instance will be a rack application ready to be used.
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/app'
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
- op_1 = ->(conn) { conn.set_status(200) }
21
- op_2 = ->(conn) { conn.set_response_body('Hello, World!') }
87
+ def render(conn)
88
+ conn.set_response_body("Hello, #{conn.fetch(:name)}")
89
+ end
90
+ end
22
91
 
23
- app = WebPipe::App.new([op_1, op_2])
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 very simple extension which allows you to configure a
4
- dependency injection container to be accessible from a `WebPipe::Conn`
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 `:configuration` key. It will be
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 thinking why you should worry about configuring a container for a
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 (from where you can resolve plugged operations). The idea
13
- here is decoupling operations from application DSL. If at anytime in the future
14
- you decide to get rid off the DSL, the process will be straightforward if
15
- operations are using the container configured in a connection instance.
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'
@@ -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. Deleting a cookie just means setting again
28
- the same key with an expiration time in the past.
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 a common
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 result.
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 can
17
- be reused through composition by others applications.
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'
@@ -1,22 +1,20 @@
1
1
  # Flash
2
2
 
3
- This extension provides with typical flash messages functionality. Messages for
4
- users are stored in session in order to be consumed by another request after a
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. In order to add a message to it,
12
- you can use `#add_flash(key, value)` method.
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 is used to add a
15
- message to the bag with the intention for it to be consumed in the current
16
- request. Be aware that it is in fact a coupling with the view layer.
17
- Something that has to be consumed in the current request should be just data
18
- given to the view layer, but it helps when it can treat both scenarios as flash
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'
@@ -1,13 +1,13 @@
1
1
  # Hanami View
2
2
 
3
- > This extension currently works with `hanami-view` v2.0.0.alpha2, which is not
4
- still released but it's available on the gem repository.
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
5
 
6
- This extensions integrates with [hanami-view](https://github.com/hanami/view)
7
- rendering system to set a hanami-view output as response body.
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.
8
8
 
9
9
  `WebPipe::Conn#view` method is at the core of this extension. In its basic
10
- behaviour, you provide to it a view instance you want to render and any
10
+ behavior, you provide to it a view instance you want to render and any
11
11
  exposures or options it may need:
12
12
 
13
13
  ```ruby
@@ -37,9 +37,8 @@ class MyApp
37
37
  end
38
38
  end
39
39
  ```
40
-
41
- However, you can resolve a view from a container if you also use (`:container`
42
- extension)[container.md]:
40
+ However, you can resolve a view from a container if you also use the
41
+ (`:container` extension)[container.md]:
43
42
 
44
43
  ```ruby
45
44
  require 'hanami_view'
@@ -64,13 +63,10 @@ end
64
63
  ```
65
64
 
66
65
  As in a standard call to `Hanami::View#call`, you can override the context
67
- (`Hanami::View::Context`) to use through `context:` option. However, it is still
68
- possible to leverage configured default context while being able to inject
69
- request specific data to it.
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.
70
67
 
71
- For that to work, you have to specify required dependencies (in this case,
72
- request specific data) to your hanami-view's context. A very convenient way to do
73
- 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):
74
70
 
75
71
  ```ruby
76
72
  require 'hanami/view/context'
@@ -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 where any number of transformations
5
- can be configured.
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` just returns GET and POST parameters as a hash:
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 at the moment of calling `#params`:
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
  # ...