-
Notifications
You must be signed in to change notification settings - Fork 0
Adds separate configs for attributes and parameters #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
bbb73bc
d21f455
4b2f10b
82d9f09
f540047
8991cd7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| # Changelog | ||
|
|
||
| ## [1.1.0] - 2026-03-25 | ||
|
|
||
| ### Added | ||
|
|
||
| - **`conversions` configuration** with independent `query_parameters` and `json_attributes` sub-keys. This allows APIs that use different naming conventions for query parameters vs JSON body attributes to be configured correctly: | ||
|
|
||
| ```ruby | ||
| module MyAPI | ||
| extend RestEasy | ||
|
|
||
| configure do | ||
| conversions.json_attributes = :camelCase | ||
| conversions.query_parameters = :PascalCase | ||
| end | ||
| end | ||
| ``` | ||
|
|
||
| - **Automatic query parameter key transformation.** `Resource.get` now transforms parameter keys according to the `query_parameters` convention before sending the request. This removes the need for manual `transform_keys` calls in consuming gems. | ||
|
|
||
| - `conversions` can be overridden per Resource class, with inheritance falling back to the parent API module configuration. | ||
|
|
||
| ### Deprecated | ||
|
|
||
| - **`attribute_convention`** is deprecated in favour of `conversions.json_attributes`. The old setting continues to work and is respected as a fallback, but emits a deprecation warning when used at the Resource level. Module-level `attribute_convention` is silently supported for backwards compatibility. | ||
|
|
||
| ## [1.0.0] | ||
|
|
||
| Initial release. | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -83,6 +83,13 @@ def configure(&block) | |||||||||||||||
| else | ||||||||||||||||
| yield self::Settings.config | ||||||||||||||||
| end | ||||||||||||||||
|
|
||||||||||||||||
| # BC: propagate deprecated attribute_convention to conversions | ||||||||||||||||
| ac = self::Settings.config.attribute_convention | ||||||||||||||||
| if ac | ||||||||||||||||
| warn "RestEasy: attribute_convention is deprecated, use `conversions.json_attributes = #{ac.inspect}` instead" | ||||||||||||||||
| self::Settings.config.conversions.json_attributes = ac | ||||||||||||||||
|
Comment on lines
+89
to
+91
|
||||||||||||||||
| if ac | |
| warn "RestEasy: attribute_convention is deprecated, use `conversions.json_attributes = #{ac.inspect}` instead" | |
| self::Settings.config.conversions.json_attributes = ac | |
| conv = self::Settings.config.conversions | |
| if ac && conv.json_attributes.nil? | |
| warn "RestEasy: attribute_convention is deprecated, use `conversions.json_attributes = #{ac.inspect}` instead" | |
| conv.json_attributes = ac |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -9,6 +9,11 @@ class Resource | |||||||||||||||||||||||||||||||||||||||||||||||||
| setting :path | ||||||||||||||||||||||||||||||||||||||||||||||||||
| setting :debug, default: false | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| setting :conversions do | ||||||||||||||||||||||||||||||||||||||||||||||||||
| setting :query_parameters # nil default — falls back to parent module | ||||||||||||||||||||||||||||||||||||||||||||||||||
| setting :json_attributes # nil default — falls back to parent module | ||||||||||||||||||||||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| # ── Types ───────────────────────────────────────────────────────────── | ||||||||||||||||||||||||||||||||||||||||||||||||||
| # Include Types so the full Dry::Types vocabulary (Strict::String, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| # Coercible::Integer, Params::Date, etc.) is available without prefix. | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -143,16 +148,31 @@ def metadata(**kwargs) | |||||||||||||||||||||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| # -- attribute_convention ------------------------------------------ | ||||||||||||||||||||||||||||||||||||||||||||||||||
| # -- conversions --------------------------------------------------- | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What happened with small single responsibility classes? This class is huge. Also I'm not a fan of these comments. If this is a separate concern in this class then it might be a sign that we can extract it to a separate class that we can test in isolation 😄 |
||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| def json_attribute_converter | ||||||||||||||||||||||||||||||||||||||||||||||||||
| @json_attribute_converter ||= Conventions.resolve( | ||||||||||||||||||||||||||||||||||||||||||||||||||
| config.conversions.json_attributes || | ||||||||||||||||||||||||||||||||||||||||||||||||||
| parent&.config&.conversions&.json_attributes | ||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| def query_parameter_converter | ||||||||||||||||||||||||||||||||||||||||||||||||||
| @query_parameter_converter ||= Conventions.resolve( | ||||||||||||||||||||||||||||||||||||||||||||||||||
| config.conversions.query_parameters || | ||||||||||||||||||||||||||||||||||||||||||||||||||
| parent&.config&.conversions&.query_parameters | ||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+154
to
+164
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| @json_attribute_converter ||= Conventions.resolve( | |
| config.conversions.json_attributes || | |
| parent&.config&.conversions&.json_attributes | |
| ) | |
| end | |
| def query_parameter_converter | |
| @query_parameter_converter ||= Conventions.resolve( | |
| config.conversions.query_parameters || | |
| parent&.config&.conversions&.query_parameters | |
| ) | |
| convention = | |
| config.conversions.json_attributes || | |
| parent&.config&.conversions&.json_attributes || | |
| :snake_case | |
| Conventions.resolve(convention) | |
| end | |
| def query_parameter_converter | |
| convention = | |
| config.conversions.query_parameters || | |
| parent&.config&.conversions&.query_parameters || | |
| :snake_case | |
| Conventions.resolve(convention) |
Copilot
AI
Mar 26, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
params.transform_keys! mutates the caller-provided params hash and will raise if the hash is frozen. This can cause surprising side effects for callers reusing a params hash across requests. Prefer a non-mutating transform (e.g., build a new hash and pass that to parent.get) and leave the input untouched.
| params.transform_keys! { |k| query_parameter_converter.serialise(k) } | |
| parent.get(path:, params:, headers:) | |
| converted_params = params.transform_keys { |k| query_parameter_converter.serialise(k) } | |
| parent.get(path:, params: converted_params, headers:) |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -9,6 +9,11 @@ class Settings | |||||||||||||||||||||
| setting :base_url, default: "https://example.com", reader: true | ||||||||||||||||||||||
| setting :max_retries, default: 3, reader: true | ||||||||||||||||||||||
| setting :authentication, default: Auth::Null.new, reader: true | ||||||||||||||||||||||
| setting :attribute_convention, default: :PascalCase, reader: true | ||||||||||||||||||||||
| setting :attribute_convention # deprecated — propagated to conversions.json_attributes in configure | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| setting :conversions do | ||||||||||||||||||||||
| setting :query_parameters, default: :snake_case, reader: true | ||||||||||||||||||||||
| setting :json_attributes, default: :snake_case, reader: true | ||||||||||||||||||||||
|
Comment on lines
+12
to
+16
|
||||||||||||||||||||||
| setting :attribute_convention # deprecated — propagated to conversions.json_attributes in configure | |
| setting :conversions do | |
| setting :query_parameters, default: :snake_case, reader: true | |
| setting :json_attributes, default: :snake_case, reader: true | |
| setting :attribute_convention, default: :PascalCase # deprecated — propagated to conversions.json_attributes in configure | |
| setting :conversions do | |
| setting :query_parameters, default: :snake_case, reader: true | |
| setting :json_attributes, default: :PascalCase, reader: true |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,5 @@ | ||
| # frozen_string_literal: true | ||
|
|
||
| module RestEasy | ||
| VERSION = "1.0.0" | ||
| VERSION = "1.1.0" | ||
| end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The changelog says module-level
attribute_conventionis "silently supported" for backwards compatibility, butRestEasy.configurecurrently emits a deprecation warning when it seesattribute_conventionset. Either update the changelog wording or adjust the implementation to avoid warning at the module level (and only warn for resource-level usage).