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

Parse remote refs #9

Merged
merged 3 commits into from
Apr 28, 2024
Merged

Parse remote refs #9

merged 3 commits into from
Apr 28, 2024

Conversation

killondark
Copy link
Contributor

Hi @skryukov.
I want to make Full support for external $refs for your skooma gem(see this point in the Feature plans).
For this I patched json_skooma gem:

  • resolve, parse and read external $ref's value

In the skooma gem I rewrited yml files for tests:
skooma/examples/rails_app/docs/bar_openapi.yml

openapi: 3.1.0
info:
  title: OpenAPI Sample
  version: 1.0.0

paths:
  "/":
    get:
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: "https://raw.githubusercontent.com/username/test_yml/main/bar_components_item.yml"

    post:
      requestBody:
        content:
          application/json:
            schema:
              $ref: "https://raw.githubusercontent.com/username/test_yml/main/bar_components_item.yml"
      responses:
        "201":
          description: OK
          content:
            application/json:
              schema:
                $ref: "https://raw.githubusercontent.com/usernamek/test_yml/main/bar_components_item.yml"
        "400":
          description: Bad Request
          content:
            application/json:
              schema:
                $ref: "bar_components_error.yml"

username/test_yml/main/bar_components_item.yml

Item:
  type: object
  unevaluatedProperties: false
  required: [foo]
  properties:
    foo:
      type: string
      enum: [bar]

skooma/examples/rails_app/docs/bar_components_error.yml

Error:
  type: object
  unevaluatedProperties: false
  required: [message]
  properties:
    message:
      type: string

skooma/examples/rails_app/docs/baz_openapi.yml

openapi: 3.1.0
info:
  title: OpenAPI Sample
  version: 1.0.0

paths:
  "/":
    get:
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: "https://raw.githubusercontent.com/usernamek/test_yml/main/baz_components_item.yml"

    post:
      requestBody:
        content:
          application/json:
            schema:
              $ref: "https://raw.githubusercontent.com/usernamek/test_yml/main/baz_components_item.yml"
      responses:
        "201":
          description: OK
          content:
            application/json:
              schema:
                $ref: "https://raw.githubusercontent.com/usernamek/test_yml/main/baz_components_item.yml"
        "400":
          description: Bad Request
          content:
            application/json:
              schema:
                $ref: "baz_components_error.yml"

username/test_yml/main/baz_components_item.yml

Item:
  type: object
  unevaluatedProperties: false
  required: [foo]
  properties:
    foo:
      type: string
      enum: [baz]

skooma/examples/rails_app/docs/baz_components_error.yml

Error:
  type: object
  unevaluatedProperties: false
  required: [message]
  properties:
    message:
      type: string

Give me feedback please.

@skryukov
Copy link
Owner

skryukov commented Apr 26, 2024

Hey, @killondark, thanks for the PR!

The explicit requirement for JSONSkooma::Sources::Remote is intentional, as accessing external resources can be insecure.

For skooma, the bootstrap code might look something like this:

skooma = Skooma::RSpec[Rails.root.join("docs", "openapi.yml")]

skooma.schema.registry.add_source(
  "https://raw.githubusercontent.com/username/test_yml/",
  JSONSkooma::Sources::Remote.new("main"),
)

config.include skooma, type: :request

So, I think we have everything in place for this particular case (except for some proper documentation 😅). What do you think?

@killondark
Copy link
Contributor Author

killondark commented Apr 26, 2024

@skryukov, I thought differently: the basic openapi yml file remains local, but it is possible to specify some $ref links to external resources, and then read files from these sources.

Please, write me your opinion about Full support for external $refs for skooma: that abilities need to create.

Copy link
Owner

@skryukov skryukov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@killondark, I just tested the remotes, and we indeed need your fix! ❤️ Let's remove the auto-resolve part and keep only the url.open.read fix here.

Another issue is that my previous example sets sources after the schema has been read, which is too late. Here's a working example with some notes on improving the interface:

  # We probably should expose this via `Skooma::RSpec.registry` or allow passing a custom registry to the `Skooma::RSpec.[]` method.
  Skooma.create_registry(name: Skooma::Matchers::Wrapper::TEST_REGISTRY_NAME)
    .add_source(
      "https://raw.githubusercontent.com/killondark/test_yml/",
      JSONSkooma::Sources::Remote.new("https://raw.githubusercontent.com/killondark/test_yml/")
    )

  config.include Skooma::RSpec[path_to_openapi, coverage: :strict], type: :request

@@ -46,7 +46,7 @@ class Remote < Base
def read(relative_path)
path = suffix ? relative_path + suffix : relative_path
url = URI.join(base, path)
URI.parse(url).open.read
url.open.read
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's leave only this fix

@skryukov skryukov merged commit 7ba5f23 into skryukov:main Apr 28, 2024
7 checks passed
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.

2 participants