Skip to content
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

fix wrong resolving of responses component using $ref #277

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

potatogim
Copy link

@potatogim potatogim commented Oct 12, 2024

Summary

Fix wrong resolving of responses component using $ref.

OpenAPI supports the reusable responses with $ref keyword but it not work as expected.

Motivation

When I tested it, as described in issue #276, it didn't behave as expected.

So I tried to print some log messages in JSON::Validator::Schema::OpenAPIv3::parameters_for_response() method.

 93
 94   my $responses = $self->get([paths => $path, $method, 'responses']);
 95   my $response  = $responses->{$status} || $responses->{default};
 96   return undef unless $response;
 97
 98   use Data::Dumper;
 99
100   warn "response: ${\Dumper($response)}";
101

and here's what I got

response: $VAR1 = {
          '$ref' => '#/components/responses/Potato'
};

Here we can see that the subpath was not parsed because we only specified up to responses as the path parameter to the get() method.

Therefore, I think we should explicitly include the HTTP return code($status) in the path parameter to support defining reusable responses and using them with the $ref keyword.

References

  • https://swagger.io/docs/specification/v3_0/describing-responses/#reusing-responses

  • Test Result
    sh run-all-tests.sh
    $ cd ../json-validator && prove -l
    t/00-project.t ......................... ok
    t/benchmark.t .......................... skipped: TEST_BENCHMARK=500
    t/bundle.t ............................. ok
    t/coerce-default.t ..................... ok
    t/coerce.t ............................. ok
    t/deep-mixed-ref.t ..................... ok
    t/draft2019-09-acceptance.t ............ skipped: TEST_ACCEPTANCE=1
    t/draft2019-09.t ....................... ok
    t/draft4-acceptance.t .................. skipped: TEST_ACCEPTANCE=1
    t/draft4.t ............................. ok
    t/draft6-acceptance.t .................. skipped: TEST_ACCEPTANCE=1
    t/draft6.t ............................. ok
    t/draft7-acceptance.t .................. skipped: TEST_ACCEPTANCE=1
    t/draft7.t ............................. ok
    t/get.t ................................ ok
    t/id-keyword-draft4.t .................. ok
    t/id-keyword-draft7.t .................. ok
    t/invalid-ref.t ........................ ok
    t/issue-103-one-of.t ................... ok
    t/issue-158-draf7-coerce-defaults.t .... ok
    t/issue-22-duplicate-error-messages.t .. ok
    t/issue-42-cache-control.t ............. skipped: TEST_ONLINE=1
    t/issue-59-oneof-blessed-booleans.t .... ok
    t/issue-71-additionalproperties.t ...... ok
    t/joi.t ................................ ok
    t/jv-allof-and-not.t ................... ok
    t/jv-allof.t ........................... ok
    t/jv-anyof.t ........................... ok
    t/jv-array.t ........................... ok
    t/jv-basic.t ........................... ok
    t/jv-boolean.t ......................... ok
    t/jv-const.t ........................... ok
    t/jv-enum.t ............................ ok
    t/jv-formats.t ......................... 1/? [JSON::Validator] Cannot validate hostname format: Data::Validate::Domain is missing at /home/potatogim/workspace/github/jhthorsen/json-validator/lib/JSON/Validator/Formats.pm line 221.
    [JSON::Validator] Cannot validate hostname format: Data::Validate::Domain is missing at /home/potatogim/workspace/github/jhthorsen/json-validator/lib/JSON/Validator/Formats.pm line 221.
    [JSON::Validator] Cannot validate idn-email format: Net::IDN::Encode is missing at /home/potatogim/workspace/github/jhthorsen/json-validator/lib/JSON/Validator/Formats.pm line 221.
    [JSON::Validator] Cannot validate idn-hostname format: Net::IDN::Encode is missing at /home/potatogim/workspace/github/jhthorsen/json-validator/lib/JSON/Validator/Formats.pm line 221.
    [JSON::Validator] Cannot validate ipv6 format: Data::Validate::IP is missing at /home/potatogim/workspace/github/jhthorsen/json-validator/lib/JSON/Validator/Formats.pm line 221.
    [JSON::Validator] Cannot validate ipv6 format: Data::Validate::IP is missing at /home/potatogim/workspace/github/jhthorsen/json-validator/lib/JSON/Validator/Formats.pm line 221.
    t/jv-formats.t ......................... ok
    t/jv-if-then-else.t .................... ok
    t/jv-integer.t ......................... ok
    t/jv-not.t ............................. ok
    t/jv-number.t .......................... ok
    t/jv-object.t .......................... ok
    t/jv-oneof.t ........................... ok
    t/jv-required.t ........................ ok
    t/jv-string.t .......................... ok
    t/load-data.t .......................... ok
    t/load-file.t .......................... ok
    t/load-from-app.t ...................... ok
    t/load-http.t .......................... skipped: TEST_ONLINE=1
    t/load-json.t .......................... 1/? Mojo::File::spurt is deprecated in favor of Mojo::File::spew at t/load-json.t line 21.
    t/load-json.t .......................... ok
    t/load-yaml-pp.t ....................... skipped: YAML::PP not available
    t/load-yaml.t .......................... ok
    t/more-bundle.t ........................ ok
    t/newline-warnings.t ................... ok
    t/openapiv2-basic.t .................... ok
    t/openapiv2-bundle.t ................... ok
    t/openapiv2-collection-format.t ........ ok
    t/openapiv2-default-values.t ........... ok
    t/openapiv2-discriminator.t ............ ok
    t/openapiv2-file.t ..................... ok
    t/openapiv2-headers.t .................. ok
    t/openapiv2-readonly.t ................. ok
    t/openapiv2-routes.t ................... ok
    t/openapiv3-basic.t .................... ok
    t/openapiv3-coerce-array.t ............. ok
    t/openapiv3-default-values.t ........... ok
    t/openapiv3-discriminator.t ............ ok
    t/openapiv3-nullable.t ................. ok
    t/openapiv3-readonly-writeonly.t ....... ok
    t/openapiv3-style-explode.t ............ ok
    t/predictable-errors.t ................. ok
    t/random-errors.t ...................... skipped: TEST_RANDOM_ITERATIONS=10000
    t/recursive_data_protection.t .......... ok
    t/relative-ref.t ....................... ok
    t/to-json.t ............................ ok
    t/unicode-multibyte.t .................. 1/? Wide character in print at /home/potatogim/.perl5/perlbrew/perls/perl-5.40.0/lib/5.40.0/Test2/Formatter/TAP.pm line 156.
    Wide character in print at /home/potatogim/.perl5/perlbrew/perls/perl-5.40.0/lib/5.40.0/Test2/Formatter/TAP.pm line 156.
    Wide character in print at /home/potatogim/.perl5/perlbrew/perls/perl-5.40.0/lib/5.40.0/Test2/Formatter/TAP.pm line 156.
    Wide character in print at /home/potatogim/.perl5/perlbrew/perls/perl-5.40.0/lib/5.40.0/Test2/Formatter/TAP.pm line 156.
    t/unicode-multibyte.t .................. ok
    t/uri.t ................................ ok
    t/util-checksum-yaml-xs.t .............. ok
    t/util.t ............................... ok
    t/validate-draft07.t ................... ok
    t/validate-id.t ........................ ok
    t/validate-recursive.t ................. ok
    t/validate-schema.t .................... ok
    All tests successful.
    Files=80, Tests=852, 19 wallclock secs ( 0.21 usr  0.09 sys + 16.79 cusr  1.98 csys = 19.07 CPU)
    Result: PASS
    $ cd ../mojolicious-plugin-openapi && prove -l
    t/00-project.t ......................... ok
    t/basic-404-501.t ...................... ok
    t/basic-autorender.t ................... ok
    t/basic-bundle.t ....................... ok
    t/basic-coerce.t ....................... ok
    t/basic-correct-order-of-paths.t ....... ok
    t/basic-custom-formats.t ............... ok
    t/basic-custom-renderer.t .............. ok
    t/basic-custom-validation.t ............ ok
    t/basic-empty-response.t ............... ok
    t/basic-invalid-json-input.t ........... ok
    t/basic-legacy-swagger2.t .............. ok
    t/basic-mojo-placeholder.t ............. ok
    t/basic-mojo-route-names.t ............. ok
    t/basic-path-parameters.t .............. ok
    t/basic-register-plugin.t .............. ok
    t/basic-under-route-authenticate.t ..... ok
    t/jv-recursion.t ....................... ok
    t/plugin-cors.t ........................ ok
    t/plugin-security-extended-status.t .... ok
    t/plugin-security-rules-not-defined.t .. ok
    t/plugin-security-v2.t ................. ok
    t/plugin-security-v3.t ................. ok
    t/plugin-spec-renderer-doc.t ........... ok
    t/plugin-spec-renderer-options.t ....... ok
    t/plugin-spec-renderer-standalone.t .... ok
    t/plugin-spec-renderer-v3.t ............ ok
    t/v2-basic.t ........................... ok
    t/v2-body.t ............................ invalid_json at t/v2-body.t line 9.
    t/v2-body.t ............................ 1/? [{"cool":"beans"}] at t/v2-body.t line 9.
    ["str"] at t/v2-body.t line 9.
    t/v2-body.t ............................ ok
    t/v2-collectionformat.t ................ ok
    t/v2-defaults.t ........................ ok
    t/v2-discriminator.t ................... ok
    t/v2-file.t ............................ ok
    t/v2-formats.t ......................... 1/? Format rule for 'unknown' is missing at /home/potatogim/workspace/github/jhthorsen/json-validator/lib/JSON/Validator/Schema.pm line 605.
    t/v2-formats.t ......................... ok
    t/v2-headers.t ......................... ok
    t/v2-id-prop.t ......................... ok
    t/v2-readonly.t ........................ ok
    t/v2-swagger.t ......................... ok
    t/v2-tutorial.t ........................ ok
    t/v2-validate-schema.t ................. ok
    t/v3-basic.t ........................... ok
    t/v3-body.t ............................ ok
    t/v3-bundle.t .......................... ok
    t/v3-defaults.t ........................ ok
    t/v3-file.t ............................ ok
    t/v3-invalid_file_refs.t ............... ok
    t/v3-invalid_file_refs_no_path.t ....... ok
    t/v3-nullable.t ........................ ok
    t/v3-style-array.t ..................... ok
    t/v3-style-object.t .................... ok
    t/v3-tutorial.t ........................ ok
    t/v3-valid_file_refs.t ................. ok
    t/v3-writeonly.t ....................... ok
    All tests successful.
    
    Test Summary Report
    -------------------
    t/v2-formats.t                       (Wstat: 0 Tests: 30 Failed: 0)
      TODO passed:   15, 21-22
    Files=53, Tests=795, 18 wallclock secs ( 0.16 usr  0.05 sys + 15.83 cusr  1.59 csys = 17.63 CPU)
    Result: PASS
    $ cd ../openapi-client && prove -l
    

@potatogim
Copy link
Author

potatogim commented Oct 12, 2024

I think that the code change I'm suggesting is inefficient in terms of performance. (Although you might think that's not a bad thing, as it will be cached after the first response.)

If there is a more efficient way to fix this, please let me know 😅

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant