Say my OpenAPI definition has two servers. Both share the same variables. Thus I want to reference these variables to prevent duplicate code.
Actually I split my OpenAPI into files and combine it with swagger-cli bundle.
This is what it creates:
openapi: 3.0.2
info:
title: My API
description: 'some description'
version: 1.0.0
servers:
- url: 'https://stage-api.domain.com/foo/{v1}/{v2}/{v3}'
description: Staging API server for QA
variables:
v1:
description: 'variable 1'
default: 'something'
enum:
- 'foo1'
- 'foo2'
v2:
description: 'variable 2'
default: 'something'
enum:
- 'foo1'
- 'foo2'
v3:
description: 'variable 3'
default: 'something'
enum:
- 'foo1'
- 'foo2'
- url: 'https://api.domain.com/foo/{v1}/{v2}/{v3}'
description: PRODUCTION API server
variables:
region:
$ref: '#/servers/0/variables/v1'
brand:
$ref: '#/servers/0/variables/v2'
locale:
$ref: '#/servers/0/variables/v3'
paths: {}
Trying to validate this in Swagger Editor I get the following error:
Structural error at servers.1.variables.v1 should NOT have
additional properties additionalProperty: $ref Jump to line xx
Structural error at servers.1.variables.v1 should have required
property 'default' missingProperty: default Jump to line xx
Is it possible to reference the server variables or reuse them in another way?
Of course I could run swagger-cli bundle -r but I would want to prevent using that.
No, this is not supported. You can request changes to the OpenAPI Specification at
https://github.com/OAI/OpenAPI-Specification/issues
In your example, the server paths are almost the same except for the subdomain, so you can use a single server definition and make the subdomain a variable:
servers:
- url: 'https://{env}.domain.com/foo/{v1}/{v2}/{v3}'
variables:
env:
description: Environment - staging or production
default: stage-api
enum:
- stage-api
- api
# other variables
# ...
Related
Super basic (video) but the title is nearly my comment to Top 3 ways to run your containers on Google Cloud
User Authentication (content) in 2020 about api gateway from endpoints
Maybe a focal point for an answer could be the app engine role for api gateway in 2022. swagger.yaml (#comment)
# openapi2-run.yaml
swagger: "2.0"
info: # >1 API/service; spec x-google-api-name OpenAPI document extension.
title: backbank # mastercard-backbank # API_ID optional-string
#https://cloud.google.com/api-gateway/docs/get-started-cloud-run
description: node cloud run api mastercard p.12 customer keys # Sample API on API Gateway with a Cloud Run backend
version: 0.0.1
security:
- firebase: []
securityDefinitions: #https://cloud.google.com/api-gateway/docs/authenticating-users-firebase
firebase: #bearer https://cloud.google.com/endpoints/docs/openapi/openapi-extensions
authorizationUrl: "" # empty for firebase frm bearer Authorization?
flow: "implicit"
type: "oauth2"
x-google-issuer: "https://securetoken.google.com/vaumoney"
x-google-jwks_uri: "https://www.googleapis.com/service_accounts/v1/metadata/x509/securetoken#system.gserviceaccount.com"
x-google-audiences: "vaumoney"
host: "vault-co.in"
basePath: "/" # https://stackoverflow.com/questions/71258737/making-a-cloud-firestore-rest-api-call-through-cloud-endpoints
#When the basePath property is configured in the service configuration as well,
#this header applies only to URL paths that are prefixed by the basePath property value.
#URLs that aren't part of the basePath aren't passed through regardless of the x-google-allow property.
schemes:
- https
consumes:
- application/json
produces:
- application/json
#x-google-allow:
#all
#jwt_audience: https://www.googleapis.com/service_accounts/v1/metadata/x509/securetoken#system.gserviceaccount.com/vaumoney
#x-google-endpoints:
#- name: "vault-co.in"
#allowCors: True
paths:
/:
get:
summary: Yes Hello cloud run (api gateway, load balance) service
operationId: get
x-google-backend:
address: https://vault-co.in:8080 # APP_URL endpoint(s)
protocol: h2
responses:
200:
description: This is a (Non-Graphical) Application Programming Interface
#schema:
#type: string
#default: '''ello guv'''
default:
description: Something is wrong
#schema:
#type: string
#default: '''some not 200'''
options:
summary: Enable CORS with headers
operationId: options
x-google-backend:
address: https://vault-co.in:8080 # APP_URL endpoint(s)
jwt_audience: https://vault-co.in
protocol: h2
description: |
Origin, Methods and Headers allowing headers potentially requested
tags:
- CORS
responses:
200:
description: OPTIONS responding headers
headers:
Access-Control-Allow-Origin:
type: string
#$ref: '#/definitions/String'
default: "'i7l8qe.csb.app'"
Access-Control-Allow-Methods:
type: string
default: "'GET,POST'"
Access-Control-Allow-Headers:
type: string
default: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key'"
403:
description: OPTIONS responding headers
headers:
Access-Control-Allow-Origin:
type: string
default: "'i7l8qe.csb.app'" # '''vau.money'''
Access-Control-Allow-Methods:
type: string
default: "'GET,POST'"
Access-Control-Allow-Headers:
type: string
default: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key'"
#content: {}
default:
description: Something is wrong
#type: string
#default: '''some not 200'''
post:
summary: Respond properly indeed
operationId: posted
x-google-backend:
address: https://vault-co.in:8080 # APP_URL endpoint(s)
jwt_audience: https://vault-co.in
protocol: h2
description: |
Successful api fetch
parameters:
- name: pageOffset
in: body
required: true
schema:
type: object
properties:
pageOffset:
description: pageOffset is required, try 0
type: string
pageLength:
description: pageLength is required, try 10
type: string
postalCode:
description: postalCode is required, try 11101
type: string
responses: # https://swagger.io/docs/specification/describing-responses/
default: #200
description: post result
#content:v3 application/json:
schema:
type: object
description: response ok
required:
- results
properties:
results:
#collectionFormat: csv
type: array
default: []
items:
type: string
meta:
type: object
properties:
title:
type: string
description:
type: string
I repeat attempts in seriatim:
gcloud api-gateway gateways delete backbank --location=us-central1
gcloud api-gateway api-configs delete backbank --api=backbank
gcloud api-gateway api-configs create backbank --api=backbank --openapi-spec=swagger.yaml --project=vaumoney --backend-auth-service-account=vaumoney#appspot.gserviceaccount.com
(a) gcloud endpoints services deploy swagger.yaml --project=vaumoney
(b) gcloud services enable vault-co.in (Principal-role permission name: "firebase-adminsdk")
gcloud run deploy backbank \
--image="gcr.io/vaumoney/endpoints-runtime-serverless:2.38.0-vault-co.in-2022-09-08r2" \
--set-env-vars ESPv2_ARGS=^++^--cors_preset=cors_with_regex++--cors_allow_origin_regex=^https:[/][/]i7l8qe.csb.app$++--cors_allow_methods=GET,POST,OPTIONS++--cors_allow_headers=Origin,Content-Type,Authorization,Referrer-Policy++--cors_allow_credentials \
--platform managed --project vaumoney
Of course, I incessantly get this:
The request was not authenticated. Either allow unauthenticated invocations or set the proper Authorization header. Read more at https://cloud.google.com/run/docs/securing/authenticating Additional troubleshooting documentation can be found at: https://cloud.google.com/run/docs/troubleshooting#unauthorized-client
But OPTIONS might be the problem (albeit "" on GET):
"This would be really useful for us, we're using cloud run for all our microservices and want to call these from a SPA via API Gateway." "We're back to Cloud Endpoints and ESPv2 for the time being, but we 100% see the benefits of the managed API Gateway, should CORS support be available for gRPC requests."
What am I to do?
I've openapi3.0 YAML file which is written according to openapi3.0 format and I am using $ swagger-cli validate simple_violation_bool.yaml and its gave True/False based on whether simple_violation_bool.yaml is valid OpenAPI 3.0 or not.
Below is the content of my OpenAPI3.0 yaml file i.e. simple_violation_bool.yaml and I am trying to add schema definition using $ref: './violation_schema.yaml#/NISE but it giving error during $ swagger-cli validate simple_violation_bool.yaml.
Below is my simple_violation_bool.yaml openapi3.0 YAML file.
simple_violation_bool.yaml
openapi: "3.0.0"
info:
version: 1.0.0
title: simple_violation_bool
license:
name: MIT
description: |
Simple violation in simple_violation_bool module
externalDocs:
description: NISE simple_violation_bool.
servers:
- url: https://swagger.io/specification/
paths: {}
components:
schemas:
NISE:
type: object
title: The Root Schema
required:
- description
- id
- name
- ports
properties:
description:
type: string
title: The Descripton Schema
schema:
$ref: './violation_schema.yaml#/NISE'
id:
type: integer
title: The Id Schema
default: 0
format: int64
schema:
$ref: './violation_schema.yaml#/NISE'
name:
type: string
title: The Name Schema
schema:
$ref: './violation_schema.yaml#/NISE'
ports:
type: array
title: The Ports Schema
schema:
$ref: './violation_schema.yaml#/NISE'
items:
type: integer
title: The items Schema
default: 0
schema:
$ref: './violation_schema.yaml#/NISE'
value:
type: object
title: The Value Schema
schema:
$ref: './violation_schema.yaml#/NISE'
And here is the content of schema definition file violation_schema.yaml which I am trying to add using $ref: './violation_schema.yaml.
violation_schema.yaml
NISE:
properties:
description:
type: string
id:
type: integer
name:
type: string
ports:
type: array
value:
type: object
Below is the error log after I run $ swagger-cli validate simple_violation_bool.yaml
Error Log:
Running swagger-cli validate on simple_violation_bool.yaml .....
Swagger schema validation failed.
Data does not match any schemas from 'oneOf' at #/components/schemas/NISE
Data does not match any schemas from 'oneOf' at #/components/schemas/NISE/properties/value
Additional properties not allowed: schema at #/properties/value
Missing required property: $ref at #/properties/value
Missing required property: $ref at #/components/schemas/NISE
JSON_OBJECT_VALIDATION_FAILED
Any insight on this issue?
Lastly, I've tried with some simple openapi3.0 yaml files in the same way and it's working without any issue.
Examples which I've tried
main.yaml
openapi: 3.0.1
info:
title: ping test
version: '1.0'
servers:
- url: 'http://localhost:8000/'
paths:
/some/ping:
get:
operationId: pingGet
responses:
'201':
description: OK
content:
application/json:
schema:
$ref: './other.yaml#/SomeObj'
components:
schemas: {}
other.yaml
SomeObj:
properties:
s1:
type: string
s3:
type: string
This simple example works without issue. i.e $ swagger-cli validate main.yaml outputs: main.yaml is valid
Looking forward to hearing soon & thanks for spending time to look into this descriptive question.
Arslan
The way in which you are trying to refer to the schema defined in the violation_schema.yaml from simple_violation_bool.yaml is not correct . You do not need to define $ref: './violation_schema.yaml#/NISE' line at against each property defined in the simple_violation_bool.yaml file . Also , since you are defining schema altogether in a different schema file violation_schema.yaml , you do not need to define all those values again in the simple_violation_bool.yaml,i.e id,name,ports,value,etc.. Let's try to understand in a simple way , lets say you were not defining a separate file for the schema, but referring it from within the same file , i.e simple_violation_bool.yaml, then in that case things will look something like this as below :
So ,based on below observation , i corrected your yaml files and now its validating properly .
simple_violation_bool.yaml
openapi: "3.0.0"
info:
version: 1.0.0
title: simple_violation_bool
license:
name: MIT
description: |
Simple violation in simple_violation_bool module
externalDocs:
description: NISE simple_violation_bool.
url: "https://simple_violation_bool.net"
servers:
- url: https://swagger.io/specification/
paths: {}
components:
schemas:
ROOT:
type: object
title: The Root Schema
$ref: 'violation_schema.yaml#/NISE'
violation_schema.yaml
NISE:
required:
- description
- id
- name
- ports
properties:
description:
type: string
title: The Descripton Schema
id:
type: integer
title: The Id Schema
default: 0
format: int64
name:
type: string
title: The Name Schema
ports:
type: array
title: The Ports Schema
items:
type: integer
title: The items Schema
default: 0
value:
type: object
title: The Value Schema
swagger-cli validate simple_violation_bool.yaml
simple_violation_bool.yaml is valid
I hope that it resolves the issue for you . Let me know if that helps !!
I have a collection of microservices, each with their own complete OpenAPI spec and a root level path
Microservice Definition
openapi: 3.0.0
info:
description: Microservice API
version: '0.0.1'
paths:
/:
get:
tags:
- Root
summary: Root Path
operationId: Root
responses:
'200':
description: Request was successful
deprecated: false
/healthcheck/ping:
get:
tags:
- Healthcheck
summary: Test the reachability of the microservice.
operationId: Ping
responses:
'200':
description: Request was successful
deprecated: false
And a root OpenAPI definition
openapi: "3.0.0"
info:
version: 1.0.0
title: API
servers:
- url: http://api.something.com/v1
paths:
/microservice1:
$ref: "https://storagebucket.someservice.com/service-definitions/microservice-swagger.yaml"
It's been my assumption that it's possible to arrange things this way but I'm getting a whole host of errors in the swagger editor for validity.
Using microservice-swagger.yaml#/paths/~1 gets me somewhere but I would expect that all the paths in the service yaml to simply be appended to the path in the main definition. Does anyone know how to achieve this?
(The reason behind it being to apply this root swagger to an API Gateway whilst maintaining each service as a self contained unit)
I would for example expect the resulting swagger to offer this as a path
/microservice1/healthcheck/ping
I have a following swagger file (parses fine with the Swagger online editor):
swagger: '2.0'
info:
title: Sample
version: 1.1.0
basePath: /base
paths:
/sample:
get:
summary: Gets the samples
parameters:
- $ref: '#parameters/reusableParam'
responses:
200:
description: Success
parameters:
reusableParam:
in: header
name: sample-param
required: true
type: string
description: Sample reusable parameter
When I run code generator on it:
java -jar swagger-codegen-cli-2.2.1.jar generate -i swagger.yaml -l java
It fails with an error:
Exception in thread "main" java.lang.NullPointerException
at io.swagger.codegen.DefaultGenerator.generateParameterId(DefaultGenerator.java:803)
at io.swagger.codegen.DefaultGenerator.processOperation(DefaultGenerator.java:727)
at io.swagger.codegen.DefaultGenerator.processPaths(DefaultGenerator.java:688)
at io.swagger.codegen.DefaultGenerator.generate(DefaultGenerator.java:376)
at io.swagger.codegen.cmd.Generate.run(Generate.java:223)
at io.swagger.codegen.SwaggerCodegen.main(SwaggerCodegen.java:36)
Am I doing something wrong in the definition of the reusable parameter?
There's a typo in your spec:
- $ref: '#parameters/reusableParam'
should be
- $ref: '#/parameters/reusableParam'
README.md on https://github.com/swagger-api/swagger-node says 'Kick the tires. Your API is live while you edit (Did we mention no code?)' -> 'Quit faking' on the next step.
So I was under impression that Swagger will generate a fake API for me.
However, if I use such swagger.yaml:
swagger: '2.0'
info:
title: test
description: test
version: "1.0.0"
host: localhost:10010
schemes:
- https
basePath: /api
produces:
- application/json
- text/event-stream
consumes:
- application/json
paths:
/pages:
get:
summary: test
description: test
responses:
200:
description: pages
schema:
type: array
items:
$ref: '#/definitions/Page'
default:
description: Unexpected error
schema:
$ref: '#/definitions/Error'
(where definitions are also given in config)
I receive 404 in both curl http://localhost:10010/api/pages and swagger editor (swagger project edit). I know about x-swagger-router-controller thing but I expected it to work out of the box. Am I doing something wrong?
I should've read the docs more carefully. Swagger gives us the mock mode (swagger project start -m)