redocly-cli
redocly-cli copied to clipboard
Possible bug while bundling
Describe the bug The bundle command does not bundle schemas and parameters properly
To Reproduce
- Extract attached zip openapi.zip
- Run:
docker run --rm -v $PWD:/spec redocly/openapi-cli bundle /spec/openapi-zip/Openapi.yaml -o /spec/openapi-zip/_build/Openapi.yaml --lint
Expected behavior
File is bundled so that no $ref are present under components.schemas.Pet and components.parameters.PetId
Logs Output of docker command:
No configurations were defined in extends -- using built in recommended configuration by default.
[openapi.zip](https://github.com/Redocly/openapi-cli/files/8554891/openapi.zip)
Woohoo! Your OpenAPI definitions are valid. 🎉
bundling /spec/openapi/Openapi.yaml...
📦 Created a bundle for /spec/openapi-zip/Openapi.yaml at /spec/openapi-zip/_build/Openapi.yaml 55ms.
OpenAPI definition OpenApi 3.0.3
openapi-cli Version(s)
latest docker image as of date of posting this issue
Node.js Version(s)
N/A
Additional context N/A
I don't think this is a bug bundling (perhaps a bug linting).
Source: https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#componentsObject
Excerpt from the OpenAPI definition:
components:
schemas:
$ref: "./schemas/_index.yaml"
parameters:
$ref: "./parameters/_index.yaml"
In the snippet above, schemas and parameters are part of components and should contain a map of strings to schemas or reference objects.
It would be correct like this:
components:
schemas:
Pet:
$ref: ./schemas/Pet.yaml
parameters:
PetId:
$ref: ./parameters/PetId.yaml
On the other hand, bundle will dynamically create the components if they are used as $ref to files from your operations. For example, your operation is already set up like this:
get:
tags:
- pet
summary: Info for a specific pet
operationId: showPetById
parameters:
- $ref: '../parameters/PetId.yaml'
responses:
'200':
description: Expected response to a valid request
content:
application/json:
schema:
$ref: "../schemas/Pet.yaml"
'400':
description: Error
If we remove components from the root file (I commented it out here):
openapi: 3.0.3
servers:
- url: 'http://example.com/v1'
info:
description: >-
Petstore
version: 0.1.0
title: Petstore
license:
name: license
url: 'https://example.com'
tags:
- name: pet
description: pet store
paths:
/pets/{petId}:
$ref: "./paths/Pet.yaml"
# components:
# schemas:
# $ref: "./schemas/_index.yaml"
# parameters:
# $ref: "./parameters/_index.yaml"
Then the result of bundle is:
bundling Openapi.yaml...
openapi: 3.0.3
servers:
- url: http://example.com/v1
info:
description: Petstore
version: 0.1.0
title: Petstore
license:
name: liscense
url: https://example.com
tags:
- name: pet
description: pet store
paths:
/pets/{petId}:
get:
tags:
- pet
summary: Info for a specific pet
operationId: showPetById
parameters:
- $ref: '#/components/parameters/PetId'
responses:
'200':
description: Expected response to a valid request
content:
application/json:
schema:
$ref: '#/components/schemas/Pet'
'400':
description: Error
components:
parameters:
PetId:
name: petId
in: path
required: true
description: The id of the pet to retrieve
schema:
type: string
schemas:
Pet:
type: object
required:
- id
- name
properties:
id:
type: integer
format: int64
name:
type: string
tag:
type: string
Thanks for taking the time to look into this.
I did try your solutions.
- When I replaced components like this:
components:
schemas:
Pet:
$ref: ./schemas/Pet.yaml
parameters:
PetId:
$ref: ./parameters/PetId.yaml
I got duplicated components:
components:
schemas:
Pet:
type: object
required:
...
properties:
...
Pet-2:
type: object
required:
...
properties:
...
parameters:
PetId:
name: petId
...
PetId-2:
name: petId
...
The bundler spits out the following warning:
bundling /spec/openapi/spec/openapi.yaml...
[1] openapi/spec/paths/Pet.yaml:7:7 at #/get/parameters/0
Two schemas are referenced with the same name but different content. Renamed PetId to PetId-2.
5 | operationId: showPetById
6 | parameters:
7 | - $ref: '../parameters/PetId.yaml'
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
8 | responses:
9 | '200':
Warning was generated by the bundler rule.
[2] openapi/spec/paths/Pet.yaml:14:13 at #/get/responses/200/content/application~1json/schema
Two schemas are referenced with the same name but different content. Renamed Pet to Pet-2.
12 | application/json:
13 | schema:
14 | $ref: "../schemas/Pet.yaml"
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
-
Commenting out the components and letting them be generated works
-
I also tried adding the
-doption to the CLI arguments - this produced the same result as 2 but without having to comment out the components section.
Furthermore, both 2 and 3 produce a strange bundle with a bunch of &refs and *refs:
paths:
/pets/{petId}:
get:
tags:
- pet
summary: Info for a specific pet
operationId: showPetById
parameters:
- name: petId
...
schema: &ref_0
type: string
responses:
'200':
description: Expected response to a valid request
content:
application/json:
schema:
type: object
required: &ref_1
...
properties: &ref_2
...
components:
parameters:
PetId:
name: petId
...
schema: *ref_0
schemas:
Pet:
type: object
required: *ref_1
properties: *ref_2
But OpenAPI generator seems to parse it without errors.
@bal-stan you did not quite try my solution. Do not put this:
components:
schemas:
Pet:
$ref: ./schemas/Pet.yaml
parameters:
PetId:
$ref: ./parameters/PetId.yaml
Those will be generated automatically when they are recognized as referenced during the bundling process. If there is a naming collision, we add the -2, etc... You can see from my resulting bundle above there is no double schemas.
@adamaltman i tried that - that works. See 2. in my previous comment.
Chances are, this will be resolved with this.
Should be fixed in v1.0.0-beta.127.