-
Notifications
You must be signed in to change notification settings - Fork 64
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
Introduce Post-Processing Hook for OpenAPI Spec Customization #206
Conversation
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## master #206 +/- ##
==========================================
+ Coverage 97.12% 97.15% +0.03%
==========================================
Files 15 15
Lines 521 528 +7
Branches 126 127 +1
==========================================
+ Hits 506 513 +7
Misses 15 15 ☔ View full report in Codecov by Sentry. |
I can imagine this use case, though I prefer de-randomizing described in #76 which can be applied to other tools.
Please elaborate on these use cases. |
@exoego I suspect that derandomization presented in #76 will only work for integer-based primary key sequencing, for UUIDs this PRs approach has better results. Also in #163 its mentioned in |
Ok, that makes sense to me. |
This was released in v0.17.0 |
This is my example for unrandomizing IDs 👍 RSpec::OpenAPI.post_process_hook = -> (path, records, spec) do
def fix_responses_example_values(spec, pattern, replacement_value)
RSpec::OpenAPI::HashHelper.matched_paths(spec, pattern).each do |paths|
example = spec.dig(*paths[0..-2])
example.each do |key, value|
case key.to_s
when /ids/
example[key] = value.map.with_index { |item, index| item.is_a?(Integer) ? replacement_value + index : "#{replacement_value}#{index}" } if value.is_a?(Array)
when /id/
example[key] = value.is_a?(Integer) ? replacement_value : replacement_value.to_s if value.present?
end
end
end
end
fix_responses_example_values(spec, 'paths.*.*.responses.*.content.*.example.*', 1)
fix_responses_example_values(spec, 'paths.*.*.responses.*.content.*.example.*.*', 2)
fix_responses_example_values(spec, 'paths.*.*.responses.*.content.*.example.*.*.*', 3)
def fix_parameters_example_values(spec, pattern, replacement_value)
RSpec::OpenAPI::HashHelper.matched_paths(spec, pattern).each do |paths|
parameters = spec.dig(*paths[0..-2])
parameters.each do |key, value|
case key.to_s
when 'example'
parameters[key] = replacement_value if value.is_a?(Integer)
when /ids/
parameters[key] = value.map.with_index { |item, index| item.is_a?(Integer) ? replacement_value + index : "#{replacement_value}#{index}" } if value.is_a?(Array)
when /id/
parameters[key] = value.is_a?(Integer) ? replacement_value : replacement_value.to_s
end
end
end
end
fix_parameters_example_values(spec, 'paths.*.*.parameters.*.example', 4)
fix_parameters_example_values(spec, 'paths.*.*.requestBody.content.*.example.*', 5)
fix_parameters_example_values(spec, 'paths.*.*.requestBody.content.*.example.*.*', 6)
end |
Description
This PR introduces a new feature: a post-processing hook that allows for custom modifications of the OpenAPI spec generated by our RSpec tests. It enables users to apply transformations or additions to the spec, such as unrandomizing IDs or adding custom fields, after the spec has been generated but before it is finalised.
Changes
post_process_hook
to apply custom modifications to the OpenAPI spec.@post_process_hook
initialized asnil
and made it accessible viaattr_accessor
.cleanup_schema!
and addedexecute_post_process_hook
, which calls the user-definedpost_process_hook
if it's provided."custom_field": "custom_value"
to the OpenAPI JSON and YAML docs as a proof of concept.Motivation
This enhancement was motivated by the need for greater flexibility in generating OpenAPI specs. Users often have specific requirements for their OpenAPI documentation, such as consistent example values, additional metadata, or custom formatting. By introducing a post-processing hook, we empower users to tailor the generated specs to their precise needs without modifying the core logic of rspec-openapi.
Usage
To utilize this feature, set the
RSpec::OpenAPI.post_process_hook
to a lambda that acceptspath
,records
, andspec
as arguments. Within this lambda, users can manipulate thespec
as needed. For example:This PR provides a foundational step towards more customizable and user-friendly OpenAPI spec generation, opening the door for numerous extensions and customizations based on user feedback and evolving requirements.