I'm trying to split a large yml into a bunch of smaller yml documents. I followed the example provided by David Garcia here, and then using OpenAPI CodeGenerator to generate my models. OpenAPI Generator complained that [BUG] attribute components.schemas.Schema name doesn't adhere to regular expression ^[a-zA-Z0-9.-_]+$
. So, I tried playing with David Garcia's example by cloning his repo and deploying locally, but I get the same error. I decided to check it in the swagger editor, and I get the same issue, but the error message says
Semantic error at components.schemas.$ref
Component names can only contain the characters A-Z a-z 0-9 - . _
Jump to line 25
I'm using the yaml from David Garcia's example:
openapi: "3.0.0"
info:
version: 1.0.0
title: Swagger Petstore
description: Multi-file boilerplate for OpenAPI Specification.
license:
name: MIT
contact:
name: API Support
url: http://www.example.com/support
email: support@example.com
servers:
- url: http://petstore.swagger.io/v1
tags:
- name: pets
paths:
/pets:
$ref: "./resources/pets.yaml"
/pets/{petId}:
$ref: "./resources/pet.yaml"
components:
parameters:
$ref: "./parameters/_index.yaml"
schemas:
$ref: "./schemas/_index.yaml"
responses:
$ref: "./_index.yaml"
You can easily paste this into the editor and see the errors yourself. The OpenAPI Specification says components objects can either be an Object or a Reference, i.e. Map[string, Schema Object | Reference Object]
, and the Schema Object definition says, "Alternatively, any time a Schema Object can be used, a Reference Object can be used in its place. "
I'm aware that I can sub it down within the yaml document, like so:
components:
parameters:
petId:
$ref: "./parameters/path/petId.yaml"
schemas:
pets:
$ref: "./schemas/Pets.yaml"
responses:
responseSchema:
$ref: "./response/pets200.yaml"
But why can't I reference an external index? The online example says yes and the open api spec says yes, but I can't get it to work.
It's a common misconception that the OpenAPI Specification allows $ref
anywhere. Actually, $ref
is only allowed in places where the OpenAPI Specification says the value of a field can be a "Reference Object" or a "Schema Object".
Specifically, this snippet is NOT valid OpenAPI syntax:
components:
parameters:
$ref: "./parameters/_index.yaml"
schemas:
$ref: "./schemas/_index.yaml"
responses:
$ref: "./_index.yaml"
Map[string, Schema Object | Reference Object]
means that the components.schemas
node must be a map where the keys are schema names and the values are either inline schemas or schema references. As in your second example (which is valid OpenAPI syntax):
components:
parameters: # Map
petId: # <string,
$ref: "./parameters/path/petId.yaml" # Reference Object>
schemas:
pets:
$ref: "./schemas/Pets.yaml"
responses:
responseSchema:
$ref: "./response/pets200.yaml"
The workaround that some implementations use to handle $refs in any places is to pre-process the spec using a generic JSON $ref resolver (such as json-refs) to resolve those non-standard $refs. For example, the blog post you took this example from uses swagger-cli
to resolve non-standard $refs and create a single merged file.