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

Using external file with all definitions doesn't work #147

Closed
chuchiperriman opened this issue Dec 7, 2015 · 16 comments
Closed

Using external file with all definitions doesn't work #147

chuchiperriman opened this issue Dec 7, 2015 · 16 comments

Comments

@chuchiperriman
Copy link

We have a file with all the definitions for a given service in a separated file and we need to reuse it in multiple api definitions but we cannnot import it. The definition original definition file use model with nested models etc and we need to import a lot of these, we cannot repeat all the names with all the $refs in every api definition.

In this example we need import all the definitions from _testdrivemulti.yaml and use it in the main api definition but it doesn't work.

# Testing swagger
swagger: '2.0'
info:
  title: API ejemplo QIS
  description: Un ejemplo de definición para QIS usando swagger
  version: "1.0.0"
host: www.example.com
# array of all schemes that your API supports
schemes:
  - https
# will be prefixed to all paths
basePath: /v1
produces:
  - text/xml
  - application/json
securityDefinitions:
  apiKey:
    type: apiKey
    name: api_key
    in: query
paths:
  /testdrives:
    get:
      summary: Test Drives
      description: Detalle de vehículos
      security:
        - api_key: []
      parameters:
        - name: filtros
          in: body
          description: Body con todos los filtros aplicables
          required: true
          schema:
            $ref: '#/definitions/BusquedaGenerica'
      responses:
        200:
          description: Todo correcto
          schema:
            $ref: '#/definitions/TestDrive'

        default:
          description: Unexpected error
          schema:
            $ref: '#/definitions/Error'
definitions:
  $ref: './_testdrivemulti.yaml'
  Error:
    properties:
      code:
        type: integer
        format: int32
      message:
        type: string
      fields:
        type: string
Cliente:
  x-dms-file: FMCUCG
  properties:
    nombre:
      type: string
    apellido1:
      type: string
TestDrive:
  x-dms-file: FXTESTDRIVEPT
  properties:
    idv:
      type: integer
      description: Id del vehículo
    cliente:
      type: object
      $ref: '#/definitions/Cliente'
@fehguy
Copy link
Contributor

fehguy commented Dec 11, 2015

I believe the relative file references shouldn't have the ./ prefix. Please try using without and see if that works.

Unfortunately this is a hazy portion of the json-pointer spec, and it may not be consistent across all implementations.

@Kabhal
Copy link
Contributor

Kabhal commented Jan 15, 2016

I have the same problem, and it doesn't work better without ./ prefix.

Moreover, the same problem arises for the whole info and the whole paths blocks, so that we can't split swagger specs into smaller sections.

@fehguy
Copy link
Contributor

fehguy commented Jan 15, 2016

I missed something on the first commit. This:

definitions:
  $ref: './_testdrivemulti.yaml'
  Error:

is not legal. You cannot have any additional attribute as a sibling to a $ref per json schema.

What you should do instead is change the references from here:

$ref: '#/definitions/TestDrive'

To here:

$ref: '_testdrivemulti.yaml#/definitions/TestDrive'

@Kabhal
Copy link
Contributor

Kabhal commented Jan 15, 2016

you're right about sibling legality, anyway you shouldn't have to use this trick to use an external definition file :)

@fehguy
Copy link
Contributor

fehguy commented Jan 15, 2016

yes, we're not violating json schema at this point, even if it's painful sometimes.

@diegode
Copy link

diegode commented Aug 10, 2016

I think the point of this issue is that we should allow:

definitions:
  $ref: './defs.yaml'

or even:

definitions:
  $ref: './file.yaml#definitions'

and the same for any other section (parameters, responses, paths, etc), but this isn't supported at the moment, right?

diegode pushed a commit to medallia/swagger-parser that referenced this issue Sep 5, 2016
diegode pushed a commit to medallia/swagger-parser that referenced this issue Sep 5, 2016
@diegode
Copy link

diegode commented Sep 5, 2016

@fehguy please take a look at #298

@fehguy
Copy link
Contributor

fehguy commented Sep 7, 2016

@diegode well, I don't think that the $ref is technically allowed there, per the spec:

https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#patterned-fields-7

Thus I'm hesitant to include this. We are adding similar support in 3.0 though, so this may... sneak in. @webron ?

@diegode
Copy link

diegode commented Sep 8, 2016

@fehguy oh, I see your point. I'm in favor of this feature mainly because it's useful, the Swagger's JSON schema allows it, and so do validating tools like sway.
The omission of this from the Swagger spec seems unintended.

@webron
Copy link
Contributor

webron commented Sep 13, 2016

If the question is on whether:

definitions:
  $ref: './defs.yaml'

is allowed in 2.0 then the answer is 'definitely not'. Whether the JSON Schema allows it or not is irrelevant as the source of truth is the spec itself.

@diegode
Copy link

diegode commented Sep 19, 2016

Oh, I understand, thanks @webron. I thought that since the Swagger syntax is just a subset of JSON Schema, the reference mechanism has to be preserved (and so a {$ref: x} object should be dereferenced no matter where it is). Note that lots of Swagger tools out there do JSON Schema-based parsing, so they dereference all $refs as I said.
I don't know the rationale behind not allowing this. I know that this complicates the parsing a little bit, since we'll have to distinguish two types of dereferencing: "by-value" (which puts a copy of the referenced object) and "by-reference" (which leaves the reference as is).

I like that you are planning to support references in more places in 3.0 (e.g. OAI/OpenAPI-Specification#677 OAI/OpenAPI-Specification#680 OAI/OpenAPI-Specification#544), but I'd vote for references everywhere :)

@webron
Copy link
Contributor

webron commented Sep 19, 2016

@diegode That's a common mistake, but Swagger syntax is not a subset of JSON Schema. The Schema Object, under the Swagger spec is a subset of JSON Schema. The rest of the structure is just a JSON format we chose, and we chose to support JSON References in some places. I won't go into it here, but there are pros and cons to allowing JSON References everywhere. I agree we should extend the locations, I disagree we should allow them everywhere.

In any case, just because other tools dereference all the references automatically, doesn't make them right ;)

@monktastic
Copy link

monktastic commented Oct 20, 2016

Am I doing something wrong? I get bad behavior with this. In my main file I have:

 paths:
   /cogs:
     get:
       summary: List cogs
       tags:
         - Cogs
       responses:
         200:
           description: An array of cogs
           schema:
             type: array
             items:
               $ref: 'definitions.yaml#/definitions/Cog'
         default:
           description: Unexpected error
           schema:
             $ref: 'definitions.yaml#/definitions/Error'

And in definitions.yaml:

 definitions:
   CogSummary:
     type: object
     properties:
       id:
         type: string
         description: Unique identifier
         readOnly: true
       name:
         type: string
         description: Name of the cog.

   Cog:
     type: object
     properties:
       id:
         type: string
         description: Unique identifier.
         readOnly: true
       name:
         type: string
         description: Name of the cog.
      components:
        type: array
        items:
          $ref: '#/definitions/Component'
        description: List of components.
       status:
         type: string
         description: Status of the cog

   Component:
     type: object
     properties:
       id:
         type: string
         description: Unique identifier.
         readOnly: true
       name:
         type: string
         description: Name of the component.
       appId:
         type: string
         description: ID of the app this component belongs to.
 ...

Note how I only reference definitions/Cog in paths//cogs/get. It validates, but "swagger bundle" produces this under responses:

       responses:
         '200':
           description: An array of cogs
           schema:
             type: array
             items:
               definitions:
                 CogSummary:
                   type: object
                   properties:
                     id:
                       type: string
                       description: Unique identifier
                       readOnly: true
                     name:
                       type: string
                       description: Name of the cog.
                 Cog:
                   type: object
                   properties:
                     id:
                       type: string
                       description: Unique identifier.
                       readOnly: true
                     name:
                       type: string
                       description: Name of the cog.
                    components:
                      type: array
                      items:
                        $ref: >-
                          #/paths/~1cogs/get/responses/200/schema/items/definitions/Component
                      description: List of components.
                     status:
                       type: string
                       description: Status of the cog.
                 Component:
                   type: object
                   properties:
                     id:
                       type: string
                       description: Unique identifier.
                       readOnly: true
                     name:
                       type: string
                       description: Name of the component.
                     appId:
                       type: string
                       description: ID of the app this component belongs to.
 ...

Note:

  1. ALL definitions are dumped in there (not just Cog, as requested).
  2. The nasty ref replacement for Component: #/paths/~1cogs/get/responses/200/schema/items/definitions/Component.

Perhaps these are bugs I should file against swagger bundle in particular?

@fehguy
Copy link
Contributor

fehguy commented Oct 21, 2016

What is swagger bundle? Perhaps it's a project using this library. If so, you do need to open an issue there, or turn your case into something reproducable by this library directly.

The ref that you describe is a legal json pointer.

@monktastic
Copy link

Oops, my bad. It's part of a CLI I'm using that I thought was official. It's clearly not.

@fehguy
Copy link
Contributor

fehguy commented Oct 21, 2016

OK got it. There are two modes for the parser, which includes "resolving" and simply parsing. If resolving, it will pull remote definitions into the local file.

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 a pull request may close this issue.

6 participants