web_pipe 0.15.1 → 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.
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
@@ -1,8 +1,8 @@
1
1
  # Rails
2
2
 
3
- The first two things to keep in mind in order to integrate with Rails is
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). For example:
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,30 +22,29 @@ class MyRoute
22
22
  end
23
23
  ```
24
24
 
25
- In order to do something like the previous example you don't need to enable
26
- this extension. Notice that rails took care of dispatching the request to our
27
- `WebPipe` rack application, which was then responsible for generating the
28
- response. In this case, it used a simple call to `#set_response_body`.
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, surely you want something more elaborate to generate
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 specially well here is
33
+ option that will play especially well here is
34
34
  [`hanami-view`](https://github.com/hanami/view). Furthermore, we have a
35
35
  tailored `hanami_view`
36
36
  [extension](https://waiting-for-dev.github.io/web_pipe/docs/extensions/hanami_view.html).
37
37
 
38
- You need to use `:rails` extension if:
38
+ You need to use the `:rails` extension if:
39
39
 
40
- - You want to use `action_view` as rendering system.
41
- - You want to use rails url helpers from your `WebPipe` application.
40
+ - You want to use `action_view` as a rendering system.
41
+ - You want to use rails URL helpers from your `WebPipe` application.
42
42
  - You want to use controller helpers from your `WebPipe` application.
43
43
 
44
- Rails responsibilities for controlling the request/response cycle and the
45
- rendering process are a little bit tangled. For this reason, even if you
46
- want to use `WebPipe` applications instead of Rails controller actions you
47
- still have to use the typical top `ApplicationController` in order to define
48
- 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:
49
48
 
50
49
  - Which layout is applied to the template.
51
50
  - Which helpers will become available to the templates.
@@ -55,11 +54,11 @@ no layout is applied and only built-in helpers (for example,
55
54
  `number_as_currency`) are available. You can change it via the
56
55
  `:rails_controller` configuration option.
57
56
 
58
- The main method that this extension adds to `WebPipe::Conn` is `#render`,
59
- which just delegates to the [Rails
60
- implementation](https://api.rubyonrails.org/v6.0.1/classes/ActionController/Renderer.html)
61
- as you'd do in a typical rails controller. Remember that you can provide
62
- template instance variables through the keyword `:assigns`.
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`.
63
62
 
64
63
  ```ruby
65
64
  # config/routes.rb
@@ -92,10 +91,10 @@ end
92
91
  ```
93
92
 
94
93
  Notice that we used the keyword `template:` instead of taking advantage of
95
- automatic template lookup. We did that way so that we don't have to create also
96
- an `ArticlesController`, but it's up to you. In the case of having an
97
- `ArticlesController` we could just do `conn.render(:index, assigns: {
98
- articles: Article.all })`.
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 })`.
99
98
 
100
99
  Besides, this extension provides with two other methods:
101
100
 
@@ -104,12 +103,7 @@ Besides, this extension provides with two other methods:
104
103
  - `helpers` returns the associated [controller
105
104
  helpers](https://api.rubyonrails.org/classes/ActionController/Helpers.html).
106
105
 
107
- In all the examples we have supposed that we are putting `WebPipe` applications
108
- within `app/controllers/` directory. However, remember you can put them
109
- wherever you like as long as you respect rails [`autoload_paths`](https://guides.rubyonrails.org/autoloading_and_reloading_constants.html#autoload-paths).
110
-
111
- Here you have a link to a very simple and contrived example of a rails
112
- application integrating `web_pipe`:
113
-
114
- https://github.com/waiting-for-dev/rails-web_pipe
115
-
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).
@@ -1,14 +1,15 @@
1
1
  # Redirect
2
2
 
3
- This extension helps with creating a redirect response.
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 redirect.
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` which takes
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 in order to merge placeholder parameters
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
- What this extension does is adding a transformation function to the registry
9
- with name `:router_params`. Internally, it merges what is present in rack env's
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
@@ -1,11 +1,11 @@
1
1
  # Session
2
2
 
3
- Wrapper around `Rack::Session` middleware to help working with
4
- sessions in your plugged operations.
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
@@ -1,11 +1,11 @@
1
1
  # URL
2
2
 
3
- `:url` extension just adds a few methods which cook raw request information
4
- about the URL into something more digestible.
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`: Which is schema + host + port (unless it is the default for the scheme). I.e. `'https://example.org'` or `'http://example.org:8000'`.
9
- - `#path`: Which is script name (if any) + path information. I.e. `'index.rb/users/1'` or `'users/1'`.
10
- - `#full_path`: Which is path + query string (if any). I.e. `'users/1?view=table'`.
11
- - `#url`: Which is base url + full path. I.e. `'http://example.org:8000/users/1?view=table'`.
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 raw: the very minimal you
4
- need to be able to build a web application. However, there are
5
- several extensions to progressively add just the ingredients you
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
- In order to load the extensions, you have to call
9
- `#load_extensions` method in `WebPipe`:
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 being a decoupled
10
- component within a web framework. For this reason, it plays extremely well
11
- with [dry-rb](https://dry-rb.org/) ecosystem. If it helps, you can think of it
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
- > In order to try this example you can paste it to a file with name `config.ru`
32
- and launch the rack command `rackup` within the same directory. The application
33
- will be available in `http://localhost:9292`.
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
- This can be leveraged to plug a whole `web_pipe` application as an operation
9
- to another application. Doing so, you are plugging an operation which is the
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
- Operations can be injected at the moment an application is initialized,
4
- which allows you to override what the definition declares.
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
- This is mainly useful for testing purposes, where you can switch a heavy
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
@@ -1,11 +1,10 @@
1
1
  # Inspecting operations
2
2
 
3
- Once a `WebPipe` class is initialized all its operations get resolved. It
3
+ Once a `WebPipe` class is initialized, all its operations get resolved. It
4
4
  happens because they are whether [resolved](resolving_operations.md) or
5
5
  [injected](injecting_operations.md). The final result can be accessed through
6
6
  the `#operations` method:
7
7
 
8
-
9
8
  ```ruby
10
9
  require 'web_pipe'
11
10
  require 'web_pipe/conn_support/builder'
@@ -1,6 +1,6 @@
1
1
  # Resolving operations
2
2
 
3
- There are several ways you can specify how an operation is resolved.
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) in order to resolve a dependency. It can be configured at the
57
- moment `WebPipe` module is included:
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[
@@ -1,10 +1,10 @@
1
1
  # Plugging operations
2
2
 
3
- You can plug operations to your application with the DSL method `plug`. The
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) on
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
@@ -1,6 +1,6 @@
1
1
  # Config
2
2
 
3
- `Config` plug helps in the addition of configuration settings (`#config` hash
3
+ The `Config` plug helps in adding configuration settings (`#config` hash
4
4
  attribute) to an instance of `WebPipe::Conn`.
5
5
 
6
6
  ```ruby
@@ -1,6 +1,7 @@
1
1
  # ContentType
2
2
 
3
- `ContentType` plug is just a helper to set `Content-Type` response header.
3
+ The `ContentType` plug is just a helper to set the `Content-Type` response
4
+ header.
4
5
 
5
6
  Example:
6
7
 
data/docs/plugs.md CHANGED
@@ -1,13 +1,12 @@
1
1
  # Plugs
2
2
 
3
- Some group of operations can be generalized as following same pattern. For
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 another one setting same header to `application/json`. We name plugs
6
- to this level of abstraction on top of operations: plugs are operation
7
- builders. In other words, they are higher order functions which return
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` in
11
- order to create an operation.
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
- In order to perform [string matching with variables](https://github.com/hanami/router#string-matching-with-variables) you just need to load [`:router_params` extension](../extensions/router_params.md).
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, a lot of browsers don't support some RESTful
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 who should
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 very simple. Just use `MethodOverride` middleware before your router does its work. For example, in `config.ru`:
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
@@ -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. When you do so, all the
7
- middlewares for that application will be added to the stack in the same order
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
@@ -1,19 +1,19 @@
1
1
  # Injecting middlewares
2
2
 
3
- Middlewares can be injected at the moment an application is initialized,
3
+ You can inject middlewares at the moment an application is initialized,
4
4
  allowing you to override what you have defined in the DSL.
5
5
 
6
- For that purpose, you have to use `middlewares:` keyword argument. It must be a
6
+ For that purpose, you have to use the `middlewares:` keyword argument. It must be a
7
7
  hash where middlewares are matched by the name you gave them in its definition.
8
8
 
9
- A middleware must be specified as an `Array`. First item must be a rack
10
- middleware class. The rest of arguments (if any) should be any option it may
9
+ A middleware must be specified as an `Array`. The first item must be a rack
10
+ middleware class. The rest of the arguments (if any) should be any options it may
11
11
  need.
12
12
 
13
- This is mainly useful for testing purposes, where you can switch a heavy
13
+ That is mainly useful for testing purposes, where you can switch a heavy
14
14
  middleware and use a mocked one instead.
15
15
 
16
- In the following example, rack session mechanism is being mocked:
16
+ In the following example, we mock the rack session mechanism:
17
17
 
18
18
  ```ruby
19
19
  # config.ru
@@ -1,15 +1,16 @@
1
1
  # Inspecting middlewares
2
2
 
3
- Once a `WebPipe` class is initialized all its middlewares get resolved. They
4
- can be accessed through the `#middlewares` method.
3
+ Once a `WebPipe` class is initialized, all its middlewares get resolved. You
4
+ can access them through the `#middlewares` method.
5
5
 
6
6
  Each middleware is represented by a
7
7
  `WebPipe::RackSupport::MiddlewareSpecification` instance, which contains two
8
- accessors: `middleware` returns the middleware class, while `options` returns
9
- an array with the arguments that are provided to the middleware on initialization.
8
+ accessors: `middleware` returns the middleware class. In contrast, `options`
9
+ returns an array with the arguments provided to the middleware on
10
+ initialization.
10
11
 
11
- Kepp in mind that every middleware is resolved as an array. This is because it
12
- can in fact be composed by an chain of middlewares built through
12
+ Keep in mind that every middleware is resolved as an array. That is because it
13
+ can be composed by a chain of middlewares built through
13
14
  [composition](composing_middlewares.md).
14
15
 
15
16
 
@@ -1,16 +1,16 @@
1
1
  # Using rack middlewares
2
2
 
3
3
  A one-way pipe like the one `web_pipe` implements can deal with any required
4
- feature in a web application. However, usually it is convenient to be able to
5
- use some well-known rack middleware so you don't have to reinvent the wheel.
6
- Even if you can add them at the router layer, `web_pipe` allows you to
7
- encapsulate them in your application definition.
4
+ feature in a web application. However, usually, it is convenient to use some
5
+ well-known rack middleware, so you don't have to reinvent the wheel. Even if
6
+ you can add them to the router layer, `web_pipe` allows you to encapsulate them
7
+ in your application definition.
8
8
 
9
- In order to add rack middlewares to the stack, you have to use the DSL method
9
+ To add rack middlewares to the stack, you have to use the DSL method
10
10
  `use`. The first argument it takes is a `Symbol` with the name you want to
11
11
  assign to it (which is needed to allow
12
12
  [injection](using_rack_middlewares/injecting_middlewares.md) on
13
- initialization). Then, it must follow the middleware class and any option it
13
+ initialization). Then, it must follow the middleware class and any options it
14
14
  may need:
15
15
 
16
16
  ```ruby
data/lib/web_pipe/app.rb CHANGED
@@ -1,54 +1,51 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'web_pipe/types'
4
3
  require 'web_pipe/conn'
5
4
  require 'web_pipe/conn_support/builder'
6
5
  require 'web_pipe/conn_support/composition'
7
6
 
8
7
  module WebPipe
9
- # Rack application built around applying a pipe of {Operation} to
10
- # a {Conn}.
8
+ # Rack app built from a chain of functions that take and return a
9
+ # {WebPipe::Conn}.
11
10
  #
12
- # A rack application is something callable accepting rack's `env`
13
- # as argument and returning a rack response. So, the workflow
14
- # followed to build it is:
11
+ # This is the abstraction encompassing a rack application built only with the
12
+ # functions on {WebPipe::Conn}. {WebPipe::RackSupport::AppWithMiddlewares}
13
+ # takes middlewares also into account.
15
14
  #
16
- # - Take rack's `env` and create a {Conn} from here.
17
- # - Starting from it, apply the pipe of operations (anything
18
- # callable accepting a {Conn} and returning a {Conn}).
19
- # - Convert last {Conn} back to a rack response and
20
- # return it.
15
+ # A rack application is something callable that takes the rack environment as
16
+ # an argument, and returns a rack response. So, this class needs to:
21
17
  #
22
- # {Conn} can itself be of two different types (subclasses of it}:
23
- # {Conn::Ongoing} and {Conn::Halted}. The pipe is stopped
24
- # whenever the stack is emptied or a {Conn::Halted} is
25
- # returned in any of the steps.
18
+ # - Take rack's environment and create a {WebPipe::Conn} struct from there.
19
+ # - Starting from the initial struct, apply the pipe of functions.
20
+ # - Convert the last {WebPipe::Conn} back to a rack response.
21
+ #
22
+ # {WebPipe::Conn} can itself be of two different types (subclasses of it}:
23
+ # {Conn::Ongoing} and {Conn::Halted}. The pipe is stopped on two scenarios:
24
+ #
25
+ # - The end of the pipe is reached.
26
+ # - One function returns a {Conn::Halted}.
26
27
  class App
27
- # Type for a rack environment.
28
- RackEnv = Types::Strict::Hash
29
-
30
28
  include Dry::Monads::Result::Mixin
31
29
 
32
30
  # @!attribute [r] operations
33
- # @return [Array<Operation[]>]
31
+ # @return [Array<Proc>]
34
32
  attr_reader :operations
35
33
 
34
+ # @param operations [Array<Proc>]
36
35
  def initialize(operations)
37
- @operations = Types.Array(
38
- ConnSupport::Composition::Operation
39
- )[operations]
36
+ @operations = operations
40
37
  end
41
38
 
42
- # @param env [Hash] Rack env
39
+ # @param env [Hash] Rack environment
43
40
  #
44
41
  # @return env [Array] Rack response
45
42
  # @raise ConnSupport::Composition::InvalidOperationResult when an
46
- # operation does not return a {Conn}
43
+ # operation doesn't return a {WebPipe::Conn}
47
44
  def call(env)
48
45
  extract_rack_response(
49
46
  apply_operations(
50
47
  conn_from_env(
51
- RackEnv[env]
48
+ env
52
49
  )
53
50
  )
54
51
  )
data/lib/web_pipe/conn.rb CHANGED
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'dry/struct'
4
- require 'web_pipe/types'
5
4
  require 'web_pipe/conn_support/types'
6
5
  require 'web_pipe/conn_support/errors'
7
6
  require 'web_pipe/conn_support/headers'
@@ -6,15 +6,8 @@ require 'web_pipe/conn_support/headers'
6
6
 
7
7
  module WebPipe
8
8
  module ConnSupport
9
- # Helper module to build a {Conn} from a rack's env.
10
- #
11
- # It always return a {Conn::Ongoing} subclass.
12
- #
13
9
  # @api private
14
10
  module Builder
15
- # @param env [Types::Env] Rack's env
16
- #
17
- # @return [Conn::Ongoing]
18
11
  # rubocop:disable Metrics/MethodLength
19
12
  def self.call(env)
20
13
  rr = Rack::Request.new(env)