Repository: swaggest/rest
Pull request #191 (2024-03-01 23:06:32)

Update deps, fix lint, fix mount example

github-actions[bot]: ### Lines Of Code

| Language  |  Files  |    Lines    |    Code     | Comments |   Blanks   | Complexity |     Bytes      |
|-----------|---------|-------------|-------------|----------|------------|------------|----------------|
| Go        | 112     | 8591 (+25)  | 6188 (+18)  | 649 (+1) | 1754 (+6)  | 1022       | 209.1K (+537B) |
| Go (test) | 55 (+1) | 6611 (+153) | 5072 (+123) | 295      | 1244 (+30) | 188        | 180.3K (+2.7K) |
| JSON      | 3       | 1855 (-1)   | 1855 (-1)   | 0        | 0          | 0          | 71.5K (-15B)   |
| YAML      | 10      | 740 (+1)    | 635 (+1)    | 46       | 59         | 0          | 23.2K (+17B)   |
<!-- Sticky Pull Request CommentLOC -->
github-actions[bot]: ### Go API Changes

<pre>
# summary
Inferred base version: v0.2.61
Suggested version: v0.2.62
</pre>
<!-- Sticky Pull Request Commentgorelease -->
github-actions[bot]: ### Unit Test Coverage
total:								(statements)			81.2%
changed lines: (statements) 100.0%
<details><summary>Coverage of changed lines</summary>

|           File            |       Function        |  Coverage   |
|---------------------------|-----------------------|-------------|
| Total                     |                       | 100.0%      |
| nethttp/options.go        |                       | 100.0%      |
| nethttp/options.go:86     | RequestMapping        | 100.0%      |
| nethttp/options.go:117    | ResponseHeaderMapping | 100.0%      |
| nethttp/usecase.go        |                       | 100.0%      |
| nethttp/usecase.go:11     | UseCaseMiddlewares    | 100.0%      |
| request/factory.go        |                       | 100.0%      |
| request/factory.go:174    | prepareCustomMapping  | 100.0%      |
| request/factory.go:222    | jsonParams            | 100.0%      |
| request/factory.go:256    | makeDefaultDecoder    | 100.0%      |
| request/reflect.go        |                       | 100.0%      |
| request/reflect.go:10     | hasFileFields         | 100.0%      |
| response/encoder.go       |                       | 100.0%      |
| response/encoder.go:77    | setupHeadersEncoder   | 100.0%      |
| response/encoder.go:123   | setupCookiesEncoder   | 100.0%      |
| _examples/jwtauth/main.go |                       | no coverage |
| _examples/mount/main.go   |                       | no coverage |

</details>

<details><summary>Coverage diff with base branch</summary>

No changes in coverage.

</details>
<!-- Sticky Pull Request Commentunit-test -->
codecov[bot]: ## [Codecov](https://app.codecov.io/gh/swaggest/rest/pull/191?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=swaggest) Report
All modified and coverable lines are covered by tests :white_check_mark:
> Project coverage is 76.16%. Comparing base [(`2ccfa52`)](https://app.codecov.io/gh/swaggest/rest/commit/2ccfa5239519290bbf3ac9997bc3d05047ed3de8?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=swaggest) to head [(`38cca4a`)](https://app.codecov.io/gh/swaggest/rest/pull/191?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=swaggest).


<details><summary>Additional details and impacted files</summary>


```diff
@@           Coverage Diff           @@
##           master     #191   +/-   ##
=======================================
  Coverage   76.16%   76.16%           
=======================================
  Files          30       30           
  Lines        1712     1712           
=======================================
  Hits         1304     1304           
  Misses        295      295           
  Partials      113      113           
```

| [Flag](https://app.codecov.io/gh/swaggest/rest/pull/191/flags?src=pr&el=flags&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=swaggest) | Coverage Δ | |
|---|---|---|
| [unittests](https://app.codecov.io/gh/swaggest/rest/pull/191/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=swaggest) | `76.16% <100.00%> (ø)` | |

Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=swaggest#carryforward-flags-in-the-pull-request-comment) to find out more.


</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/swaggest/rest/pull/191?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=swaggest).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=swaggest).

github-actions[bot]: ### Benchmark Result
<details><summary>Benchmark diff with base branch</summary>

```
name                                    old time/op    new time/op    delta
pkg:github.com/swaggest/rest/jsonschema goos:linux goarch:amd64
RequestValidator_ValidateRequestData-4    1.09µs ± 1%    1.09µs ± 1%    ~     (p=0.827 n=6+5)
pkg:github.com/swaggest/rest/request goos:linux goarch:amd64
Decoder_Decode-4                           507ns ± 3%     503ns ± 1%    ~     (p=0.429 n=6+5)
DecoderFunc_Decode-4                      1.45µs ± 1%    1.46µs ± 1%    ~     (p=0.461 n=6+6)
Decoder_Decode_json-4                     18.6µs ± 2%    18.5µs ± 1%    ~     (p=1.000 n=6+6)
Decoder_Decode_queryObject-4              3.92µs ± 0%    3.95µs ± 0%  +0.97%  (p=0.004 n=6+5)
Decoder_Decode_jsonParam-4                1.51µs ± 0%    1.49µs ± 0%  -1.47%  (p=0.004 n=5+6)
DecoderFactory_SetDecoderFunc-4           1.30µs ± 0%    1.29µs ± 0%  -1.13%  (p=0.004 n=5+6)
pkg:github.com/swaggest/rest/response/gzip goos:linux goarch:amd64
Middleware-4                              11.4µs ± 0%    11.5µs ± 0%    ~     (p=0.160 n=6+5)
Middleware_control-4                      2.74µs ± 1%    2.76µs ± 2%    ~     (p=0.240 n=6+6)

name                                    old alloc/op   new alloc/op   delta
pkg:github.com/swaggest/rest/jsonschema goos:linux goarch:amd64
RequestValidator_ValidateRequestData-4    2.46kB ± 0%    2.46kB ± 0%    ~     (all equal)
pkg:github.com/swaggest/rest/request goos:linux goarch:amd64
Decoder_Decode-4                            440B ± 0%      440B ± 0%    ~     (all equal)
DecoderFunc_Decode-4                      1.51kB ± 0%    1.51kB ± 0%    ~     (all equal)
Decoder_Decode_json-4                     12.3kB ± 0%    12.3kB ± 0%    ~     (all equal)
Decoder_Decode_queryObject-4              2.00kB ± 0%    2.00kB ± 0%    ~     (all equal)
Decoder_Decode_jsonParam-4                  736B ± 0%      736B ± 0%    ~     (all equal)
DecoderFactory_SetDecoderFunc-4           1.02kB ± 0%    1.02kB ± 0%    ~     (all equal)
pkg:github.com/swaggest/rest/response/gzip goos:linux goarch:amd64
Middleware-4                              1.33kB ± 1%    1.32kB ± 5%    ~     (p=1.000 n=5+6)
Middleware_control-4                      11.2kB ± 0%    11.2kB ± 0%    ~     (all equal)

name                                    old allocs/op  new allocs/op  delta
pkg:github.com/swaggest/rest/jsonschema goos:linux goarch:amd64
RequestValidator_ValidateRequestData-4      8.00 ± 0%      8.00 ± 0%    ~     (all equal)
pkg:github.com/swaggest/rest/request goos:linux goarch:amd64
Decoder_Decode-4                            4.00 ± 0%      4.00 ± 0%    ~     (all equal)
DecoderFunc_Decode-4                        12.0 ± 0%      12.0 ± 0%    ~     (all equal)
Decoder_Decode_json-4                        177 ± 0%       177 ± 0%    ~     (all equal)
Decoder_Decode_queryObject-4                36.0 ± 0%      36.0 ± 0%    ~     (all equal)
Decoder_Decode_jsonParam-4                  12.0 ± 0%      12.0 ± 0%    ~     (all equal)
DecoderFactory_SetDecoderFunc-4             16.0 ± 0%      16.0 ± 0%    ~     (all equal)
pkg:github.com/swaggest/rest/response/gzip goos:linux goarch:amd64
Middleware-4                                11.0 ± 0%      11.0 ± 0%    ~     (all equal)
Middleware_control-4                        9.00 ± 0%      9.00 ± 0%    ~     (all equal)
```
</details>

<details><summary>Benchmark result</summary>

```
name                                    time/op
pkg:github.com/swaggest/rest/jsonschema goos:linux goarch:amd64
RequestValidator_ValidateRequestData-4  1.09µs ± 1%
pkg:github.com/swaggest/rest/request goos:linux goarch:amd64
Decoder_Decode-4                         503ns ± 1%
DecoderFunc_Decode-4                    1.46µs ± 1%
Decoder_Decode_json-4                   18.5µs ± 1%
Decoder_Decode_queryObject-4            3.95µs ± 0%
Decoder_Decode_jsonParam-4              1.49µs ± 0%
DecoderFactory_SetDecoderFunc-4         1.29µs ± 0%
pkg:github.com/swaggest/rest/response/gzip goos:linux goarch:amd64
Middleware-4                            11.5µs ± 0%
Middleware_control-4                    2.76µs ± 2%

name                                    alloc/op
pkg:github.com/swaggest/rest/jsonschema goos:linux goarch:amd64
RequestValidator_ValidateRequestData-4  2.46kB ± 0%
pkg:github.com/swaggest/rest/request goos:linux goarch:amd64
Decoder_Decode-4                          440B ± 0%
DecoderFunc_Decode-4                    1.51kB ± 0%
Decoder_Decode_json-4                   12.3kB ± 0%
Decoder_Decode_queryObject-4            2.00kB ± 0%
Decoder_Decode_jsonParam-4                736B ± 0%
DecoderFactory_SetDecoderFunc-4         1.02kB ± 0%
pkg:github.com/swaggest/rest/response/gzip goos:linux goarch:amd64
Middleware-4                            1.32kB ± 5%
Middleware_control-4                    11.2kB ± 0%

name                                    allocs/op
pkg:github.com/swaggest/rest/jsonschema goos:linux goarch:amd64
RequestValidator_ValidateRequestData-4    8.00 ± 0%
pkg:github.com/swaggest/rest/request goos:linux goarch:amd64
Decoder_Decode-4                          4.00 ± 0%
DecoderFunc_Decode-4                      12.0 ± 0%
Decoder_Decode_json-4                      177 ± 0%
Decoder_Decode_queryObject-4              36.0 ± 0%
Decoder_Decode_jsonParam-4                12.0 ± 0%
DecoderFactory_SetDecoderFunc-4           16.0 ± 0%
pkg:github.com/swaggest/rest/response/gzip goos:linux goarch:amd64
Middleware-4                              11.0 ± 0%
Middleware_control-4                      9.00 ± 0%
```
</details>
<!-- Sticky Pull Request Commentbench -->
github-actions[bot]: ### Examples Benchmark Result
<details><summary>Benchmark diff with base branch</summary>

```
name                       old time/op    new time/op    delta
pkg:github.com/swaggest/rest/_examples/advanced goos:linux goarch:amd64
_directGzip-4                15.8µs ± 1%    15.8µs ± 1%     ~     (p=0.886 n=4+4)
_directGzipHead-4            15.7µs ± 1%    15.7µs ± 1%     ~     (p=0.841 n=5+5)
_noDirectGzip-4              91.3µs ± 1%    91.1µs ± 1%     ~     (p=0.421 n=5+5)
_directGzip_decode-4          320µs ± 0%     323µs ± 1%     ~     (p=0.056 n=5+5)
_noDirectGzip_decode-4       92.1µs ± 1%    91.8µs ± 1%     ~     (p=0.421 n=5+5)
_jsonBody-4                  33.4µs ± 1%    34.4µs ± 1%   +2.75%  (p=0.008 n=5+5)
_jsonBodyValidation-4        38.5µs ± 2%    40.0µs ± 1%   +3.83%  (p=0.008 n=5+5)
_outputHeaders-4             16.4µs ± 3%    16.5µs ± 3%     ~     (p=0.690 n=5+5)
_requestResponseMapping-4    33.1µs ± 2%    34.3µs ± 0%   +3.56%  (p=0.008 n=5+5)
_validation-4                35.7µs ± 2%    36.7µs ± 2%   +2.83%  (p=0.008 n=5+5)
_noValidation-4              25.4µs ± 2%    26.2µs ± 2%   +3.16%  (p=0.016 n=5+5)
pkg:github.com/swaggest/rest/_examples/advanced-generic-openapi31 goos:linux goarch:amd64
_directGzip-4                16.0µs ± 1%    16.4µs ± 2%   +2.48%  (p=0.008 n=5+5)
_directGzipHead-4            15.9µs ± 1%    16.0µs ± 0%   +0.94%  (p=0.016 n=4+5)
_noDirectGzip-4               102µs ± 1%      91µs ± 0%  -10.72%  (p=0.008 n=5+5)
_directGzip_decode-4          338µs ± 0%     325µs ± 0%   -3.61%  (p=0.008 n=5+5)
_noDirectGzip_decode-4        103µs ± 2%      92µs ± 0%  -11.20%  (p=0.008 n=5+5)
_htmlResponse-4              28.8µs ± 1%    29.3µs ± 1%   +2.01%  (p=0.008 n=5+5)
_jsonBodyManual-4            20.2µs ± 1%    20.6µs ± 1%   +2.01%  (p=0.008 n=5+5)
_jsonBody-4                  30.2µs ± 0%    30.8µs ± 1%   +2.04%  (p=0.008 n=5+5)
_jsonBodyValidation-4        38.9µs ± 1%    39.9µs ± 1%   +2.46%  (p=0.008 n=5+5)
_outputHeaders-4             28.0µs ± 0%    28.8µs ± 1%   +2.70%  (p=0.008 n=5+5)
_requestResponseMapping-4    32.9µs ± 2%    33.7µs ± 2%   +2.37%  (p=0.016 n=5+5)
_validation-4                35.6µs ± 4%    36.4µs ± 0%     ~     (p=0.190 n=5+4)
_noValidation-4              25.2µs ± 1%    25.6µs ± 1%     ~     (p=0.095 n=5+5)
pkg:github.com/swaggest/rest/_examples/task-api/internal/infra/nethttp goos:linux goarch:amd64
_notFoundSrv-4               18.0µs ± 1%    18.0µs ± 2%     ~     (p=0.413 n=4+5)
_ok-4                        17.8µs ± 0%    18.2µs ± 7%     ~     (p=0.310 n=5+5)
_invalidBody-4               26.2µs ± 4%    26.4µs ± 4%     ~     (p=0.548 n=5+5)

name                       old 50%:ms     new 50%:ms     delta
pkg:github.com/swaggest/rest/_examples/advanced goos:linux goarch:amd64
_directGzip-4                  0.72 ± 4%      0.70 ± 6%     ~     (p=0.095 n=5+5)
_directGzipHead-4              0.69 ± 6%      0.67 ± 3%     ~     (p=0.222 n=5+5)
_noDirectGzip-4                4.09 ± 1%      4.23 ± 7%     ~     (p=0.063 n=4+5)
_directGzip_decode-4           11.7 ± 5%      10.3 ±16%     ~     (p=0.056 n=5+5)
_noDirectGzip_decode-4         4.21 ± 5%      4.22 ± 5%     ~     (p=1.000 n=5+5)
_jsonBody-4                    1.47 ± 9%      1.41 ± 6%     ~     (p=0.310 n=5+5)
_jsonBodyValidation-4          1.60 ±11%      1.62 ± 5%     ~     (p=0.548 n=5+5)
_outputHeaders-4               0.71 ± 6%      0.72 ± 6%     ~     (p=0.841 n=5+5)
_requestResponseMapping-4      1.32 ± 7%      1.37 ± 4%     ~     (p=0.421 n=5+5)
_validation-4                  1.44 ± 5%      1.46 ± 4%     ~     (p=0.841 n=5+5)
_noValidation-4                1.07 ± 6%      1.08 ± 4%     ~     (p=1.000 n=5+5)
pkg:github.com/swaggest/rest/_examples/advanced-generic-openapi31 goos:linux goarch:amd64
_directGzip-4                  0.70 ± 5%      0.73 ± 3%     ~     (p=0.310 n=5+5)
_directGzipHead-4              0.70 ± 8%      0.72 ± 5%     ~     (p=0.421 n=5+5)
_noDirectGzip-4                4.73 ± 6%      4.23 ± 6%  -10.52%  (p=0.008 n=5+5)
_directGzip_decode-4           12.4 ± 5%      11.5 ± 3%   -7.52%  (p=0.016 n=5+5)
_noDirectGzip_decode-4         4.58 ± 6%      4.12 ± 5%  -10.02%  (p=0.008 n=5+5)
_htmlResponse-4                1.24 ± 7%      1.27 ± 6%     ~     (p=1.000 n=5+5)
_jsonBodyManual-4              0.92 ± 5%      0.90 ± 4%     ~     (p=0.222 n=5+5)
_jsonBody-4                    1.28 ± 7%      1.30 ± 6%     ~     (p=0.690 n=5+5)
_jsonBodyValidation-4          1.58 ± 2%      1.65 ± 4%   +4.71%  (p=0.016 n=5+5)
_outputHeaders-4               1.18 ± 6%      1.19 ± 6%     ~     (p=1.000 n=5+5)
_requestResponseMapping-4      1.30 ± 5%      1.34 ± 7%     ~     (p=0.690 n=5+5)
_validation-4                  1.44 ±14%      1.47 ± 8%     ~     (p=0.421 n=5+5)
_noValidation-4                1.07 ± 5%      1.11 ± 5%     ~     (p=0.310 n=5+5)
pkg:github.com/swaggest/rest/_examples/task-api/internal/infra/nethttp goos:linux goarch:amd64
_notFoundSrv-4                 0.83 ±10%      0.79 ± 7%     ~     (p=0.421 n=5+5)
_ok-4                          0.79 ± 6%      0.81 ± 6%     ~     (p=0.548 n=5+5)
_invalidBody-4                 1.06 ±11%      1.10 ± 4%     ~     (p=0.151 n=5+5)

name                       old 90%:ms     new 90%:ms     delta
pkg:github.com/swaggest/rest/_examples/advanced goos:linux goarch:amd64
_directGzip-4                  1.42 ± 7%      1.46 ± 7%     ~     (p=0.548 n=5+5)
_directGzipHead-4              1.43 ± 6%      1.37 ± 1%     ~     (p=0.421 n=5+5)
_noDirectGzip-4                8.57 ± 7%      8.74 ± 4%     ~     (p=0.222 n=5+5)
_directGzip_decode-4           31.2 ±10%      32.1 ± 8%     ~     (p=0.548 n=5+5)
_noDirectGzip_decode-4         8.87 ± 1%      8.44 ± 4%   -4.77%  (p=0.008 n=5+5)
_jsonBody-4                    3.16 ± 4%      3.19 ± 4%     ~     (p=1.000 n=5+5)
_jsonBodyValidation-4          3.58 ± 5%      3.59 ± 4%     ~     (p=1.000 n=5+5)
_outputHeaders-4               1.50 ± 5%      1.48 ± 5%     ~     (p=0.548 n=5+5)
_requestResponseMapping-4      3.10 ± 4%      3.26 ± 7%     ~     (p=0.222 n=5+5)
_validation-4                  3.36 ± 3%      3.43 ± 5%     ~     (p=0.222 n=5+5)
_noValidation-4                2.44 ± 4%      2.47 ± 3%     ~     (p=0.841 n=5+5)
pkg:github.com/swaggest/rest/_examples/advanced-generic-openapi31 goos:linux goarch:amd64
_directGzip-4                  1.44 ± 8%      1.51 ± 4%     ~     (p=0.095 n=5+5)
_directGzipHead-4              1.46 ± 7%      1.45 ± 8%     ~     (p=0.690 n=5+5)
_noDirectGzip-4                9.74 ± 4%      8.61 ± 4%  -11.68%  (p=0.008 n=5+5)
_directGzip_decode-4           31.5 ± 3%      30.3 ± 6%     ~     (p=0.056 n=5+5)
_noDirectGzip_decode-4         9.85 ± 4%      8.56 ± 4%  -13.11%  (p=0.008 n=5+5)
_htmlResponse-4                2.68 ± 8%      2.78 ± 4%     ~     (p=0.421 n=5+5)
_jsonBodyManual-4              1.78 ± 3%      1.88 ± 7%     ~     (p=0.056 n=5+5)
_jsonBody-4                    2.80 ± 3%      2.93 ± 8%     ~     (p=0.095 n=5+5)
_jsonBodyValidation-4          3.63 ± 4%      3.67 ± 2%     ~     (p=0.690 n=5+5)
_outputHeaders-4               2.69 ± 5%      2.72 ± 4%     ~     (p=0.548 n=5+5)
_requestResponseMapping-4      3.09 ± 7%      3.17 ± 3%     ~     (p=0.310 n=5+5)
_validation-4                  3.33 ± 8%      3.43 ± 6%     ~     (p=0.310 n=5+5)
_noValidation-4                2.31 ± 3%      2.41 ± 3%     ~     (p=0.056 n=5+5)
pkg:github.com/swaggest/rest/_examples/task-api/internal/infra/nethttp goos:linux goarch:amd64
_notFoundSrv-4                 1.67 ±17%      1.69 ± 5%     ~     (p=0.310 n=5+5)
_ok-4                          1.60 ± 4%      1.64 ±12%     ~     (p=1.000 n=5+5)
_invalidBody-4                 2.48 ± 8%      2.50 ± 4%     ~     (p=1.000 n=5+5)

name                       old 99%:ms     new 99%:ms     delta
pkg:github.com/swaggest/rest/_examples/advanced goos:linux goarch:amd64
_directGzip-4                  2.48 ±24%      2.50 ±24%     ~     (p=0.690 n=5+5)
_directGzipHead-4              2.37 ± 5%      2.32 ± 5%     ~     (p=0.421 n=5+5)
_noDirectGzip-4                13.2 ± 4%      13.3 ± 5%     ~     (p=0.690 n=5+5)
_directGzip_decode-4           57.6 ±10%      58.0 ± 1%     ~     (p=1.000 n=5+4)
_noDirectGzip_decode-4         13.5 ± 7%      13.1 ± 4%     ~     (p=0.286 n=5+5)
_jsonBody-4                    4.92 ± 5%      4.96 ± 4%     ~     (p=1.000 n=5+5)
_jsonBodyValidation-4          5.82 ± 9%      6.23 ± 6%     ~     (p=0.095 n=5+5)
_outputHeaders-4               2.55 ± 7%      2.54 ± 3%     ~     (p=1.000 n=5+5)
_requestResponseMapping-4      5.66 ±16%      5.54 ± 7%     ~     (p=0.841 n=5+5)
_validation-4                  6.05 ± 7%      6.24 ± 7%     ~     (p=0.548 n=5+5)
_noValidation-4                4.25 ±10%      4.35 ± 3%     ~     (p=0.310 n=5+5)
pkg:github.com/swaggest/rest/_examples/advanced-generic-openapi31 goos:linux goarch:amd64
_directGzip-4                  2.38 ± 4%      2.51 ±12%     ~     (p=0.095 n=5+5)
_directGzipHead-4              2.56 ±17%      2.38 ± 3%     ~     (p=0.151 n=5+5)
_noDirectGzip-4                15.0 ± 3%      13.3 ± 6%  -11.43%  (p=0.008 n=5+5)
_directGzip_decode-4           60.6 ± 7%      56.8 ± 4%   -6.27%  (p=0.032 n=5+5)
_noDirectGzip_decode-4         14.8 ± 7%      13.5 ± 3%   -9.29%  (p=0.008 n=5+5)
_htmlResponse-4                4.65 ± 2%      4.76 ± 8%     ~     (p=0.690 n=5+5)
_jsonBodyManual-4              3.16 ± 6%      3.23 ± 3%     ~     (p=0.548 n=5+5)
_jsonBody-4                    4.91 ± 5%      5.21 ± 8%     ~     (p=0.222 n=5+5)
_jsonBodyValidation-4          6.46 ±11%      6.30 ± 3%     ~     (p=0.690 n=5+5)
_outputHeaders-4               4.59 ± 3%      4.63 ± 6%     ~     (p=0.841 n=5+5)
_requestResponseMapping-4      5.25 ±11%      5.14 ± 5%     ~     (p=0.548 n=5+5)
_validation-4                  5.56 ±11%      5.80 ±12%     ~     (p=0.548 n=5+5)
_noValidation-4                4.17 ± 5%      4.11 ± 6%     ~     (p=0.690 n=5+5)
pkg:github.com/swaggest/rest/_examples/task-api/internal/infra/nethttp goos:linux goarch:amd64
_notFoundSrv-4                 2.82 ±26%      2.71 ± 5%     ~     (p=0.690 n=5+5)
_ok-4                          2.63 ± 6%      2.70 ±20%     ~     (p=1.000 n=5+5)
_invalidBody-4                 4.35 ± 7%      4.40 ± 7%     ~     (p=0.690 n=5+5)

name                       old 99.9%:ms   new 99.9%:ms   delta
pkg:github.com/swaggest/rest/_examples/advanced goos:linux goarch:amd64
_directGzip-4                 5.31 ±101%      4.81 ±62%     ~     (p=0.548 n=5+5)
_directGzipHead-4              4.36 ±39%      4.21 ±17%     ~     (p=1.000 n=5+5)
_noDirectGzip-4                16.4 ± 7%      17.1 ± 7%     ~     (p=0.222 n=5+5)
_directGzip_decode-4           80.1 ±18%      81.3 ± 9%     ~     (p=0.548 n=5+5)
_noDirectGzip_decode-4         17.6 ±10%      16.8 ± 7%     ~     (p=0.222 n=5+5)
_jsonBody-4                    7.86 ± 4%      7.79 ±14%     ~     (p=0.841 n=5+5)
_jsonBodyValidation-4          9.10 ±19%      9.16 ± 5%     ~     (p=0.690 n=5+5)
_outputHeaders-4               5.01 ±20%      5.49 ±13%     ~     (p=0.421 n=5+5)
_requestResponseMapping-4      8.88 ± 5%      8.81 ± 7%     ~     (p=0.841 n=5+5)
_validation-4                  10.0 ±10%       9.6 ± 2%     ~     (p=0.222 n=5+5)
_noValidation-4                8.45 ±20%      7.04 ±13%  -16.61%  (p=0.032 n=5+5)
pkg:github.com/swaggest/rest/_examples/advanced-generic-openapi31 goos:linux goarch:amd64
_directGzip-4                  3.90 ±22%      4.33 ±19%     ~     (p=0.310 n=5+5)
_directGzipHead-4              5.60 ±42%      4.33 ±22%     ~     (p=0.056 n=5+5)
_noDirectGzip-4                19.6 ±10%      16.7 ± 4%  -15.21%  (p=0.008 n=5+5)
_directGzip_decode-4           79.7 ± 3%      71.1 ±11%  -10.83%  (p=0.032 n=5+5)
_noDirectGzip_decode-4         22.8 ±39%      17.3 ±11%  -24.16%  (p=0.016 n=5+5)
_htmlResponse-4                7.90 ±14%      7.98 ±15%     ~     (p=1.000 n=5+5)
_jsonBodyManual-4              6.12 ± 9%      6.35 ±34%     ~     (p=0.548 n=5+5)
_jsonBody-4                    8.45 ±20%      8.67 ±17%     ~     (p=0.690 n=5+5)
_jsonBodyValidation-4          10.0 ± 7%      10.1 ± 5%     ~     (p=1.000 n=5+5)
_outputHeaders-4               7.66 ±12%      7.81 ±21%     ~     (p=0.841 n=5+5)
_requestResponseMapping-4      8.87 ±12%      8.88 ±15%     ~     (p=1.000 n=5+5)
_validation-4                  9.24 ±25%      9.91 ±35%     ~     (p=0.841 n=5+5)
_noValidation-4                6.17 ±14%      6.37 ± 9%     ~     (p=0.841 n=5+5)
pkg:github.com/swaggest/rest/_examples/task-api/internal/infra/nethttp goos:linux goarch:amd64
_notFoundSrv-4                 5.15 ±51%      4.70 ±38%     ~     (p=1.000 n=5+5)
_ok-4                          3.86 ± 8%      4.92 ±90%     ~     (p=1.000 n=5+5)
_invalidBody-4                 6.75 ±13%      7.13 ±20%     ~     (p=0.690 n=5+5)

name                       old B:rcvd/op  new B:rcvd/op  delta
pkg:github.com/swaggest/rest/_examples/advanced goos:linux goarch:amd64
_directGzip-4                   630 ± 0%       630 ± 0%     ~     (all equal)
_directGzipHead-4               174 ± 0%       174 ± 0%     ~     (all equal)
_noDirectGzip-4               1.03k ± 0%     1.03k ± 0%     ~     (all equal)
_directGzip_decode-4            630 ± 0%       630 ± 0%     ~     (all equal)
_noDirectGzip_decode-4        1.03k ± 0%     1.03k ± 0%     ~     (all equal)
_jsonBody-4                     199 ± 0%       199 ± 0%     ~     (all equal)
_jsonBodyValidation-4           185 ± 0%       185 ± 0%     ~     (all equal)
_outputHeaders-4                146 ± 0%       146 ± 0%     ~     (all equal)
_requestResponseMapping-4      94.0 ± 0%      94.0 ± 0%     ~     (all equal)
_validation-4                   168 ± 0%       168 ± 0%     ~     (all equal)
_noValidation-4                 168 ± 0%       168 ± 0%     ~     (all equal)
pkg:github.com/swaggest/rest/_examples/advanced-generic-openapi31 goos:linux goarch:amd64
_directGzip-4                   638 ± 0%       638 ± 0%     ~     (all equal)
_directGzipHead-4               182 ± 0%       182 ± 0%     ~     (all equal)
_noDirectGzip-4               1.04k ± 0%     1.04k ± 0%     ~     (all equal)
_directGzip_decode-4            638 ± 0%       638 ± 0%     ~     (all equal)
_noDirectGzip_decode-4        1.04k ± 0%     1.04k ± 0%     ~     (all equal)
_htmlResponse-4                 355 ± 0%       355 ± 0%     ~     (all equal)
_jsonBodyManual-4               207 ± 0%       207 ± 0%     ~     (all equal)
_jsonBody-4                     207 ± 0%       207 ± 0%     ~     (all equal)
_jsonBodyValidation-4           193 ± 0%       193 ± 0%     ~     (all equal)
_outputHeaders-4                214 ± 0%       214 ± 0%     ~     (all equal)
_requestResponseMapping-4       108 ± 0%       108 ± 0%     ~     (all equal)
_validation-4                   176 ± 0%       176 ± 0%     ~     (all equal)
_noValidation-4                 176 ± 0%       176 ± 0%     ~     (all equal)
pkg:github.com/swaggest/rest/_examples/task-api/internal/infra/nethttp goos:linux goarch:amd64
_notFoundSrv-4                  322 ± 0%       322 ± 0%     ~     (all equal)
_ok-4                           344 ± 0%       344 ± 0%     ~     (p=0.333 n=4+5)
_invalidBody-4                  420 ± 0%       420 ± 0%     ~     (all equal)

name                       old B:sent/op  new B:sent/op  delta
pkg:github.com/swaggest/rest/_examples/advanced goos:linux goarch:amd64
_directGzip-4                   103 ± 0%       103 ± 0%     ~     (all equal)
_directGzipHead-4               104 ± 0%       104 ± 0%     ~     (all equal)
_noDirectGzip-4                 117 ± 0%       117 ± 0%     ~     (all equal)
_directGzip_decode-4            116 ± 0%       116 ± 0%     ~     (all equal)
_noDirectGzip_decode-4          130 ± 0%       130 ± 0%     ~     (all equal)
_jsonBody-4                     188 ± 0%       188 ± 0%     ~     (all equal)
_jsonBodyValidation-4           192 ± 0%       192 ± 0%     ~     (all equal)
_outputHeaders-4               77.0 ± 0%      77.0 ± 0%     ~     (all equal)
_requestResponseMapping-4       169 ± 0%       169 ± 0%     ~     (all equal)
_validation-4                   170 ± 0%       170 ± 0%     ~     (all equal)
_noValidation-4                 173 ± 0%       173 ± 0%     ~     (all equal)
pkg:github.com/swaggest/rest/_examples/advanced-generic-openapi31 goos:linux goarch:amd64
_directGzip-4                   103 ± 0%       103 ± 0%     ~     (all equal)
_directGzipHead-4               104 ± 0%       104 ± 0%     ~     (all equal)
_noDirectGzip-4                 117 ± 0%       117 ± 0%     ~     (all equal)
_directGzip_decode-4            116 ± 0%       116 ± 0%     ~     (all equal)
_noDirectGzip_decode-4          130 ± 0%       130 ± 0%     ~     (all equal)
_htmlResponse-4                 108 ± 0%       108 ± 0%     ~     (all equal)
_jsonBodyManual-4               195 ± 0%       195 ± 0%     ~     (all equal)
_jsonBody-4                     188 ± 0%       188 ± 0%     ~     (all equal)
_jsonBodyValidation-4           192 ± 0%       192 ± 0%     ~     (all equal)
_outputHeaders-4               88.0 ± 0%      88.0 ± 0%     ~     (all equal)
_requestResponseMapping-4       169 ± 0%       169 ± 0%     ~     (all equal)
_validation-4                   170 ± 0%       170 ± 0%     ~     (all equal)
_noValidation-4                 173 ± 0%       173 ± 0%     ~     (all equal)
pkg:github.com/swaggest/rest/_examples/task-api/internal/infra/nethttp goos:linux goarch:amd64
_notFoundSrv-4                 74.0 ± 0%      74.0 ± 0%     ~     (all equal)
_ok-4                          74.0 ± 0%      74.0 ± 0%     ~     (all equal)
_invalidBody-4                  137 ± 0%       137 ± 0%     ~     (all equal)

name                       old rps        new rps        delta
pkg:github.com/swaggest/rest/_examples/advanced goos:linux goarch:amd64
_directGzip-4                 62.0k ± 8%     63.5k ± 1%     ~     (p=0.556 n=5+4)
_directGzipHead-4             63.8k ± 1%     63.8k ± 1%     ~     (p=0.841 n=5+5)
_noDirectGzip-4               10.9k ± 1%     11.0k ± 1%     ~     (p=0.421 n=5+5)
_directGzip_decode-4          3.13k ± 0%     3.10k ± 1%     ~     (p=0.056 n=5+5)
_noDirectGzip_decode-4        10.9k ± 1%     10.9k ± 1%     ~     (p=0.421 n=5+5)
_jsonBody-4                   29.9k ± 1%     29.1k ± 1%   -2.68%  (p=0.008 n=5+5)
_jsonBodyValidation-4         26.0k ± 2%     25.0k ± 1%   -3.70%  (p=0.008 n=5+5)
_outputHeaders-4              61.0k ± 3%     60.8k ± 3%     ~     (p=0.690 n=5+5)
_requestResponseMapping-4     30.2k ± 2%     29.2k ± 0%   -3.46%  (p=0.008 n=5+5)
_validation-4                 28.0k ± 2%     27.2k ± 2%   -2.76%  (p=0.008 n=5+5)
_noValidation-4               39.4k ± 2%     38.2k ± 2%   -3.06%  (p=0.016 n=5+5)
pkg:github.com/swaggest/rest/_examples/advanced-generic-openapi31 goos:linux goarch:amd64
_directGzip-4                 62.7k ± 1%     61.2k ± 2%   -2.40%  (p=0.008 n=5+5)
_directGzipHead-4             62.9k ± 1%     62.3k ± 0%   -0.93%  (p=0.016 n=4+5)
_noDirectGzip-4               9.77k ± 1%    10.94k ± 0%  +12.01%  (p=0.008 n=5+5)
_directGzip_decode-4          2.96k ± 0%     3.07k ± 0%   +3.75%  (p=0.008 n=5+5)
_noDirectGzip_decode-4        9.70k ± 2%    10.92k ± 0%  +12.60%  (p=0.008 n=5+5)
_htmlResponse-4               34.8k ± 1%     34.1k ± 1%   -1.97%  (p=0.008 n=5+5)
_jsonBodyManual-4             49.5k ± 1%     48.5k ± 1%   -1.97%  (p=0.008 n=5+5)
_jsonBody-4                   33.1k ± 0%     32.4k ± 1%   -2.00%  (p=0.008 n=5+5)
_jsonBodyValidation-4         25.7k ± 1%     25.1k ± 1%   -2.39%  (p=0.008 n=5+5)
_outputHeaders-4              35.7k ± 0%     34.7k ± 1%   -2.62%  (p=0.008 n=5+5)
_requestResponseMapping-4     30.4k ± 2%     29.7k ± 2%   -2.32%  (p=0.016 n=5+5)
_validation-4                 28.1k ± 4%     27.5k ± 0%     ~     (p=0.190 n=5+4)
_noValidation-4               39.6k ± 1%     39.1k ± 1%     ~     (p=0.095 n=5+5)
pkg:github.com/swaggest/rest/_examples/task-api/internal/infra/nethttp goos:linux goarch:amd64
_notFoundSrv-4                55.5k ± 1%     55.6k ± 2%     ~     (p=0.413 n=4+5)
_ok-4                         56.1k ± 0%     55.1k ± 6%     ~     (p=0.310 n=5+5)
_invalidBody-4                38.2k ± 4%     37.9k ± 4%     ~     (p=0.548 n=5+5)

name                       old alloc/op   new alloc/op   delta
pkg:github.com/swaggest/rest/_examples/advanced goos:linux goarch:amd64
_directGzip-4                3.86kB ± 0%    3.86kB ± 0%     ~     (p=0.063 n=5+5)
_directGzipHead-4            3.85kB ± 0%    3.86kB ± 0%   +0.14%  (p=0.008 n=5+5)
_noDirectGzip-4              6.50kB ±24%    6.67kB ±29%     ~     (p=0.730 n=5+5)
_directGzip_decode-4          404kB ± 0%     404kB ± 0%     ~     (p=0.421 n=5+5)
_noDirectGzip_decode-4       5.82kB ±10%    5.88kB ± 8%     ~     (p=0.690 n=5+5)
_jsonBody-4                  13.2kB ± 0%    13.2kB ± 0%   +0.17%  (p=0.008 n=5+5)
_jsonBodyValidation-4        19.0kB ± 0%    19.0kB ± 0%   +0.20%  (p=0.008 n=5+5)
_outputHeaders-4             3.57kB ± 0%    3.57kB ± 0%   +0.08%  (p=0.016 n=5+5)
_requestResponseMapping-4    16.7kB ± 0%    16.7kB ± 0%   +0.17%  (p=0.008 n=5+5)
_validation-4                16.6kB ± 0%    16.6kB ± 0%     ~     (p=0.079 n=5+5)
_noValidation-4              7.78kB ± 0%    7.79kB ± 0%   +0.12%  (p=0.008 n=5+5)
pkg:github.com/swaggest/rest/_examples/advanced-generic-openapi31 goos:linux goarch:amd64
_directGzip-4                3.89kB ± 0%    3.87kB ± 0%   -0.33%  (p=0.008 n=5+5)
_directGzipHead-4            3.88kB ± 0%    3.87kB ± 0%   -0.36%  (p=0.008 n=5+5)
_noDirectGzip-4              7.05kB ±17%    7.01kB ±25%     ~     (p=1.000 n=5+5)
_directGzip_decode-4          404kB ± 0%     404kB ± 0%   +0.04%  (p=0.016 n=5+5)
_noDirectGzip_decode-4       6.11kB ± 9%    6.22kB ± 6%     ~     (p=1.000 n=5+5)
_htmlResponse-4              8.08kB ± 0%    8.07kB ± 0%   -0.12%  (p=0.008 n=5+5)
_jsonBodyManual-4            4.50kB ± 0%    4.49kB ± 0%   -0.24%  (p=0.008 n=5+5)
_jsonBody-4                  10.3kB ± 0%    10.3kB ± 0%   -0.05%  (p=0.032 n=5+5)
_jsonBodyValidation-4        19.1kB ± 0%    19.1kB ± 0%     ~     (p=0.452 n=5+5)
_outputHeaders-4             10.4kB ± 0%    10.4kB ± 0%   -0.06%  (p=0.016 n=5+5)
_requestResponseMapping-4    16.7kB ± 0%    16.7kB ± 0%     ~     (p=0.508 n=5+4)
_validation-4                16.6kB ± 0%    16.6kB ± 0%     ~     (p=0.206 n=5+5)
_noValidation-4              7.84kB ± 0%    7.82kB ± 0%   -0.16%  (p=0.016 n=5+5)
pkg:github.com/swaggest/rest/_examples/task-api/internal/infra/nethttp goos:linux goarch:amd64
_notFoundSrv-4               4.65kB ± 0%    4.65kB ± 0%     ~     (p=0.056 n=5+5)
_ok-4                        4.55kB ± 0%    4.56kB ± 0%     ~     (p=0.086 n=4+4)
_invalidBody-4               8.27kB ± 0%    8.28kB ± 0%     ~     (p=0.686 n=4+4)

name                       old allocs/op  new allocs/op  delta
pkg:github.com/swaggest/rest/_examples/advanced goos:linux goarch:amd64
_directGzip-4                  42.0 ± 0%      42.0 ± 0%     ~     (all equal)
_directGzipHead-4              42.0 ± 0%      42.0 ± 0%     ~     (all equal)
_noDirectGzip-4                49.2 ± 4%      49.2 ± 4%     ~     (p=1.000 n=5+5)
_directGzip_decode-4            503 ± 0%       503 ± 0%     ~     (p=0.881 n=5+5)
_noDirectGzip_decode-4         50.0 ± 0%      50.0 ± 0%     ~     (all equal)
_jsonBody-4                     128 ± 0%       128 ± 0%     ~     (all equal)
_jsonBodyValidation-4           186 ± 0%       186 ± 0%     ~     (all equal)
_outputHeaders-4               36.0 ± 0%      36.0 ± 0%     ~     (all equal)
_requestResponseMapping-4       124 ± 0%       124 ± 0%     ~     (all equal)
_validation-4                   154 ± 0%       155 ± 0%     ~     (p=0.167 n=5+5)
_noValidation-4                91.0 ± 0%      91.0 ± 0%     ~     (all equal)
pkg:github.com/swaggest/rest/_examples/advanced-generic-openapi31 goos:linux goarch:amd64
_directGzip-4                  44.0 ± 0%      43.0 ± 0%   -2.27%  (p=0.008 n=5+5)
_directGzipHead-4              44.0 ± 0%      43.0 ± 0%   -2.27%  (p=0.008 n=5+5)
_noDirectGzip-4                51.2 ± 4%      50.2 ± 4%     ~     (p=0.151 n=5+5)
_directGzip_decode-4            505 ± 0%       504 ± 0%     ~     (p=0.167 n=5+5)
_noDirectGzip_decode-4         52.0 ± 0%      51.0 ± 0%   -1.92%  (p=0.008 n=5+5)
_htmlResponse-4                 145 ± 0%       144 ± 0%   -0.69%  (p=0.008 n=5+5)
_jsonBodyManual-4              49.0 ± 0%      48.0 ± 0%   -2.04%  (p=0.008 n=5+5)
_jsonBody-4                     100 ± 0%        99 ± 0%   -1.00%  (p=0.008 n=5+5)
_jsonBodyValidation-4           188 ± 0%       187 ± 0%   -0.53%  (p=0.008 n=5+5)
_outputHeaders-4                113 ± 0%       112 ± 0%   -0.88%  (p=0.008 n=5+5)
_requestResponseMapping-4       126 ± 0%       125 ± 0%   -0.79%  (p=0.008 n=5+5)
_validation-4                   156 ± 0%       155 ± 0%   -0.64%  (p=0.000 n=5+4)
_noValidation-4                93.0 ± 0%      92.0 ± 0%   -1.08%  (p=0.008 n=5+5)
pkg:github.com/swaggest/rest/_examples/task-api/internal/infra/nethttp goos:linux goarch:amd64
_notFoundSrv-4                 53.0 ± 0%      53.0 ± 0%     ~     (all equal)
_ok-4                          49.0 ± 0%      49.0 ± 0%     ~     (all equal)
_invalidBody-4                 97.0 ± 0%      97.0 ± 0%     ~     (all equal)
```
</details>
<!-- Sticky Pull Request Commentbench-examples -->

Patch:
diff --git a/.github/workflows/bench.yml b/.github/workflows/bench.yml
index 51fbc24..f118ccd 100644
--- a/.github/workflows/bench.yml
+++ b/.github/workflows/bench.yml
@@ -21,7 +21,7 @@ env:
   GO111MODULE: "on"
   CACHE_BENCHMARK: "off"    # Enables benchmark result reuse between runs, may skew latency results.
   RUN_BASE_BENCHMARK: "on"  # Runs benchmark for PR base in case benchmark result is missing.
-  GO_VERSION: 1.21.x
+  GO_VERSION: 1.22.x
 jobs:
   bench:
     runs-on: ubuntu-latest
diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml
index d2e4b61..6239219 100644
--- a/.github/workflows/golangci-lint.yml
+++ b/.github/workflows/golangci-lint.yml
@@ -21,13 +21,13 @@ jobs:
     steps:
       - uses: actions/setup-go@v3
         with:
-          go-version: 1.21.x
+          go-version: 1.22.x
       - uses: actions/checkout@v2
       - name: golangci-lint
-        uses: golangci/golangci-lint-action@v3.7.0
+        uses: golangci/golangci-lint-action@v4.0.0
         with:
           # Required: the version of golangci-lint is required and must be specified without patch version: we always use the latest patch version.
-          version: v1.54.1
+          version: v1.56.2
 
           # Optional: working directory, useful for monorepos
           # working-directory: somedir
diff --git a/.github/workflows/gorelease.yml b/.github/workflows/gorelease.yml
index 97ebe87..6356a9d 100644
--- a/.github/workflows/gorelease.yml
+++ b/.github/workflows/gorelease.yml
@@ -9,7 +9,7 @@ concurrency:
   cancel-in-progress: true
 
 env:
-  GO_VERSION: 1.21.x
+  GO_VERSION: 1.22.x
 jobs:
   gorelease:
     runs-on: ubuntu-latest
diff --git a/.golangci.yml b/.golangci.yml
index 6f8655e..3dcca94 100644
--- a/.golangci.yml
+++ b/.golangci.yml
@@ -73,5 +73,6 @@ issues:
     - linters:
         - errcheck # Error checking omitted for brevity.
         - gosec
+        - revive
       path: "example_"
 
diff --git a/Makefile b/Makefile
index 73ced0a..9d78891 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-#GOLANGCI_LINT_VERSION := "v1.54.1" # Optional configuration to pinpoint golangci-lint version.
+#GOLANGCI_LINT_VERSION := "v1.56.2" # Optional configuration to pinpoint golangci-lint version.
 
 # The head of Makefile determines location of dev-go to include standard targets.
 GO ?= go
diff --git a/_examples/go.mod b/_examples/go.mod
index 7875314..395d380 100644
--- a/_examples/go.mod
+++ b/_examples/go.mod
@@ -6,27 +6,27 @@ replace github.com/swaggest/rest => ../
 
 require (
 	github.com/bool64/ctxd v1.2.1
-	github.com/bool64/dev v0.2.32
+	github.com/bool64/dev v0.2.34
 	github.com/bool64/httpmock v0.1.13
 	github.com/bool64/httptestbench v0.1.4
 	github.com/gin-gonic/gin v1.9.1
-	github.com/go-chi/chi/v5 v5.0.10
-	github.com/go-chi/jwtauth/v5 v5.1.1
-	github.com/google/uuid v1.3.0
+	github.com/go-chi/chi/v5 v5.0.12
+	github.com/go-chi/jwtauth/v5 v5.3.0
+	github.com/google/uuid v1.6.0
 	github.com/kelseyhightower/envconfig v1.4.0
-	github.com/rs/cors v1.9.0
-	github.com/stretchr/testify v1.8.4
+	github.com/rs/cors v1.10.1
+	github.com/stretchr/testify v1.9.0
 	github.com/swaggest/assertjson v1.9.0
-	github.com/swaggest/jsonschema-go v0.3.64
-	github.com/swaggest/openapi-go v0.2.43
+	github.com/swaggest/jsonschema-go v0.3.66
+	github.com/swaggest/openapi-go v0.2.46
 	github.com/swaggest/rest v0.0.0-00010101000000-000000000000
-	github.com/swaggest/swgui v1.7.3
-	github.com/swaggest/usecase v1.3.0
-	github.com/valyala/fasthttp v1.48.0
+	github.com/swaggest/swgui v1.8.0
+	github.com/swaggest/usecase v1.3.1
+	github.com/valyala/fasthttp v1.52.0
 )
 
 require (
-	github.com/andybalholm/brotli v1.0.5 // indirect
+	github.com/andybalholm/brotli v1.1.0 // indirect
 	github.com/bool64/shared v0.1.5 // indirect
 	github.com/bytedance/sonic v1.9.1 // indirect
 	github.com/cespare/xxhash/v2 v2.2.0 // indirect
@@ -42,14 +42,14 @@ require (
 	github.com/goccy/go-json v0.10.2 // indirect
 	github.com/iancoleman/orderedmap v0.3.0 // indirect
 	github.com/json-iterator/go v1.1.12 // indirect
-	github.com/klauspost/compress v1.16.7 // indirect
+	github.com/klauspost/compress v1.17.7 // indirect
 	github.com/klauspost/cpuid/v2 v2.2.4 // indirect
 	github.com/leodido/go-urn v1.2.4 // indirect
-	github.com/lestrrat-go/blackmagic v1.0.1 // indirect
+	github.com/lestrrat-go/blackmagic v1.0.2 // indirect
 	github.com/lestrrat-go/httpcc v1.0.1 // indirect
 	github.com/lestrrat-go/httprc v1.0.4 // indirect
 	github.com/lestrrat-go/iter v1.0.2 // indirect
-	github.com/lestrrat-go/jwx/v2 v2.0.11 // indirect
+	github.com/lestrrat-go/jwx/v2 v2.0.20 // indirect
 	github.com/lestrrat-go/option v1.0.1 // indirect
 	github.com/mattn/go-isatty v0.0.19 // indirect
 	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
@@ -70,10 +70,10 @@ require (
 	github.com/yudai/gojsondiff v1.0.0 // indirect
 	github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 // indirect
 	golang.org/x/arch v0.3.0 // indirect
-	golang.org/x/crypto v0.10.0 // indirect
-	golang.org/x/net v0.10.0 // indirect
-	golang.org/x/sys v0.9.0 // indirect
-	golang.org/x/text v0.13.0 // indirect
+	golang.org/x/crypto v0.20.0 // indirect
+	golang.org/x/net v0.21.0 // indirect
+	golang.org/x/sys v0.17.0 // indirect
+	golang.org/x/text v0.14.0 // indirect
 	google.golang.org/protobuf v1.30.0 // indirect
 	gopkg.in/yaml.v2 v2.4.0 // indirect
 	gopkg.in/yaml.v3 v3.0.1 // indirect
diff --git a/_examples/go.sum b/_examples/go.sum
index c68d7ee..b181883 100644
--- a/_examples/go.sum
+++ b/_examples/go.sum
@@ -1,11 +1,11 @@
-github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs=
-github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
+github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M=
+github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY=
 github.com/bool64/ctxd v1.2.1 h1:hARFteq0zdn4bwfmxLhak3fXFuvtJVKDH2X29VV/2ls=
 github.com/bool64/ctxd v1.2.1/go.mod h1:ZG6QkeGVLTiUl2mxPpyHmFhDzFZCyocr9hluBV3LYuc=
 github.com/bool64/dev v0.2.5/go.mod h1:cTHiTDNc8EewrQPy3p1obNilpMpdmlUesDkFTF2zRWU=
 github.com/bool64/dev v0.2.25/go.mod h1:iJbh1y/HkunEPhgebWRNcs8wfGq7sjvJ6W5iabL8ACg=
-github.com/bool64/dev v0.2.32 h1:DRZtloaoH1Igky3zphaUHV9+SLIV2H3lsf78JsJHFg0=
-github.com/bool64/dev v0.2.32/go.mod h1:iJbh1y/HkunEPhgebWRNcs8wfGq7sjvJ6W5iabL8ACg=
+github.com/bool64/dev v0.2.34 h1:P9n315P8LdpxusnYQ0X7MP1CZXwBK5ae5RZrd+GdSZE=
+github.com/bool64/dev v0.2.34/go.mod h1:iJbh1y/HkunEPhgebWRNcs8wfGq7sjvJ6W5iabL8ACg=
 github.com/bool64/httpmock v0.1.13 h1:3QpRXQ5kwHLW8xnVT8+Ug7VS6RerhdEFV+RWYC61aVo=
 github.com/bool64/httpmock v0.1.13/go.mod h1:YMTLaypQ3o5DAx78eA/kDRSLec0f+42sLMDmHdmeY+E=
 github.com/bool64/httptestbench v0.1.4 h1:35f9RwWqcnQRXM+sA+GUhWVGSa6XEFlKpNSH9oYzOjI=
@@ -23,7 +23,6 @@ github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583j
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo=
 github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs=
 github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0=
 github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI=
@@ -34,10 +33,10 @@ github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE
 github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
 github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg=
 github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU=
-github.com/go-chi/chi/v5 v5.0.10 h1:rLz5avzKpjqxrYwXNfmjkrYYXOyLJd37pz53UFHC6vk=
-github.com/go-chi/chi/v5 v5.0.10/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
-github.com/go-chi/jwtauth/v5 v5.1.1 h1:Pjixqu5YkjE9sCLpzE01L0Q4sQzJIPdo7uz9r8ftp/c=
-github.com/go-chi/jwtauth/v5 v5.1.1/go.mod h1:CYP1WSbzD4MPuKCr537EM3kfFhSQgpUEtMJFuYJjqWU=
+github.com/go-chi/chi/v5 v5.0.12 h1:9euLV5sTrTNTRUU9POmDUvfxyj6LAABLUcEWO+JJb4s=
+github.com/go-chi/chi/v5 v5.0.12/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
+github.com/go-chi/jwtauth/v5 v5.3.0 h1:X7RKGks1lrVeIe2omGyz47pNaNjG2YmwlRN5UKhN8qg=
+github.com/go-chi/jwtauth/v5 v5.3.0/go.mod h1:2PoGm/KbnzRN9ILY6HFZAI6fTnb1gEZAKogAyqkd6fY=
 github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
 github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
 github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
@@ -51,16 +50,16 @@ github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaS
 github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
 github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
-github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
-github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
+github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/iancoleman/orderedmap v0.3.0 h1:5cbR2grmZR/DiVt+VJopEhtVs9YGInGIxAoMJn+Ichc=
 github.com/iancoleman/orderedmap v0.3.0/go.mod h1:XuLcCUkdL5owUCQeF2Ue9uuw1EptkJDkXXS7VoV7XGE=
 github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
 github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
 github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8=
 github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg=
-github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I=
-github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
+github.com/klauspost/compress v1.17.7 h1:ehO88t2UGzQK66LMdE8tibEd1ErmzZjNEqWkjLAKQQg=
+github.com/klauspost/compress v1.17.7/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
 github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
 github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk=
 github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY=
@@ -71,17 +70,16 @@ github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
 github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
 github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
 github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
-github.com/lestrrat-go/blackmagic v1.0.1 h1:lS5Zts+5HIC/8og6cGHb0uCcNCa3OUt1ygh3Qz2Fe80=
-github.com/lestrrat-go/blackmagic v1.0.1/go.mod h1:UrEqBzIR2U6CnzVyUtfM6oZNMt/7O7Vohk2J0OGSAtU=
+github.com/lestrrat-go/blackmagic v1.0.2 h1:Cg2gVSc9h7sz9NOByczrbUvLopQmXrfFx//N+AkAr5k=
+github.com/lestrrat-go/blackmagic v1.0.2/go.mod h1:UrEqBzIR2U6CnzVyUtfM6oZNMt/7O7Vohk2J0OGSAtU=
 github.com/lestrrat-go/httpcc v1.0.1 h1:ydWCStUeJLkpYyjLDHihupbn2tYmZ7m22BGkcvZZrIE=
 github.com/lestrrat-go/httpcc v1.0.1/go.mod h1:qiltp3Mt56+55GPVCbTdM9MlqhvzyuL6W/NMDA8vA5E=
 github.com/lestrrat-go/httprc v1.0.4 h1:bAZymwoZQb+Oq8MEbyipag7iSq6YIga8Wj6GOiJGdI8=
 github.com/lestrrat-go/httprc v1.0.4/go.mod h1:mwwz3JMTPBjHUkkDv/IGJ39aALInZLrhBp0X7KGUZlo=
 github.com/lestrrat-go/iter v1.0.2 h1:gMXo1q4c2pHmC3dn8LzRhJfP1ceCbgSiT9lUydIzltI=
 github.com/lestrrat-go/iter v1.0.2/go.mod h1:Momfcq3AnRlRjI5b5O8/G5/BvpzrhoFTZcn06fEOPt4=
-github.com/lestrrat-go/jwx/v2 v2.0.11 h1:ViHMnaMeaO0qV16RZWBHM7GTrAnX2aFLVKofc7FuKLQ=
-github.com/lestrrat-go/jwx/v2 v2.0.11/go.mod h1:ZtPtMFlrfDrH2Y0iwfa3dRFn8VzwBrB+cyrm3IBWdDg=
-github.com/lestrrat-go/option v1.0.0/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I=
+github.com/lestrrat-go/jwx/v2 v2.0.20 h1:sAgXuWS/t8ykxS9Bi2Qtn5Qhpakw1wrcjxChudjolCc=
+github.com/lestrrat-go/jwx/v2 v2.0.20/go.mod h1:UlCSmKqw+agm5BsOBfEAbTvKsEApaGNqHAEUTv5PJC4=
 github.com/lestrrat-go/option v1.0.1 h1:oAzP2fvZGQKWkvHa1/SAcFolBEca1oN+mQ7eooNBEYU=
 github.com/lestrrat-go/option v1.0.1/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I=
 github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8=
@@ -99,8 +97,8 @@ github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZ
 github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/rs/cors v1.9.0 h1:l9HGsTsHJcvW14Nk7J9KFz8bzeAWXn3CG6bgt7LsrAE=
-github.com/rs/cors v1.9.0/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU=
+github.com/rs/cors v1.10.1 h1:L0uuZVXIKlI1SShY2nhFfo44TYvDPQ1w4oFkUJNfhyo=
+github.com/rs/cors v1.10.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU=
 github.com/santhosh-tekuri/jsonschema/v3 v3.1.0 h1:levPcBfnazlA1CyCMC3asL/QLZkq9pa8tQZOH513zQw=
 github.com/santhosh-tekuri/jsonschema/v3 v3.1.0/go.mod h1:8kzK2TC0k0YjOForaAHdNEa7ik0fokNa2k30BKJ/W7Y=
 github.com/segmentio/asm v1.2.0 h1:9BQrFxC+YOHJlTlHGkTrFWf59nbL3XnCoFLTwDCI7ys=
@@ -119,30 +117,30 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO
 github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
 github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
 github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
-github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
-github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
+github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
+github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
 github.com/swaggest/assertjson v1.9.0 h1:dKu0BfJkIxv/xe//mkCrK5yZbs79jL7OVf9Ija7o2xQ=
 github.com/swaggest/assertjson v1.9.0/go.mod h1:b+ZKX2VRiUjxfUIal0HDN85W0nHPAYUbYH5WkkSsFsU=
 github.com/swaggest/form/v5 v5.1.1 h1:ct6/rOQBGrqWUQ0FUv3vW5sHvTUb31AwTUWj947N6cY=
 github.com/swaggest/form/v5 v5.1.1/go.mod h1:X1hraaoONee20PMnGNLQpO32f9zbQ0Czfm7iZThuEKg=
-github.com/swaggest/jsonschema-go v0.3.64 h1:HyB41fkA4XP0BZkqWfGap5i2JtRHQGXG/21dGDPbyLM=
-github.com/swaggest/jsonschema-go v0.3.64/go.mod h1:DYuKqdpms/edvywsX6p1zHXCZkdwB28wRaBdFCe3Duw=
-github.com/swaggest/openapi-go v0.2.43 h1:nuNr60vmsx4pxIh1NoaIKrruh+pVba6iXjF+dXlTLAk=
-github.com/swaggest/openapi-go v0.2.43/go.mod h1:/ykzNtS1ZO7X43OnEtyisMktxCiawQLyGd08rkjV68U=
+github.com/swaggest/jsonschema-go v0.3.66 h1:4c5d7NRRqPLTswsbaypKqcMe3Z+CYHE3/lGsPIByp8o=
+github.com/swaggest/jsonschema-go v0.3.66/go.mod h1:7N43/CwdaWgPUDfYV70K7Qm79tRqe/al7gLSt9YeGIE=
+github.com/swaggest/openapi-go v0.2.46 h1:T7gCeErrNLu93aACb2/IacAPAe/lOcGz141a1+LYEx8=
+github.com/swaggest/openapi-go v0.2.46/go.mod h1:MK5O26lG289kFgMOyXK1VXDoTZ89KJ8Vt0v0ic23zZw=
 github.com/swaggest/refl v1.3.0 h1:PEUWIku+ZznYfsoyheF97ypSduvMApYyGkYF3nabS0I=
 github.com/swaggest/refl v1.3.0/go.mod h1:3Ujvbmh1pfSbDYjC6JGG7nMgPvpG0ehQL4iNonnLNbg=
-github.com/swaggest/swgui v1.7.3 h1:e1Du/3kqvR5HxL41M4pdkJhsADHtuyWpahl8tdcPStM=
-github.com/swaggest/swgui v1.7.3/go.mod h1:FP9uIPTB/QqVs2ZbOD6zc5yTw8SDTJfftak5f4ZRqOQ=
-github.com/swaggest/usecase v1.3.0 h1:Zte74uCWQYeGradJbxlhOrqi77K/GMK16VYTIjyenoA=
-github.com/swaggest/usecase v1.3.0/go.mod h1:cae3lDd5VDmM36OQcOOOdAlEDg40TiQYIp99S9ejWqA=
+github.com/swaggest/swgui v1.8.0 h1:dPu8TsYIOraaObAkyNdoiLI8mu7nOqQ6SU7HOv254rM=
+github.com/swaggest/swgui v1.8.0/go.mod h1:YBaAVAwS3ndfvdtW8A4yWDJpge+W57y+8kW+f/DqZtU=
+github.com/swaggest/usecase v1.3.1 h1:JdKV30MTSsDxAXxkldLNcEn8O2uf565khyo6gr5sS+w=
+github.com/swaggest/usecase v1.3.1/go.mod h1:cae3lDd5VDmM36OQcOOOdAlEDg40TiQYIp99S9ejWqA=
 github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
 github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
 github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
 github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
 github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
 github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
-github.com/valyala/fasthttp v1.48.0 h1:oJWvHb9BIZToTQS3MuQ2R3bJZiNSa2KiNdeI8A+79Tc=
-github.com/valyala/fasthttp v1.48.0/go.mod h1:k2zXd82h/7UZc3VOdJ2WaUqt1uZ/XpXAfE9i+HBC3lA=
+github.com/valyala/fasthttp v1.52.0 h1:wqBQpxH71XW0e2g+Og4dzQM8pk34aFYlA1Ga8db7gU0=
+github.com/valyala/fasthttp v1.52.0/go.mod h1:hf5C4QnVMkNXMspnsUlfM3WitlgYflyhHYoKol/szxQ=
 github.com/vearutop/dynhist-go v1.1.0 h1:kufNShpt45I97L2eO3bEYTSPKBSued0prheukJUYRok=
 github.com/vearutop/dynhist-go v1.1.0/go.mod h1:mjWlwr64oGBtouxh8s/9YOXV73MYP0Q9tfKIAp8/xto=
 github.com/vearutop/statigz v1.4.0 h1:RQL0KG3j/uyA/PFpHeZ/L6l2ta920/MxlOAIGEOuwmU=
@@ -154,54 +152,20 @@ github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FB
 github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 h1:BHyfKlQyqbsFN5p3IfnEUduWvb9is428/nNb5L3U01M=
 github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM=
 github.com/yudai/pp v2.0.1+incompatible h1:Q4//iY4pNF6yPLZIigmvcl7k/bPgrcTPIFIcmawg5bI=
-github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
 golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
 golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k=
 golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
-golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
-golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
-golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM=
-golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I=
-golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
-golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
-golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
-golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
-golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
-golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
-golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
-golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/crypto v0.20.0 h1:jmAMJJZXr5KiCw05dfYK9QnqaqKLYXijU23lsEdcQqg=
+golang.org/x/crypto v0.20.0/go.mod h1:Xwo95rrVNIoSMx9wa1JroENMToLWn3RNVrTBpLHgZPQ=
+golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=
+golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
 golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s=
-golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
-golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
-golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
-golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
-golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
-golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
-golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
-golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
-golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
-golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
-golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
-golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
-golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
-golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y=
+golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
+golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
diff --git a/_examples/jwtauth/main.go b/_examples/jwtauth/main.go
index e60b4d3..f464394 100644
--- a/_examples/jwtauth/main.go
+++ b/_examples/jwtauth/main.go
@@ -111,7 +111,7 @@ func router() http.Handler {
 		r.Group(func(r chi.Router) {
 			r.Use(
 				jwtauth.Verifier(tokenAuth),
-				jwtauth.Authenticator,
+				jwtauth.Authenticator(tokenAuth),
 			)
 
 			r.Method(http.MethodGet, "/", nethttp.NewHandler(Get()))
diff --git a/_examples/mount/main.go b/_examples/mount/main.go
index ed38729..0279ac6 100644
--- a/_examples/mount/main.go
+++ b/_examples/mount/main.go
@@ -7,6 +7,7 @@ import (
 	"net/http"
 
 	"github.com/go-chi/chi/v5/middleware"
+	"github.com/swaggest/openapi-go"
 	"github.com/swaggest/openapi-go/openapi3"
 	"github.com/swaggest/rest/nethttp"
 	"github.com/swaggest/rest/web"
@@ -36,30 +37,50 @@ func sum() usecase.Interactor {
 	})
 }
 
-func main() {
-	service := web.NewService(openapi3.NewReflector())
-	service.OpenAPISchema().SetTitle("Security and Mount Example")
+func service() *web.Service {
+	s := web.NewService(openapi3.NewReflector())
+	s.OpenAPISchema().SetTitle("Security and Mount Example")
 
-	apiV1 := web.NewService(service.OpenAPIReflector())
+	apiV1 := web.NewService(openapi3.NewReflector())
+	apiV2 := web.NewService(openapi3.NewReflector())
 
 	apiV1.Wrap(
 		middleware.BasicAuth("Admin Access", map[string]string{"admin": "admin"}),
-		nethttp.HTTPBasicSecurityMiddleware(service.OpenAPICollector, "Admin", "Admin access"),
+		nethttp.HTTPBasicSecurityMiddleware(s.OpenAPICollector, "Admin", "Admin access"),
+		nethttp.OpenAPIAnnotationsMiddleware(s.OpenAPICollector, func(oc openapi.OperationContext) error {
+			oc.SetTags(append(oc.Tags(), "V1")...)
+			return nil
+		}),
 	)
-
 	apiV1.Post("/sum", sum())
 	apiV1.Post("/mul", mul())
 
-	service.Mount("/api/v1", apiV1)
-	service.Docs("/api/v1/docs", swgui.New)
+	apiV2.Wrap(
+		// No auth for V2.
+
+		nethttp.OpenAPIAnnotationsMiddleware(s.OpenAPICollector, func(oc openapi.OperationContext) error {
+			oc.SetTags(append(oc.Tags(), "V2")...)
+			return nil
+		}),
+	)
+	apiV2.Post("/summarization", sum())
+	apiV2.Post("/multiplication", mul())
+
+	s.Mount("/api/v1", apiV1)
+	s.Mount("/api/v2", apiV2)
+	s.Docs("/api/docs", swgui.New)
 
 	// Blanket handler, for example to serve static content.
-	service.Mount("/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+	s.Mount("/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 		_, _ = w.Write([]byte("blanket handler got a request: " + r.URL.String()))
 	}))
 
-	fmt.Println("Swagger UI at http://localhost:8010/api/v1/docs.")
-	if err := http.ListenAndServe("localhost:8010", service); err != nil {
+	return s
+}
+
+func main() {
+	fmt.Println("Swagger UI at http://localhost:8010/api/docs.")
+	if err := http.ListenAndServe("localhost:8010", service()); err != nil {
 		log.Fatal(err)
 	}
 }
diff --git a/go.mod b/go.mod
index b6df15f..a21e629 100644
--- a/go.mod
+++ b/go.mod
@@ -3,20 +3,20 @@ module github.com/swaggest/rest
 go 1.17
 
 require (
-	github.com/bool64/dev v0.2.32
+	github.com/bool64/dev v0.2.34
 	github.com/bool64/httpmock v0.1.13
 	github.com/bool64/shared v0.1.5
 	github.com/cespare/xxhash/v2 v2.2.0
-	github.com/go-chi/chi/v5 v5.0.10
-	github.com/gorilla/mux v1.8.0
+	github.com/go-chi/chi/v5 v5.0.12
+	github.com/gorilla/mux v1.8.1
 	github.com/santhosh-tekuri/jsonschema/v3 v3.1.0
 	github.com/stretchr/testify v1.8.2
 	github.com/swaggest/assertjson v1.9.0
 	github.com/swaggest/form/v5 v5.1.1
-	github.com/swaggest/jsonschema-go v0.3.64
-	github.com/swaggest/openapi-go v0.2.43
+	github.com/swaggest/jsonschema-go v0.3.66
+	github.com/swaggest/openapi-go v0.2.46
 	github.com/swaggest/refl v1.3.0
-	github.com/swaggest/usecase v1.3.0
+	github.com/swaggest/usecase v1.3.1
 )
 
 require (
diff --git a/go.sum b/go.sum
index 50a5c4d..b800645 100644
--- a/go.sum
+++ b/go.sum
@@ -3,8 +3,9 @@ github.com/bool64/dev v0.2.25/go.mod h1:iJbh1y/HkunEPhgebWRNcs8wfGq7sjvJ6W5iabL8
 github.com/bool64/dev v0.2.27/go.mod h1:iJbh1y/HkunEPhgebWRNcs8wfGq7sjvJ6W5iabL8ACg=
 github.com/bool64/dev v0.2.29/go.mod h1:iJbh1y/HkunEPhgebWRNcs8wfGq7sjvJ6W5iabL8ACg=
 github.com/bool64/dev v0.2.31/go.mod h1:iJbh1y/HkunEPhgebWRNcs8wfGq7sjvJ6W5iabL8ACg=
-github.com/bool64/dev v0.2.32 h1:DRZtloaoH1Igky3zphaUHV9+SLIV2H3lsf78JsJHFg0=
 github.com/bool64/dev v0.2.32/go.mod h1:iJbh1y/HkunEPhgebWRNcs8wfGq7sjvJ6W5iabL8ACg=
+github.com/bool64/dev v0.2.34 h1:P9n315P8LdpxusnYQ0X7MP1CZXwBK5ae5RZrd+GdSZE=
+github.com/bool64/dev v0.2.34/go.mod h1:iJbh1y/HkunEPhgebWRNcs8wfGq7sjvJ6W5iabL8ACg=
 github.com/bool64/httpmock v0.1.13 h1:3QpRXQ5kwHLW8xnVT8+Ug7VS6RerhdEFV+RWYC61aVo=
 github.com/bool64/httpmock v0.1.13/go.mod h1:YMTLaypQ3o5DAx78eA/kDRSLec0f+42sLMDmHdmeY+E=
 github.com/bool64/shared v0.1.5 h1:fp3eUhBsrSjNCQPcSdQqZxxh9bBwrYiZ+zOKFkM0/2E=
@@ -17,8 +18,8 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
 github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
 github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
 github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
-github.com/go-chi/chi/v5 v5.0.10 h1:rLz5avzKpjqxrYwXNfmjkrYYXOyLJd37pz53UFHC6vk=
-github.com/go-chi/chi/v5 v5.0.10/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
+github.com/go-chi/chi/v5 v5.0.12 h1:9euLV5sTrTNTRUU9POmDUvfxyj6LAABLUcEWO+JJb4s=
+github.com/go-chi/chi/v5 v5.0.12/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
 github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
 github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
 github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
@@ -30,8 +31,8 @@ github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw
 github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
 github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
 github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
-github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
+github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
+github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
 github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
 github.com/iancoleman/orderedmap v0.2.0/go.mod h1:N0Wam8K1arqPXNWjMo21EXnBPOPp36vB07FNRdD2geA=
 github.com/iancoleman/orderedmap v0.3.0 h1:5cbR2grmZR/DiVt+VJopEhtVs9YGInGIxAoMJn+Ichc=
@@ -77,14 +78,14 @@ github.com/swaggest/assertjson v1.9.0 h1:dKu0BfJkIxv/xe//mkCrK5yZbs79jL7OVf9Ija7
 github.com/swaggest/assertjson v1.9.0/go.mod h1:b+ZKX2VRiUjxfUIal0HDN85W0nHPAYUbYH5WkkSsFsU=
 github.com/swaggest/form/v5 v5.1.1 h1:ct6/rOQBGrqWUQ0FUv3vW5sHvTUb31AwTUWj947N6cY=
 github.com/swaggest/form/v5 v5.1.1/go.mod h1:X1hraaoONee20PMnGNLQpO32f9zbQ0Czfm7iZThuEKg=
-github.com/swaggest/jsonschema-go v0.3.64 h1:HyB41fkA4XP0BZkqWfGap5i2JtRHQGXG/21dGDPbyLM=
-github.com/swaggest/jsonschema-go v0.3.64/go.mod h1:DYuKqdpms/edvywsX6p1zHXCZkdwB28wRaBdFCe3Duw=
-github.com/swaggest/openapi-go v0.2.43 h1:nuNr60vmsx4pxIh1NoaIKrruh+pVba6iXjF+dXlTLAk=
-github.com/swaggest/openapi-go v0.2.43/go.mod h1:/ykzNtS1ZO7X43OnEtyisMktxCiawQLyGd08rkjV68U=
+github.com/swaggest/jsonschema-go v0.3.66 h1:4c5d7NRRqPLTswsbaypKqcMe3Z+CYHE3/lGsPIByp8o=
+github.com/swaggest/jsonschema-go v0.3.66/go.mod h1:7N43/CwdaWgPUDfYV70K7Qm79tRqe/al7gLSt9YeGIE=
+github.com/swaggest/openapi-go v0.2.46 h1:T7gCeErrNLu93aACb2/IacAPAe/lOcGz141a1+LYEx8=
+github.com/swaggest/openapi-go v0.2.46/go.mod h1:MK5O26lG289kFgMOyXK1VXDoTZ89KJ8Vt0v0ic23zZw=
 github.com/swaggest/refl v1.3.0 h1:PEUWIku+ZznYfsoyheF97ypSduvMApYyGkYF3nabS0I=
 github.com/swaggest/refl v1.3.0/go.mod h1:3Ujvbmh1pfSbDYjC6JGG7nMgPvpG0ehQL4iNonnLNbg=
-github.com/swaggest/usecase v1.3.0 h1:Zte74uCWQYeGradJbxlhOrqi77K/GMK16VYTIjyenoA=
-github.com/swaggest/usecase v1.3.0/go.mod h1:cae3lDd5VDmM36OQcOOOdAlEDg40TiQYIp99S9ejWqA=
+github.com/swaggest/usecase v1.3.1 h1:JdKV30MTSsDxAXxkldLNcEn8O2uf565khyo6gr5sS+w=
+github.com/swaggest/usecase v1.3.1/go.mod h1:cae3lDd5VDmM36OQcOOOdAlEDg40TiQYIp99S9ejWqA=
 github.com/yosuke-furukawa/json5 v0.1.2-0.20201207051438-cf7bb3f354ff h1:7YqG491bE4vstXRz1lD38rbSgbXnirvROz1lZiOnPO8=
 github.com/yosuke-furukawa/json5 v0.1.2-0.20201207051438-cf7bb3f354ff/go.mod h1:sw49aWDqNdRJ6DYUtIQiaA3xyj2IL9tjeNYmX2ixwcU=
 github.com/yudai/gojsondiff v1.0.0 h1:27cbfqXLVEJ1o8I6v3y9lg8Ydm53EKqHXAOMxEGlCOA=
diff --git a/nethttp/handler.go b/nethttp/handler.go
index a9456ca..9b081b0 100644
--- a/nethttp/handler.go
+++ b/nethttp/handler.go
@@ -126,7 +126,6 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 	}
 
 	err = h.useCase.Interact(r.Context(), input, output)
-
 	if err != nil {
 		h.handleErrResponse(w, r, err)
 
diff --git a/nethttp/options.go b/nethttp/options.go
index 6b0ef77..c18e1bc 100644
--- a/nethttp/options.go
+++ b/nethttp/options.go
@@ -96,7 +96,7 @@ func RequestMapping(v interface{}) func(h *Handler) {
 		} {
 			mm := make(map[string]string)
 
-			refl.WalkTaggedFields(reflect.ValueOf(v), func(v reflect.Value, sf reflect.StructField, tag string) {
+			refl.WalkTaggedFields(reflect.ValueOf(v), func(_ reflect.Value, sf reflect.StructField, tag string) {
 				mm[sf.Name] = tag
 			}, string(in))
 
@@ -124,7 +124,7 @@ func ResponseHeaderMapping(v interface{}) func(h *Handler) {
 
 		mm := make(map[string]string)
 
-		refl.WalkTaggedFields(reflect.ValueOf(v), func(v reflect.Value, sf reflect.StructField, tag string) {
+		refl.WalkTaggedFields(reflect.ValueOf(v), func(_ reflect.Value, sf reflect.StructField, tag string) {
 			mm[sf.Name] = tag
 		}, "header")
 
diff --git a/nethttp/usecase.go b/nethttp/usecase.go
index e3d1433..9e5a26d 100644
--- a/nethttp/usecase.go
+++ b/nethttp/usecase.go
@@ -20,8 +20,8 @@ func UseCaseMiddlewares(mw ...usecase.Middleware) func(http.Handler) http.Handle
 		}
 
 		u := uh.UseCase()
-		fu := usecase.Wrap(u, usecase.MiddlewareFunc(func(next usecase.Interactor) usecase.Interactor {
-			return usecase.Interact(func(ctx context.Context, input, output interface{}) error {
+		fu := usecase.Wrap(u, usecase.MiddlewareFunc(func(_ usecase.Interactor) usecase.Interactor {
+			return usecase.Interact(func(ctx context.Context, _, _ interface{}) error {
 				return ctx.Value(decodeErrCtxKey{}).(error)
 			})
 		}))
diff --git a/openapi/collector.go b/openapi/collector.go
index 01dbb68..3c16579 100644
--- a/openapi/collector.go
+++ b/openapi/collector.go
@@ -321,6 +321,7 @@ func (c *Collector) setupOutput(oc openapi.OperationContext, u usecase.Interacto
 		if h.SuccessStatus != 0 {
 			status = h.SuccessStatus
 		}
+
 		oc.AddRespStructure(output, func(cu *openapi.ContentUnit) {
 			cu.HTTPStatus = status
 			setupCU(cu)
diff --git a/request/factory.go b/request/factory.go
index c859424..823e245 100644
--- a/request/factory.go
+++ b/request/factory.go
@@ -182,7 +182,7 @@ func (df *DecoderFactory) prepareCustomMapping(input interface{}, customMapping
 	if hdm, exists := cm[rest.ParamInHeader]; !exists && refl.HasTaggedFields(input, string(rest.ParamInHeader)) {
 		hdm = make(map[string]string)
 
-		refl.WalkTaggedFields(reflect.ValueOf(input), func(v reflect.Value, sf reflect.StructField, tag string) {
+		refl.WalkTaggedFields(reflect.ValueOf(input), func(_ reflect.Value, sf reflect.StructField, tag string) {
 			hdm[sf.Name] = http.CanonicalHeaderKey(tag)
 		}, string(rest.ParamInHeader))
 
@@ -195,7 +195,7 @@ func (df *DecoderFactory) prepareCustomMapping(input interface{}, customMapping
 
 	fields := make(map[string]bool)
 
-	refl.WalkTaggedFields(reflect.ValueOf(input), func(v reflect.Value, sf reflect.StructField, tag string) {
+	refl.WalkTaggedFields(reflect.ValueOf(input), func(_ reflect.Value, sf reflect.StructField, _ string) {
 		fields[sf.Name] = true
 	}, "")
 
@@ -221,7 +221,7 @@ func (df *DecoderFactory) prepareCustomMapping(input interface{}, customMapping
 // jsonParams configures custom decoding for parameters with JSON struct values.
 func (df *DecoderFactory) jsonParams(formDecoder *form.Decoder, in rest.ParamIn, input interface{}) {
 	// Check fields for struct values with json tags. E.g. query parameter with json value.
-	refl.WalkTaggedFields(reflect.ValueOf(input), func(v reflect.Value, sf reflect.StructField, tag string) {
+	refl.WalkTaggedFields(reflect.ValueOf(input), func(v reflect.Value, sf reflect.StructField, _ string) {
 		// Skip unexported fields.
 		if sf.PkgPath != "" {
 			return
@@ -234,7 +234,9 @@ func (df *DecoderFactory) jsonParams(formDecoder *form.Decoder, in rest.ParamIn,
 			// from a string value into a struct.
 			formDecoder.RegisterFunc(func(s string) (interface{}, error) {
 				var err error
+
 				f := reflect.New(sf.Type)
+
 				if df.JSONReader != nil {
 					err = df.JSONReader(bytes.NewBufferString(s), f.Interface())
 				} else {
@@ -254,7 +256,7 @@ func (df *DecoderFactory) jsonParams(formDecoder *form.Decoder, in rest.ParamIn,
 func (df *DecoderFactory) makeDefaultDecoder(input interface{}, m *decoder) {
 	defaults := url.Values{}
 
-	refl.WalkFieldsRecursively(reflect.ValueOf(input), func(v reflect.Value, sf reflect.StructField, path []reflect.StructField) {
+	refl.WalkFieldsRecursively(reflect.ValueOf(input), func(_ reflect.Value, sf reflect.StructField, path []reflect.StructField) {
 		var key string
 
 		for _, p := range path {
@@ -286,7 +288,7 @@ func (df *DecoderFactory) makeDefaultDecoder(input interface{}, m *decoder) {
 
 	dec := df.defaultValDecoder
 
-	m.decoders = append(m.decoders, func(r *http.Request, v interface{}, validator rest.Validator) error {
+	m.decoders = append(m.decoders, func(_ *http.Request, v interface{}, _ rest.Validator) error {
 		return dec.Decode(v, defaults)
 	})
 	m.in = append(m.in, defaultTag)
diff --git a/request/reflect.go b/request/reflect.go
index 428dc9d..f82f5d5 100644
--- a/request/reflect.go
+++ b/request/reflect.go
@@ -10,7 +10,7 @@ import (
 func hasFileFields(i interface{}, tagname string) bool {
 	found := false
 
-	refl.WalkTaggedFields(reflect.ValueOf(i), func(v reflect.Value, sf reflect.StructField, tag string) {
+	refl.WalkTaggedFields(reflect.ValueOf(i), func(_ reflect.Value, sf reflect.StructField, _ string) {
 		if sf.Type == multipartFileType || sf.Type == multipartFileHeaderType ||
 			sf.Type == multipartFilesType || sf.Type == multipartFileHeadersType {
 			found = true
diff --git a/response/encoder.go b/response/encoder.go
index f34a8bb..39f6a2b 100644
--- a/response/encoder.go
+++ b/response/encoder.go
@@ -90,7 +90,7 @@ func (h *Encoder) setupHeadersEncoder(output interface{}, ht *rest.HandlerTrait)
 	if len(respHeaderMapping) == 0 && refl.HasTaggedFields(output, string(rest.ParamInHeader)) {
 		respHeaderMapping = make(map[string]string)
 
-		refl.WalkTaggedFields(reflect.ValueOf(output), func(v reflect.Value, sf reflect.StructField, tag string) {
+		refl.WalkTaggedFields(reflect.ValueOf(output), func(_ reflect.Value, sf reflect.StructField, _ string) {
 			// Converting name to canonical form, while keeping omitempty and any other options.
 			t := sf.Tag.Get(string(rest.ParamInHeader))
 			parts := strings.Split(t, ",")
@@ -137,7 +137,7 @@ func (h *Encoder) setupCookiesEncoder(output interface{}, ht *rest.HandlerTrait)
 		respCookieMapping = make(map[string]http.Cookie)
 		h.outputCookieBase = make([]http.Cookie, 0)
 
-		refl.WalkTaggedFields(reflect.ValueOf(output), func(v reflect.Value, sf reflect.StructField, tag string) {
+		refl.WalkTaggedFields(reflect.ValueOf(output), func(_ reflect.Value, sf reflect.StructField, tag string) {
 			c := http.Cookie{
 				Name: tag,
 			}
@@ -147,11 +147,13 @@ func (h *Encoder) setupCookiesEncoder(output interface{}, ht *rest.HandlerTrait)
 				resp := http.Response{}
 				resp.Header = make(http.Header)
 				resp.Header.Add("Set-Cookie", tag+"=x;"+strings.Join(options, ";"))
+
 				cc := resp.Cookies()
 				if len(cc) == 1 {
 					c = *cc[0]
 				}
 			}
+
 			c.Value = ""
 			c.Raw = ""
 


Test patch:
diff --git a/.github/workflows/test-unit.yml b/.github/workflows/test-unit.yml
index 1f61fb8..7eb27c9 100644
--- a/.github/workflows/test-unit.yml
+++ b/.github/workflows/test-unit.yml
@@ -15,13 +15,13 @@ concurrency:
 env:
   GO111MODULE: "on"
   RUN_BASE_COVERAGE: "on"  # Runs test for PR base in case base test coverage is missing.
-  COV_GO_VERSION: 1.21.x   # Version of Go to collect coverage
+  COV_GO_VERSION: 1.22.x   # Version of Go to collect coverage
   TARGET_DELTA_COV: 90     # Target coverage of changed lines, in percents
 jobs:
   test:
     strategy:
       matrix:
-        go-version: [ 1.13.x, 1.20.x, 1.21.x ]
+        go-version: [ 1.13.x, 1.21.x, 1.22.x ]
     runs-on: ubuntu-latest
     steps:
       - name: Install Go stable
@@ -88,9 +88,9 @@ jobs:
         id: annotate
         if: matrix.go-version == env.COV_GO_VERSION && github.event.pull_request.base.sha != ''
         run: |
-          curl -sLO https://github.com/vearutop/gocovdiff/releases/download/v1.4.0/linux_amd64.tar.gz && tar xf linux_amd64.tar.gz && rm linux_amd64.tar.gz
+          curl -sLO https://github.com/vearutop/gocovdiff/releases/download/v1.4.2/linux_amd64.tar.gz && tar xf linux_amd64.tar.gz && rm linux_amd64.tar.gz
           gocovdiff_hash=$(git hash-object ./gocovdiff)
-          [ "$gocovdiff_hash" == "f191b45548bb65ec2c7d88909679a57116ff1ba1" ] || (echo "::error::unexpected hash for gocovdiff, possible tampering: $gocovdiff_hash" && exit 1)
+          [ "$gocovdiff_hash" == "c37862c73a677e5a9c069470287823ab5bbf0244" ] || (echo "::error::unexpected hash for gocovdiff, possible tampering: $gocovdiff_hash" && exit 1)
           git fetch origin master ${{ github.event.pull_request.base.sha }}
           REP=$(./gocovdiff -mod github.com/$GITHUB_REPOSITORY -cov unit.coverprofile -gha-annotations gha-unit.txt -delta-cov-file delta-cov-unit.txt -target-delta-cov ${TARGET_DELTA_COV})
           echo "${REP}"
diff --git a/_examples/advanced-generic-openapi31/_testdata/openapi.json b/_examples/advanced-generic-openapi31/_testdata/openapi.json
index 3ef2188..103c613 100644
--- a/_examples/advanced-generic-openapi31/_testdata/openapi.json
+++ b/_examples/advanced-generic-openapi31/_testdata/openapi.json
@@ -915,17 +915,17 @@
      "simple":{"description":"Simple scalar value in body.","type":"string"},
      "uploads1":{
       "description":"Uploads with *multipart.FileHeader.",
-      "items":{"$ref":"#/components/schemas/MultipartFileHeader"},"type":["array","null"]
+      "items":{"$ref":"#/components/schemas/MultipartFileHeader"},"type":"array"
      },
      "uploads2":{
       "description":"Uploads with multipart.File.","items":{"$ref":"#/components/schemas/MultipartFile"},
-      "type":["array","null"]
+      "type":"array"
      }
     },
     "type":"object"
    },
-   "MultipartFile":{"format":"binary","type":["null","string"]},
-   "MultipartFileHeader":{"format":"binary","type":["null","string"]},
+   "MultipartFile":{"contentMediaType":"application/octet-stream","format":"binary","type":"string"},
+   "MultipartFileHeader":{"contentMediaType":"application/octet-stream","format":"binary","type":"string"},
    "RestErrResponse":{
     "properties":{
      "code":{"description":"Application-specific error code.","type":"integer"},
diff --git a/_examples/advanced/_testdata/openapi.json b/_examples/advanced/_testdata/openapi.json
index 8602e49..13351c0 100644
--- a/_examples/advanced/_testdata/openapi.json
+++ b/_examples/advanced/_testdata/openapi.json
@@ -728,17 +728,16 @@
           "simple":{"type":"string","description":"Simple scalar value in body."},
           "uploads1":{
             "type":"array","items":{"$ref":"#/components/schemas/MultipartFileHeader"},
-            "description":"Uploads with *multipart.FileHeader.","nullable":true
+            "description":"Uploads with *multipart.FileHeader."
           },
           "uploads2":{
             "type":"array","items":{"$ref":"#/components/schemas/MultipartFile"},
-            "description":"Uploads with multipart.File.","nullable":true
+            "description":"Uploads with multipart.File."
           }
         },
         "additionalProperties":false
       },
-      "MultipartFile":{"type":"string","format":"binary","nullable":true},
-      "MultipartFileHeader":{"type":"string","format":"binary","nullable":true},
+      "MultipartFile":{"type":"string","format":"binary"},"MultipartFileHeader":{"type":"string","format":"binary"},
       "RestErrResponse":{
         "type":"object",
         "properties":{
diff --git a/_examples/mount/main_test.go b/_examples/mount/main_test.go
new file mode 100644
index 0000000..4892019
--- /dev/null
+++ b/_examples/mount/main_test.go
@@ -0,0 +1,129 @@
+package main
+
+import (
+	"bytes"
+	"encoding/json"
+	"net/http"
+	"net/http/httptest"
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
+	"github.com/swaggest/assertjson"
+)
+
+func Test_service(t *testing.T) {
+	s := service()
+
+	rw := httptest.NewRecorder()
+	r, err := http.NewRequest(http.MethodGet, "/api/docs/openapi.json", nil)
+	require.NoError(t, err)
+
+	s.ServeHTTP(rw, r)
+	assertjson.EqMarshal(t, `{
+	  "openapi":"3.0.3","info":{"title":"Security and Mount Example","version":""},
+	  "paths":{
+		"/api/v1/mul":{
+		  "post":{
+			"tags":["V1"],"summary":"Mul","operationId":"_examples/mount.mul",
+			"requestBody":{
+			  "content":{
+				"application/json":{"schema":{"type":"array","items":{"type":"integer"}}}
+			  }
+			},
+			"responses":{
+			  "200":{
+				"description":"OK",
+				"content":{"application/json":{"schema":{"type":"integer"}}}
+			  },
+			  "401":{
+				"description":"Unauthorized",
+				"content":{
+				  "application/json":{"schema":{"$ref":"#/components/schemas/RestErrResponse"}}
+				}
+			  }
+			},
+			"security":[{"Admin":[]}]
+		  }
+		},
+		"/api/v1/sum":{
+		  "post":{
+			"tags":["V1"],"summary":"Sum","operationId":"_examples/mount.sum",
+			"requestBody":{
+			  "content":{
+				"application/json":{"schema":{"type":"array","items":{"type":"integer"}}}
+			  }
+			},
+			"responses":{
+			  "200":{
+				"description":"OK",
+				"content":{"application/json":{"schema":{"type":"integer"}}}
+			  },
+			  "401":{
+				"description":"Unauthorized",
+				"content":{
+				  "application/json":{"schema":{"$ref":"#/components/schemas/RestErrResponse"}}
+				}
+			  }
+			},
+			"security":[{"Admin":[]}]
+		  }
+		},
+		"/api/v2/multiplication":{
+		  "post":{
+			"tags":["V2"],"summary":"Mul","operationId":"_examples/mount.mul2",
+			"requestBody":{
+			  "content":{
+				"application/json":{"schema":{"type":"array","items":{"type":"integer"}}}
+			  }
+			},
+			"responses":{
+			  "200":{
+				"description":"OK",
+				"content":{"application/json":{"schema":{"type":"integer"}}}
+			  }
+			}
+		  }
+		},
+		"/api/v2/summarization":{
+		  "post":{
+			"tags":["V2"],"summary":"Sum","operationId":"_examples/mount.sum2",
+			"requestBody":{
+			  "content":{
+				"application/json":{"schema":{"type":"array","items":{"type":"integer"}}}
+			  }
+			},
+			"responses":{
+			  "200":{
+				"description":"OK",
+				"content":{"application/json":{"schema":{"type":"integer"}}}
+			  }
+			}
+		  }
+		}
+	  },
+	  "components":{
+		"schemas":{
+		  "RestErrResponse":{
+			"type":"object",
+			"properties":{
+			  "code":{"type":"integer","description":"Application-specific error code."},
+			  "context":{
+				"type":"object","additionalProperties":{},
+				"description":"Application context."
+			  },
+			  "error":{"type":"string","description":"Error message."},
+			  "status":{"type":"string","description":"Status text."}
+			}
+		  }
+		},
+		"securitySchemes":{"Admin":{"type":"http","scheme":"basic","description":"Admin access"}}
+	  }
+	}`, json.RawMessage(rw.Body.Bytes()))
+
+	rw = httptest.NewRecorder()
+	r, err = http.NewRequest(http.MethodPost, "/api/v2/multiplication", bytes.NewReader([]byte(`[1,2,3]`)))
+
+	s.ServeHTTP(rw, r)
+	assert.Equal(t, "6\n", rw.Body.String())
+}
diff --git a/chirouter/example_test.go b/chirouter/example_test.go
index d969e88..a5f5e8a 100644
--- a/chirouter/example_test.go
+++ b/chirouter/example_test.go
@@ -35,7 +35,7 @@ func ExamplePathToURLValues() {
 	router := chi.NewRouter()
 
 	// Now in router handler you can decode *http.Request into a Go structure.
-	router.Handle("/foo/{path1}/bar/{path2}", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+	router.Handle("/foo/{path1}/bar/{path2}", http.HandlerFunc(func(_ http.ResponseWriter, r *http.Request) {
 		var in myRequest
 
 		_ = dec.Decode(r, &in, nil)
diff --git a/chirouter/wrapper_test.go b/chirouter/wrapper_test.go
index 0ff0d39..4c4e76a 100644
--- a/chirouter/wrapper_test.go
+++ b/chirouter/wrapper_test.go
@@ -80,12 +80,12 @@ func TestNewWrapper(t *testing.T) {
 
 	r.Use(mw)
 
-	r.NotFound(r.(*chirouter.Wrapper).HandlerFunc(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {})))
+	r.NotFound(r.(*chirouter.Wrapper).HandlerFunc(http.HandlerFunc(func(_ http.ResponseWriter, _ *http.Request) {})))
 
 	r.Group(func(r chi.Router) {
 		r.Method(http.MethodPost,
 			"/baz/{id}/",
-			HandlerWithFoo{Handler: http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
+			HandlerWithFoo{Handler: http.HandlerFunc(func(_ http.ResponseWriter, request *http.Request) {
 				val, err := chirouter.PathToURLValues(request)
 				assert.NoError(t, err)
 				assert.Equal(t, url.Values{"id": []string{"123"}}, val)
@@ -94,7 +94,7 @@ func TestNewWrapper(t *testing.T) {
 	})
 
 	r.Mount("/mount",
-		HandlerWithFoo{Handler: http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {})},
+		HandlerWithFoo{Handler: http.HandlerFunc(func(_ http.ResponseWriter, _ *http.Request) {})},
 	)
 
 	r.Route("/deeper", func(r chi.Router) {
@@ -102,19 +102,19 @@ func TestNewWrapper(t *testing.T) {
 			return HandlerWithFoo{Handler: handler}
 		})
 
-		r.Get("/foo", func(writer http.ResponseWriter, request *http.Request) {})
-		r.Head("/foo", func(writer http.ResponseWriter, request *http.Request) {})
-		r.Post("/foo", func(writer http.ResponseWriter, request *http.Request) {})
-		r.Put("/foo", func(writer http.ResponseWriter, request *http.Request) {})
-		r.Trace("/foo", func(writer http.ResponseWriter, request *http.Request) {})
-		r.Connect("/foo", func(writer http.ResponseWriter, request *http.Request) {})
-		r.Options("/foo", func(writer http.ResponseWriter, request *http.Request) {})
-		r.Patch("/foo", func(writer http.ResponseWriter, request *http.Request) {})
-		r.Delete("/foo", func(writer http.ResponseWriter, request *http.Request) {})
+		r.Get("/foo", func(_ http.ResponseWriter, _ *http.Request) {})
+		r.Head("/foo", func(_ http.ResponseWriter, _ *http.Request) {})
+		r.Post("/foo", func(_ http.ResponseWriter, _ *http.Request) {})
+		r.Put("/foo", func(_ http.ResponseWriter, _ *http.Request) {})
+		r.Trace("/foo", func(_ http.ResponseWriter, _ *http.Request) {})
+		r.Connect("/foo", func(_ http.ResponseWriter, _ *http.Request) {})
+		r.Options("/foo", func(_ http.ResponseWriter, _ *http.Request) {})
+		r.Patch("/foo", func(_ http.ResponseWriter, _ *http.Request) {})
+		r.Delete("/foo", func(_ http.ResponseWriter, _ *http.Request) {})
 
-		r.MethodFunc(http.MethodGet, "/cuux", func(writer http.ResponseWriter, request *http.Request) {})
+		r.MethodFunc(http.MethodGet, "/cuux", func(_ http.ResponseWriter, _ *http.Request) {})
 
-		r.Handle("/bar", http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {}))
+		r.Handle("/bar", http.HandlerFunc(func(_ http.ResponseWriter, _ *http.Request) {}))
 	})
 
 	for _, u := range []string{"/baz/123/", "/deeper/foo", "/mount/abc"} {
@@ -140,7 +140,9 @@ func TestWrapper_Use_precedence(t *testing.T) {
 		func(handler http.Handler) http.Handler {
 			return http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
 				log = append(log, "cmw1 before")
+
 				handler.ServeHTTP(writer, request)
+
 				log = append(log, "cmw1 after")
 			})
 		},
@@ -148,7 +150,9 @@ func TestWrapper_Use_precedence(t *testing.T) {
 		func(handler http.Handler) http.Handler {
 			return http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
 				log = append(log, "cmw2 before")
+
 				handler.ServeHTTP(writer, request)
+
 				log = append(log, "cmw2 after")
 			})
 		},
@@ -160,7 +164,9 @@ func TestWrapper_Use_precedence(t *testing.T) {
 		func(handler http.Handler) http.Handler {
 			return http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
 				log = append(log, "wmw1 before")
+
 				handler.ServeHTTP(writer, request)
+
 				log = append(log, "wmw1 after")
 			})
 		},
@@ -168,7 +174,9 @@ func TestWrapper_Use_precedence(t *testing.T) {
 		func(handler http.Handler) http.Handler {
 			return http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
 				log = append(log, "wmw2 before")
+
 				handler.ServeHTTP(writer, request)
+
 				log = append(log, "wmw2 after")
 			})
 		},
@@ -177,7 +185,7 @@ func TestWrapper_Use_precedence(t *testing.T) {
 	req, err := http.NewRequest(http.MethodGet, "/", nil)
 	require.NoError(t, err)
 
-	h := http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
+	h := http.HandlerFunc(func(_ http.ResponseWriter, _ *http.Request) {
 		log = append(log, "h")
 	})
 
@@ -238,7 +246,7 @@ func TestWrapper_Use_StripSlashes(t *testing.T) {
 
 	rw := httptest.NewRecorder()
 
-	h := http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
+	h := http.HandlerFunc(func(writer http.ResponseWriter, _ *http.Request) {
 		if _, err := writer.Write([]byte("OK")); err != nil {
 			log = append(log, err.Error())
 		}
@@ -276,7 +284,7 @@ func TestWrapper_Mount(t *testing.T) {
 		nethttp.HTTPBasicSecurityMiddleware(service.OpenAPICollector, "Admin", "Admin access"),
 	)
 
-	apiV1.Post("/sum", usecase.NewIOI(new([]int), new(int), func(ctx context.Context, input, output interface{}) error {
+	apiV1.Post("/sum", usecase.NewIOI(new([]int), new(int), func(_ context.Context, _, _ interface{}) error {
 		return errors.New("oops")
 	}))
 
@@ -387,7 +395,7 @@ func TestWrapper_With(t *testing.T) {
 
 	cw.Use(wrapper, notWrapper)
 	cw.With(wrapper, notWrapper).Method(http.MethodGet, "/",
-		http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {}))
+		http.HandlerFunc(func(_ http.ResponseWriter, _ *http.Request) {}))
 
 	assert.Equal(t, 2, wrapperCalled)
 	assert.Equal(t, 2, wrapperFound)
diff --git a/gzip/container_test.go b/gzip/container_test.go
index 89fa113..2ad11ab 100644
--- a/gzip/container_test.go
+++ b/gzip/container_test.go
@@ -49,7 +49,7 @@ func TestWriteJSON(t *testing.T) {
 	var ur interface{} = cont
 
 	u.Output = new(interface{})
-	u.Interactor = usecase.Interact(func(ctx context.Context, input, output interface{}) error {
+	u.Interactor = usecase.Interact(func(_ context.Context, _, output interface{}) error {
 		*output.(*interface{}) = ur
 
 		return nil
diff --git a/nethttp/handler_test.go b/nethttp/handler_test.go
index 6e0d224..feab71b 100644
--- a/nethttp/handler_test.go
+++ b/nethttp/handler_test.go
@@ -35,7 +35,7 @@ func TestHandler_ServeHTTP(t *testing.T) {
 	u.Input = new(Input)
 	u.Output = new(Output)
 
-	u.Interactor = usecase.Interact(func(ctx context.Context, input, output interface{}) error {
+	u.Interactor = usecase.Interact(func(_ context.Context, input, output interface{}) error {
 		in, ok := input.(*Input)
 		require.True(t, ok)
 		require.NotNil(t, in)
@@ -56,7 +56,7 @@ func TestHandler_ServeHTTP(t *testing.T) {
 	validatorCalled := false
 	h := nethttp.NewHandler(u,
 		func(h *nethttp.Handler) {
-			h.ReqValidator = rest.ValidatorFunc(func(in rest.ParamIn, namedData map[string]interface{}) error {
+			h.ReqValidator = rest.ValidatorFunc(func(_ rest.ParamIn, _ map[string]interface{}) error {
 				validatorCalled = true
 
 				return nil
@@ -71,7 +71,9 @@ func TestHandler_ServeHTTP(t *testing.T) {
 	h.SetRequestDecoder(request.DecoderFunc(
 		func(r *http.Request, input interface{}, validator rest.Validator) error {
 			assert.Equal(t, req, r)
+
 			in, ok := input.(*Input)
+
 			require.True(t, ok)
 			require.NotNil(t, in)
 
@@ -116,7 +118,7 @@ func TestHandler_ServeHTTP_decodeErr(t *testing.T) {
 	u.Input = new(Input)
 	u.Output = new(Output)
 
-	u.Interactor = usecase.Interact(func(ctx context.Context, input, output interface{}) error {
+	u.Interactor = usecase.Interact(func(_ context.Context, _, _ interface{}) error {
 		assert.Fail(t, "should not be called")
 
 		return nil
@@ -127,7 +129,7 @@ func TestHandler_ServeHTTP_decodeErr(t *testing.T) {
 
 	uh := nethttp.NewHandler(u)
 	uh.SetRequestDecoder(request.DecoderFunc(
-		func(r *http.Request, input interface{}, validator rest.Validator) error {
+		func(_ *http.Request, _ interface{}, _ rest.Validator) error {
 			return errors.New("failed to decode request")
 		},
 	))
@@ -156,7 +158,7 @@ func TestHandler_ServeHTTP_emptyPorts(t *testing.T) {
 		usecase.Interactor
 	}{}
 
-	u.Interactor = usecase.Interact(func(ctx context.Context, input, output interface{}) error {
+	u.Interactor = usecase.Interact(func(_ context.Context, input, output interface{}) error {
 		assert.Nil(t, input)
 		assert.Nil(t, output)
 
@@ -182,7 +184,7 @@ func TestHandler_ServeHTTP_customErrResp(t *testing.T) {
 		usecase.OutputWithNoContent
 	}{}
 
-	u.Interactor = usecase.Interact(func(ctx context.Context, input, output interface{}) error {
+	u.Interactor = usecase.Interact(func(_ context.Context, input, output interface{}) error {
 		assert.Nil(t, input)
 		assert.Nil(t, output)
 
@@ -190,7 +192,7 @@ func TestHandler_ServeHTTP_customErrResp(t *testing.T) {
 	})
 
 	h := nethttp.NewHandler(u)
-	h.MakeErrResp = func(ctx context.Context, err error) (int, interface{}) {
+	h.MakeErrResp = func(_ context.Context, err error) (int, interface{}) {
 		return http.StatusExpectationFailed, struct {
 			Custom string `json:"custom"`
 		}{
@@ -213,7 +215,7 @@ func TestHandlerWithRouteMiddleware(t *testing.T) {
 	called := false
 
 	var h http.Handler
-	h = http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
+	h = http.HandlerFunc(func(_ http.ResponseWriter, _ *http.Request) {
 		called = true
 	})
 
@@ -242,7 +244,7 @@ func TestHandler_ServeHTTP_getWithBody(t *testing.T) {
 
 	u.Input = new(reqWithBody)
 
-	u.Interactor = usecase.Interact(func(ctx context.Context, input, output interface{}) error {
+	u.Interactor = usecase.Interact(func(_ context.Context, input, output interface{}) error {
 		in, ok := input.(*reqWithBody)
 		assert.True(t, ok)
 		assert.Equal(t, 123, in.ID)
@@ -273,7 +275,7 @@ func TestHandler_ServeHTTP_customMapping(t *testing.T) {
 	}{}
 
 	u.Input = new(Input)
-	u.Interactor = usecase.Interact(func(ctx context.Context, input, output interface{}) error {
+	u.Interactor = usecase.Interact(func(_ context.Context, input, _ interface{}) error {
 		in, ok := input.(*Input)
 		assert.True(t, ok)
 		assert.Equal(t, 123, in.ID)
@@ -309,11 +311,11 @@ func TestHandler_ServeHTTP_customMapping(t *testing.T) {
 }
 
 func TestOptionsMiddleware(t *testing.T) {
-	u := usecase.NewIOI(nil, nil, func(ctx context.Context, input, output interface{}) error {
+	u := usecase.NewIOI(nil, nil, func(_ context.Context, _, _ interface{}) error {
 		return errors.New("failed")
 	})
 	h := nethttp.NewHandler(u, func(h *nethttp.Handler) {
-		h.MakeErrResp = func(ctx context.Context, err error) (int, interface{}) {
+		h.MakeErrResp = func(_ context.Context, err error) (int, interface{}) {
 			return http.StatusExpectationFailed, struct {
 				Foo string `json:"foo"`
 			}{Foo: err.Error()}
@@ -331,8 +333,9 @@ func TestOptionsMiddleware(t *testing.T) {
 		handleErrResponse := h.HandleErrResponse
 		h.HandleErrResponse = func(w http.ResponseWriter, r *http.Request, err error) {
 			assert.Equal(t, req, r)
-			loggedErr = err
 			handleErrResponse(w, r, err)
+
+			loggedErr = err
 		}
 	})(h)
 
diff --git a/nethttp/openapi_test.go b/nethttp/openapi_test.go
index f514bf3..d59ee3c 100644
--- a/nethttp/openapi_test.go
+++ b/nethttp/openapi_test.go
@@ -26,7 +26,7 @@ func TestOpenAPIMiddleware(t *testing.T) {
 		Value  string `json:"val"`
 		Header int
 	})
-	u.Interactor = usecase.Interact(func(ctx context.Context, input, output interface{}) error {
+	u.Interactor = usecase.Interact(func(_ context.Context, input, _ interface{}) error {
 		in, ok := input.(*Input)
 		assert.True(t, ok)
 		assert.Equal(t, 123, in.ID)
diff --git a/nethttp/options_test.go b/nethttp/options_test.go
index b9eea72..21fb229 100644
--- a/nethttp/options_test.go
+++ b/nethttp/options_test.go
@@ -42,7 +42,7 @@ func TestRequestBodyContent(t *testing.T) {
 func TestRequestBodyContent_webService(t *testing.T) {
 	s := web.NewService(openapi3.NewReflector())
 
-	u := usecase.NewIOI(new(string), nil, func(ctx context.Context, input, output interface{}) error {
+	u := usecase.NewIOI(new(string), nil, func(_ context.Context, _, _ interface{}) error {
 		return nil
 	})
 
diff --git a/nethttp/wrap_test.go b/nethttp/wrap_test.go
index 0a4e6b6..41b9081 100644
--- a/nethttp/wrap_test.go
+++ b/nethttp/wrap_test.go
@@ -12,7 +12,7 @@ func TestWrapHandler(t *testing.T) {
 	var flow []string
 
 	h := nethttp.WrapHandler(
-		http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
+		http.HandlerFunc(func(_ http.ResponseWriter, _ *http.Request) {
 			flow = append(flow, "handler")
 		}),
 		func(handler http.Handler) http.Handler {
@@ -20,7 +20,9 @@ func TestWrapHandler(t *testing.T) {
 
 			return http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
 				flow = append(flow, "mw1 before")
+
 				handler.ServeHTTP(writer, request)
+
 				flow = append(flow, "mw1 after")
 			})
 		},
@@ -29,7 +31,9 @@ func TestWrapHandler(t *testing.T) {
 
 			return http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
 				flow = append(flow, "mw2 before")
+
 				handler.ServeHTTP(writer, request)
+
 				flow = append(flow, "mw2 after")
 			})
 		},
@@ -38,7 +42,9 @@ func TestWrapHandler(t *testing.T) {
 
 			return http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
 				flow = append(flow, "mw3 before")
+
 				handler.ServeHTTP(writer, request)
+
 				flow = append(flow, "mw3 after")
 			})
 		},
diff --git a/openapi/collector_test.go b/openapi/collector_test.go
index b312bd0..0a9087c 100644
--- a/openapi/collector_test.go
+++ b/openapi/collector_test.go
@@ -106,7 +106,7 @@ func TestCollector_Collect(t *testing.T) {
 	assertjson.Equal(t, j, rw.Body.Bytes())
 
 	val := validatorMock{
-		AddSchemaFunc: func(in rest.ParamIn, name string, schemaData []byte, required bool) error {
+		AddSchemaFunc: func(_ rest.ParamIn, _ string, _ []byte, _ bool) error {
 			return nil
 		},
 	}
@@ -209,7 +209,7 @@ func TestCollector_Collect_requestMapping(t *testing.T) {
 	  },
 	  "components":{
 		"schemas":{
-		  "MultipartFile":{"type":"string","format":"binary","nullable":true},
+		  "MultipartFile":{"type":"string","format":"binary"},
 		  "OpenapiTestInput":{
 			"type":"object",
 			"properties":{
@@ -222,7 +222,7 @@ func TestCollector_Collect_requestMapping(t *testing.T) {
 	}`, collector.SpecSchema())
 
 	val := validatorMock{
-		AddSchemaFunc: func(in rest.ParamIn, name string, schemaData []byte, required bool) error {
+		AddSchemaFunc: func(_ rest.ParamIn, _ string, _ []byte, _ bool) error {
 			return nil
 		},
 	}
@@ -246,7 +246,7 @@ func TestCollector_Collect_CombineErrors(t *testing.T) {
 	u.SetExpectedErrors(status.InvalidArgument, anotherErr{}, status.FailedPrecondition, status.AlreadyExists)
 
 	h := rest.HandlerTrait{}
-	h.MakeErrResp = func(ctx context.Context, err error) (int, interface{}) {
+	h.MakeErrResp = func(_ context.Context, err error) (int, interface{}) {
 		code, er := rest.Err(err)
 
 		var ae anotherErr
diff --git a/request/decoder_test.go b/request/decoder_test.go
index 3662892..772a805 100644
--- a/request/decoder_test.go
+++ b/request/decoder_test.go
@@ -141,7 +141,7 @@ func BenchmarkDecoderFunc_Decode(b *testing.B) {
 	req.AddCookie(&c)
 
 	df := request.NewDecoderFactory()
-	df.SetDecoderFunc(rest.ParamInPath, func(r *http.Request) (url.Values, error) {
+	df.SetDecoderFunc(rest.ParamInPath, func(_ *http.Request) (url.Values, error) {
 		return url.Values{"in_path": []string{"mno"}}, nil
 	})
 
diff --git a/request/factory_test.go b/request/factory_test.go
index 6572e45..765fdae 100644
--- a/request/factory_test.go
+++ b/request/factory_test.go
@@ -23,16 +23,19 @@ func TestDecoderFactory_SetDecoderFunc(t *testing.T) {
 		}
 
 		var m map[string]json.RawMessage
+
 		err := json.Unmarshal([]byte(ah[7:]), &m)
 		if err != nil {
 			return nil, err
 		}
 
 		res := make(url.Values)
+
 		for k, v := range m {
 			if len(v) > 2 && v[0] == '"' && v[len(v)-1] == '"' {
 				v = v[1 : len(v)-1]
 			}
+
 			res[k] = []string{string(v)}
 		}
 
@@ -79,10 +82,12 @@ func BenchmarkDecoderFactory_SetDecoderFunc(b *testing.B) {
 		}
 
 		res := make(url.Values)
+
 		for k, v := range m {
 			if len(v) > 2 && v[0] == '"' && v[len(v)-1] == '"' {
 				v = v[1 : len(v)-1]
 			}
+
 			res[k] = []string{string(v)}
 		}
 
@@ -254,7 +259,7 @@ func TestDecoderFactory_MakeDecoder_header_case_sensitivity(t *testing.T) {
 
 	req.Header.Set("x-One-Two-threE", "hello!")
 
-	require.NoError(t, d.Decode(req, &v, rest.ValidatorFunc(func(in rest.ParamIn, namedData map[string]interface{}) error {
+	require.NoError(t, d.Decode(req, &v, rest.ValidatorFunc(func(_ rest.ParamIn, namedData map[string]interface{}) error {
 		fmt.Printf("%+v", namedData)
 
 		return nil
diff --git a/request/file_test.go b/request/file_test.go
index 315aed3..3387488 100644
--- a/request/file_test.go
+++ b/request/file_test.go
@@ -37,7 +37,7 @@ type fileReqTest struct {
 }
 
 func TestDecoder_Decode_fileUploadOptional(t *testing.T) {
-	u := usecase.NewIOI(new(ReqEmb), nil, func(ctx context.Context, input, output interface{}) error {
+	u := usecase.NewIOI(new(ReqEmb), nil, func(_ context.Context, _, _ interface{}) error {
 		return nil
 	})
 
@@ -88,7 +88,7 @@ func TestDecoder_Decode_fileUploadTag(t *testing.T) {
 	}{}
 
 	u.Input = new(fileReqTest)
-	u.Interactor = usecase.Interact(func(ctx context.Context, input, output interface{}) error {
+	u.Interactor = usecase.Interact(func(_ context.Context, input, _ interface{}) error {
 		in, ok := input.(*fileReqTest)
 		assert.True(t, ok)
 		assert.NotNil(t, in.Upload)
diff --git a/request/jsonbody_test.go b/request/jsonbody_test.go
index f7dcad9..3380b62 100644
--- a/request/jsonbody_test.go
+++ b/request/jsonbody_test.go
@@ -30,7 +30,7 @@ func Test_decodeJSONBody(t *testing.T) {
 	assert.Equal(t, "248df4b7-aa70-47b8-a036-33ac447e668d", i.CustomerID)
 	assert.Equal(t, "withdraw", i.Type)
 
-	vl := rest.ValidatorFunc(func(in rest.ParamIn, namedData map[string]interface{}) error {
+	vl := rest.ValidatorFunc(func(_ rest.ParamIn, _ map[string]interface{}) error {
 		return nil
 	})
 
@@ -90,7 +90,7 @@ func Test_decodeJSONBody_validateFailed(t *testing.T) {
 
 	var i []int
 
-	vl := rest.ValidatorFunc(func(in rest.ParamIn, namedData map[string]interface{}) error {
+	vl := rest.ValidatorFunc(func(_ rest.ParamIn, _ map[string]interface{}) error {
 		return errors.New("failed")
 	})
 
diff --git a/response/gzip/middleware_test.go b/response/gzip/middleware_test.go
index ddda589..69c28ab 100644
--- a/response/gzip/middleware_test.go
+++ b/response/gzip/middleware_test.go
@@ -18,7 +18,7 @@ import (
 
 func TestMiddleware(t *testing.T) {
 	resp := []byte(strings.Repeat("A", 10000) + "!!!")
-	h := gzip.Middleware(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
+	h := gzip.Middleware(http.HandlerFunc(func(rw http.ResponseWriter, _ *http.Request) {
 		_, err := rw.Write(resp)
 		assert.NoError(t, err)
 	}))
@@ -67,7 +67,7 @@ func TestMiddleware(t *testing.T) {
 // BenchmarkMiddleware-12    	  108810	      9619 ns/op	    1223 B/op	      11 allocs/op.
 func BenchmarkMiddleware(b *testing.B) {
 	resp := []byte(strings.Repeat("A", 10000) + "!!!")
-	h := gzip.Middleware(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
+	h := gzip.Middleware(http.HandlerFunc(func(rw http.ResponseWriter, _ *http.Request) {
 		_, err := rw.Write(resp)
 		assert.NoError(b, err)
 	}))
@@ -92,7 +92,7 @@ func BenchmarkMiddleware(b *testing.B) {
 // BenchmarkMiddleware_control-4   	  214824	      5945 ns/op	   11184 B/op	       9 allocs/op.
 func BenchmarkMiddleware_control(b *testing.B) {
 	resp := []byte(strings.Repeat("A", 10000) + "!!!")
-	h := http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
+	h := http.HandlerFunc(func(rw http.ResponseWriter, _ *http.Request) {
 		_, err := rw.Write(resp)
 		assert.NoError(b, err)
 	})
@@ -114,12 +114,12 @@ func BenchmarkMiddleware_control(b *testing.B) {
 func TestMiddleware_concurrency(t *testing.T) {
 	resp := []byte(strings.Repeat("A", 10000) + "!!!")
 	respGz := gzipEncode(t, resp)
-	h := gzip.Middleware(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
+	h := gzip.Middleware(http.HandlerFunc(func(rw http.ResponseWriter, _ *http.Request) {
 		_, err := rw.Write(resp)
 		assert.NoError(t, err)
 	}))
 
-	hg := gzip.Middleware(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
+	hg := gzip.Middleware(http.HandlerFunc(func(rw http.ResponseWriter, _ *http.Request) {
 		_, err := gzip2.WriteCompressedBytes(respGz, rw)
 		assert.NoError(t, err)
 	}))
@@ -161,7 +161,7 @@ func TestGzipResponseWriter_ExpectCompressedBytes(t *testing.T) {
 	resp := []byte(strings.Repeat("A", 10000) + "!!!")
 	respGz := gzipEncode(t, resp)
 
-	h := gzip.Middleware(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
+	h := gzip.Middleware(http.HandlerFunc(func(rw http.ResponseWriter, _ *http.Request) {
 		_, err := gzip2.WriteCompressedBytes(respGz, rw)
 		assert.NoError(t, err)
 	}))
@@ -181,7 +181,7 @@ func TestGzipResponseWriter_ExpectCompressedBytes(t *testing.T) {
 
 func TestMiddleware_skipContentEncoding(t *testing.T) {
 	resp := []byte(strings.Repeat("A", 10000) + "!!!")
-	h := gzip.Middleware(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
+	h := gzip.Middleware(http.HandlerFunc(func(rw http.ResponseWriter, _ *http.Request) {
 		rw.Header().Set("Content-Encoding", "br")
 		_, err := rw.Write(resp)
 		assert.NoError(t, err)
@@ -201,7 +201,7 @@ func TestMiddleware_skipContentEncoding(t *testing.T) {
 }
 
 func TestMiddleware_noContent(t *testing.T) {
-	h := gzip.Middleware(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
+	h := gzip.Middleware(http.HandlerFunc(func(rw http.ResponseWriter, _ *http.Request) {
 		rw.WriteHeader(http.StatusNoContent)
 
 		// Second call does not hurt.
@@ -252,7 +252,7 @@ func gzipDecode(t *testing.T, data []byte) []byte {
 
 func TestMiddleware_hijacker(t *testing.T) {
 	rb := []byte(strings.Repeat("A", 10000) + "!!!")
-	h := gzip.Middleware(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
+	h := gzip.Middleware(http.HandlerFunc(func(rw http.ResponseWriter, _ *http.Request) {
 		_, ok := rw.(http.Hijacker)
 		require.True(t, ok)
 
diff --git a/response/middleware_test.go b/response/middleware_test.go
index bb68ded..560645f 100644
--- a/response/middleware_test.go
+++ b/response/middleware_test.go
@@ -25,7 +25,7 @@ func TestEncoderMiddleware(t *testing.T) {
 	}
 
 	u.Output = new(outputPort)
-	u.Interactor = usecase.Interact(func(ctx context.Context, input, output interface{}) error {
+	u.Interactor = usecase.Interact(func(_ context.Context, _, output interface{}) error {
 		output.(*outputPort).Name = "Jane"
 		output.(*outputPort).Items = []string{"one", "two", "three"}
 
diff --git a/response/validator_test.go b/response/validator_test.go
index 0fdf48d..1d32985 100644
--- a/response/validator_test.go
+++ b/response/validator_test.go
@@ -32,7 +32,7 @@ func TestValidatorMiddleware(t *testing.T) {
 	}
 
 	u.Output = new(outputPort)
-	u.Interactor = usecase.Interact(func(ctx context.Context, input, output interface{}) error {
+	u.Interactor = usecase.Interact(func(_ context.Context, _, output interface{}) error {
 		out, ok := output.(*outputPort)
 		require.True(t, ok)
 
diff --git a/resttest/client_test.go b/resttest/client_test.go
index 1bc6443..74e5d3d 100644
--- a/resttest/client_test.go
+++ b/resttest/client_test.go
@@ -36,7 +36,9 @@ func TestNewClient(t *testing.T) {
 		assert.Equal(t, "bar", c.Value)
 
 		ncnt := atomic.AddInt64(&cnt, 1)
+
 		rw.Header().Set("Content-Type", "application/json")
+
 		if ncnt > 1 {
 			rw.WriteHeader(http.StatusConflict)
 			_, err := rw.Write([]byte(`{"error":"conflict"}`))
@@ -88,7 +90,7 @@ func TestNewClient(t *testing.T) {
 }
 
 func TestNewClient_failedExpectation(t *testing.T) {
-	srv := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
+	srv := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, _ *http.Request) {
 		_, err := writer.Write([]byte(`{"bar":"foo"}`))
 		assert.NoError(t, err)
 	}))
diff --git a/web/service_test.go b/web/service_test.go
index 1d822cf..eb436f7 100644
--- a/web/service_test.go
+++ b/web/service_test.go
@@ -22,7 +22,7 @@ type albumID struct {
 }
 
 func albumByID() usecase.Interactor {
-	u := usecase.NewIOI(new(albumID), new(album), func(ctx context.Context, input, output interface{}) error {
+	u := usecase.NewIOI(new(albumID), new(album), func(_ context.Context, _, _ interface{}) error {
 		return nil
 	})
 	u.SetTags("Album")
@@ -35,8 +35,8 @@ func TestDefaultService(t *testing.T) {
 
 	service := web.NewService(
 		openapi3.NewReflector(),
-		func(s *web.Service) { l = append(l, "one") },
-		func(s *web.Service) { l = append(l, "two") },
+		func(_ *web.Service) { l = append(l, "one") },
+		func(_ *web.Service) { l = append(l, "two") },
 	)
 
 	service.OpenAPISchema().SetTitle("Albums API")
@@ -51,9 +51,9 @@ func TestDefaultService(t *testing.T) {
 	service.Put("/albums", postAlbums(), nethttp.SuccessStatus(http.StatusCreated))
 	service.Trace("/albums", postAlbums(), nethttp.SuccessStatus(http.StatusCreated))
 	service.Options("/albums", postAlbums(), nethttp.SuccessStatus(http.StatusCreated))
-	service.Docs("/docs", func(title, schemaURL, basePath string) http.Handler {
+	service.Docs("/docs", func(_, _, _ string) http.Handler {
 		// Mount github.com/swaggest/swgui/v4emb.New here.
-		return http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {})
+		return http.HandlerFunc(func(_ http.ResponseWriter, _ *http.Request) {})
 	})
 
 	service.OnNotFound(usecase.NewIOI(
@@ -61,7 +61,7 @@ func TestDefaultService(t *testing.T) {
 		new(struct {
 			Foo string `json:"foo"`
 		}),
-		func(ctx context.Context, input, output interface{}) error {
+		func(_ context.Context, _, _ interface{}) error {
 			return nil
 		}),
 	)
@@ -71,7 +71,7 @@ func TestDefaultService(t *testing.T) {
 		new(struct {
 			Foo string `json:"foo"`
 		}),
-		func(ctx context.Context, input, output interface{}) error {
+		func(_ context.Context, _, _ interface{}) error {
 			return nil
 		}),
 	)