rest-easy 1.1.2 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +9 -1
- data/README.md +91 -8
- data/lib/rest_easy/settings.rb +5 -3
- data/lib/rest_easy/version.rb +1 -1
- data/lib/rest_easy.rb +13 -0
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c5f42d44a6677ffb6553237d5be80fc7247a6501946069ee1034b0811a4b6219
|
|
4
|
+
data.tar.gz: 858f63be66e21f33873ea74467eb411215d213c921acab98c489d6db03734fdd
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5249f3a12786557b868a420b07778c5e8ce17feefc72a8e5e093fcca6c6390caf8113eebd8746c6e3dfb7150b80547c6bdaf38584004f760e2fea6b743c1c060
|
|
7
|
+
data.tar.gz: 2453b54cb4e35ffb47d60dec50417c9d3869f9a8ae10594ca19c2c9dc5c1462254b5792ecf7d0f7e4d03520d0242e72d9e3728daf92135e20509509eeb95867d
|
data/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [1.2.0] - 2026-05-17
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- **`logger` setting.** When set to a `Logger`-compatible instance, Faraday's built-in logger middleware is attached to the connection and logs HTTP request/response lines and headers. Unset by default — no overhead when not in use. The standard auth-bearing headers (`Authorization`, `Proxy-Authorization`, `Cookie`, `Set-Cookie`) are always filtered to `[FILTERED]`; consumer gems are responsible for redacting domain-specific secrets in non-standard headers or response bodies (see README "Redacting domain-specific secrets").
|
|
10
|
+
- **`log_bodies` setting** (default `false`). Opt-in toggle for logging request/response bodies. Off by default because bodies often carry domain-specific secrets that RestEasy cannot recognize.
|
|
11
|
+
|
|
5
12
|
## [1.1.2] - 2026-05-15
|
|
6
13
|
|
|
7
14
|
### Changed
|
|
@@ -48,7 +55,8 @@
|
|
|
48
55
|
|
|
49
56
|
Initial release.
|
|
50
57
|
|
|
51
|
-
[Unreleased]: https://github.com/accodeing/rest-easy/compare/v1.
|
|
58
|
+
[Unreleased]: https://github.com/accodeing/rest-easy/compare/v1.2.0...HEAD
|
|
59
|
+
[1.2.0]: https://github.com/accodeing/rest-easy/compare/v1.1.2...v1.2.0
|
|
52
60
|
[1.1.2]: https://github.com/accodeing/rest-easy/compare/v1.1.1...v1.1.2
|
|
53
61
|
[1.1.1]: https://github.com/accodeing/rest-easy/compare/v1.1.0...v1.1.1
|
|
54
62
|
[1.1.0]: https://github.com/accodeing/rest-easy/compare/v1.0.0...v1.1.0
|
data/README.md
CHANGED
|
@@ -92,17 +92,100 @@ end
|
|
|
92
92
|
|
|
93
93
|
### Available settings
|
|
94
94
|
|
|
95
|
-
| Setting | Default | Description
|
|
96
|
-
|
|
97
|
-
| `
|
|
98
|
-
| `
|
|
99
|
-
| `
|
|
100
|
-
| `conversions.
|
|
101
|
-
| `
|
|
95
|
+
| Setting | Default | Description |
|
|
96
|
+
|----------------------------------|----------------------------|--------------------------------------------------------------------------------------------|
|
|
97
|
+
| `authentication` | `Auth::Null.new` | Authentication strategy |
|
|
98
|
+
| `base_url` | `"https://example.com"` | Base URL for all requests |
|
|
99
|
+
| `conversions.json_attributes` | `:PascalCase` | Naming convention for JSON response/request fields |
|
|
100
|
+
| `conversions.query_parameters` | `nil` (no transformation) | Naming convention for query parameter keys |
|
|
101
|
+
| `log_bodies` | `false` | When `true`, request/response bodies are logged. Off by default to avoid leaking domain secrets |
|
|
102
|
+
| `logger` | `nil` | When set, attaches Faraday's logger middleware and writes HTTP request/response details to it |
|
|
103
|
+
| `max_retries` | `3` | Retry count on request failure |
|
|
104
|
+
|
|
105
|
+
### Logging HTTP traffic
|
|
106
|
+
|
|
107
|
+
Set `logger` to any `Logger`-compatible instance to log HTTP request and response details. The middleware is Faraday's built-in `Faraday::Response::Logger` and is only attached when the setting is non-nil — no overhead when unset.
|
|
108
|
+
|
|
109
|
+
```ruby
|
|
110
|
+
module Acme
|
|
111
|
+
extend RestEasy
|
|
112
|
+
|
|
113
|
+
configure do |config|
|
|
114
|
+
config.logger = Logger.new($stdout)
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
By default, RestEasy logs request/response **lines and headers only**, with the following standard headers always filtered to `[FILTERED]`:
|
|
120
|
+
|
|
121
|
+
- `Authorization`
|
|
122
|
+
- `Proxy-Authorization`
|
|
123
|
+
- `Cookie`
|
|
124
|
+
- `Set-Cookie`
|
|
125
|
+
|
|
126
|
+
Request and response **bodies are not logged by default**, because bodies frequently carry API-specific secrets (OAuth token responses, signed payloads, PII) that RestEasy has no way to recognize.
|
|
127
|
+
|
|
128
|
+
> **Note:** The Faraday connection is built lazily on the first request and cached for the lifetime of the process. Changes to `logger` or `log_bodies` after the first request take effect only after restart.
|
|
129
|
+
|
|
130
|
+
#### Logging request/response bodies
|
|
131
|
+
|
|
132
|
+
If your API's bodies are safe to log — or you've added domain-specific scrubbing (see below) — opt in:
|
|
133
|
+
|
|
134
|
+
```ruby
|
|
135
|
+
module Acme
|
|
136
|
+
extend RestEasy
|
|
137
|
+
|
|
138
|
+
configure do |config|
|
|
139
|
+
config.logger = Logger.new($stdout)
|
|
140
|
+
config.log_bodies = true
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
#### Redacting domain-specific secrets
|
|
146
|
+
|
|
147
|
+
RestEasy only knows about HTTP-standard auth headers. If your API returns secrets in response bodies (e.g. an access-token endpoint), or uses non-standard headers like `X-Acme-Api-Key`, your consumer gem is responsible for scrubbing them. The simplest pattern is to wrap the `Logger` instance before handing it to RestEasy — sketched here as a `SimpleDelegator`:
|
|
148
|
+
|
|
149
|
+
```ruby
|
|
150
|
+
# Sketch — wrap the Logger in your gem so it scrubs your
|
|
151
|
+
# domain secrets out of each line before it's written.
|
|
152
|
+
|
|
153
|
+
class RedactingLogger < SimpleDelegator
|
|
154
|
+
# ...your scrubbing logic, applied to each log message...
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
module Acme
|
|
158
|
+
extend RestEasy
|
|
159
|
+
|
|
160
|
+
configure do |config|
|
|
161
|
+
config.logger = RedactingLogger.new(Logger.new($stdout))
|
|
162
|
+
config.log_bodies = true
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
#### Exposing a debug switch in your consumer gem
|
|
168
|
+
|
|
169
|
+
RestEasy does not read any environment variable itself — that decision belongs to the gem that wraps it. If you want consumers of your gem to flip logging on without editing code, expose your own env var and wire it to `config.logger`:
|
|
170
|
+
|
|
171
|
+
```ruby
|
|
172
|
+
module Acme
|
|
173
|
+
extend RestEasy
|
|
174
|
+
|
|
175
|
+
configure do |config|
|
|
176
|
+
if ENV["ACME_DEBUG"]
|
|
177
|
+
config.logger = RedactingLogger.new(Logger.new($stdout))
|
|
178
|
+
config.log_bodies = true
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
Now `ACME_DEBUG=1 bundle exec ...` turns on wire logging — with Acme-aware scrubbing — without any code changes in the consuming application.
|
|
102
185
|
|
|
103
186
|
### Faraday middleware
|
|
104
187
|
|
|
105
|
-
|
|
188
|
+
For middleware beyond the built-in logger, configure the underlying Faraday connection with a `connection` block:
|
|
106
189
|
|
|
107
190
|
```ruby
|
|
108
191
|
module Acme
|
data/lib/rest_easy/settings.rb
CHANGED
|
@@ -6,14 +6,16 @@ module RestEasy
|
|
|
6
6
|
class Settings
|
|
7
7
|
extend Dry::Configurable
|
|
8
8
|
|
|
9
|
+
setting :attribute_convention # deprecated — propagated to conversions.json_attributes in configure
|
|
10
|
+
setting :authentication, default: Auth::Null.new, reader: true
|
|
9
11
|
setting :base_url, default: "https://example.com", reader: true
|
|
12
|
+
setting :log_bodies, default: false, reader: true
|
|
13
|
+
setting :logger, reader: true
|
|
10
14
|
setting :max_retries, default: 3, reader: true
|
|
11
|
-
setting :authentication, default: Auth::Null.new, reader: true
|
|
12
|
-
setting :attribute_convention # deprecated — propagated to conversions.json_attributes in configure
|
|
13
15
|
|
|
14
16
|
setting :conversions do
|
|
15
|
-
setting :query_parameters, default: nil, reader: true
|
|
16
17
|
setting :json_attributes, default: Conventions::DEFAULT, reader: true
|
|
18
|
+
setting :query_parameters, default: nil, reader: true
|
|
17
19
|
end
|
|
18
20
|
end
|
|
19
21
|
end
|
data/lib/rest_easy/version.rb
CHANGED
data/lib/rest_easy.rb
CHANGED
|
@@ -66,6 +66,9 @@ module RestEasy
|
|
|
66
66
|
# ── Module extension (ClassMethods) ──────────────────────────────────
|
|
67
67
|
|
|
68
68
|
module ClassMethods
|
|
69
|
+
STANDARD_AUTH_HEADERS = %w[Authorization Proxy-Authorization Cookie Set-Cookie].freeze
|
|
70
|
+
private_constant :STANDARD_AUTH_HEADERS
|
|
71
|
+
|
|
69
72
|
def config
|
|
70
73
|
self::Settings.config
|
|
71
74
|
end
|
|
@@ -107,6 +110,16 @@ module RestEasy
|
|
|
107
110
|
@faraday_connection ||= Faraday.new(url: config.base_url) do |f|
|
|
108
111
|
f.request :json
|
|
109
112
|
f.response :json
|
|
113
|
+
if config.logger
|
|
114
|
+
# Faraday's logger emits headers as `Name: "value"` — the filters
|
|
115
|
+
# depend on that format. If the format changes, redaction silently
|
|
116
|
+
# breaks; the integration specs catch the common case.
|
|
117
|
+
f.response :logger, config.logger, bodies: config.log_bodies do |l|
|
|
118
|
+
STANDARD_AUTH_HEADERS.each do |name|
|
|
119
|
+
l.filter(/(#{Regexp.escape(name)}:\s*")[^"]+/i, '\1[FILTERED]')
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
end
|
|
110
123
|
@connection_block&.call(f)
|
|
111
124
|
end
|
|
112
125
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rest-easy
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Jonas Schubert Erlandsson
|
|
@@ -10,7 +10,7 @@ authors:
|
|
|
10
10
|
autorequire:
|
|
11
11
|
bindir: bin
|
|
12
12
|
cert_chain: []
|
|
13
|
-
date: 2026-05-
|
|
13
|
+
date: 2026-05-17 00:00:00.000000000 Z
|
|
14
14
|
dependencies:
|
|
15
15
|
- !ruby/object:Gem::Dependency
|
|
16
16
|
name: dry-types
|