Skip to content

Parse remote refs#9

Merged
skryukov merged 3 commits intoskryukov:mainfrom
killondark:parse-remote-refs
Apr 28, 2024
Merged

Parse remote refs#9
skryukov merged 3 commits intoskryukov:mainfrom
killondark:parse-remote-refs

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

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
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