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
@@ -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)