Open Download opened 7 years ago
@Download There is no reason that tooling could not use environment variables to drive ServerVariables
that are used for constructing the base URL of the API.
However, I don't know whether we would want to enable arbitrary variables through the spec that would need to be resolved from the environment before the spec is processable. What are the limits? Can an environment variable be used to define part of the path of a path item key? Can an environment variable be used to provide values to Schema properties? Does this introduce a pre-processing stop for resolving variables before being able to validate the spec?
Yeah I see your issue. Where does it stop? Personally I would want this feature to be able to change some URL's, like for the oauth server. I used to have a static swagger.json file, but had to turn it into a dynamically served file to be able to change the URL.
A whole different approach might be to have a setup with profiles for different situations, where you could specify e.g. multiple auth configs and select one.
I understand it's a complex issue. Maybe the spec isn't the right place for it and it should be moved to the tooling itself.
I am looking at if/how overlays can solve this problem as part of determining whether overlay spec is sufficient. I won't comment on other solutions now.
An example overlay to update servers and auth urls, assuming authentication like this example is in contract - https://swagger.io/docs/specification/authentication/. You could also give the whole securityScheme object instead.
{
"overlay": "1.0.0",
"info": {
"title": "Servers and Authentication Overlay",
"version": "1.0.0"
},
"actions": [
{
"target": "info",
"update": {
"x-overlay-applied": "common-servers-auth"
}
},
{
"description": "Add default servers",
"target": "@",
"update": {
"servers": [
{
"description": "Sandbox",
"url": "http://sandbox.petstore.swagger.io"
},
{
"description": "Prod",
"url": "http://petstore.swagger.io"
}
]
}
},
{
"description": "Add auth urls",
"target": "components.securitySchemes.OAuth2.flows.authorizationCode",
"update": {
"authorization_url": "https://example.com/oauth/authorize",
"token_url": "https://example.com/oauth/token"
}
}
]
}
This really needs to be supported.
One workaround is to create files in build tooling just to store each single environment variable needed for the spec. Those can then be $ref'd, but:
Another workaround would be to manually run envsubst
, or lacking that, sed -i
all the spec files for all the needed envvars in a preprocess step. This implies some extra tooling around the OpenAPI build, as it would now use the preprocessed files instead of the source files.
Please consider supporting e.g. "some-string-prefix-${ENVVAR_NAME}-and-suffix"
interpolation to make reinventing the wheel unnecessary.
Please consider supporting e.g. "some-string-prefix-${ENVVAR_NAME}-and-suffix" interpolation to make reinventing the wheel unnecessary.
RFC6570 states
The expression syntax specifically excludes use of the dollar ("$") and parentheses ["(" and ")"] characters so that they remain available for use outside the scope of this specification. For example, a macro language might use these characters to apply macro substitution to a string prior to that string being processed as a URI Template.
so I see no reason why tooling could not make use of this ($(ENV_VAR)
) convention, but I'm unsure whether it needs to be called out in the specification itself...
RFC6570 states
The expression syntax specifically excludes use of the dollar ("$") and parentheses ["(" and ")"] characters so that they remain available for use outside the scope of this specification.
Alright, that's a very good reason not to do it. Thanks!
Alright, that's a very good reason not to do it. Thanks!
No, I'm saying you can do it (today) with $(..)
not ${...}
but as you need a tool to do the replacement, it feels more like a tooling issue than something we need to put in the spec. We could add it to our documentation as a 'best practice'?
Thanks for transferring this @handrews. I think overlays is a good way to update server variables, but I am still unclear if we need to adopt the environment variable substitution step into the formal description, or just document a recommended workflow. Comments welcome!
Sorry if this came up before, I searched but could not find anything.
Environment variables have become something of the de facto mechanism to set server-specific values, then access them from software. The hosting providers I have worked with (AWS, Heroku, OpenShift) all offer features to easily set/import/export them and most software I've seen meant to run on these systems uses it for things like environment specific URLs, secrets etc.
But afaik there is no way to reference environment variables in an OpenAPI definition.
Would this be a feature to support? I imagine the definition having a section (probably at the top level) that specified a set of environment variables expected to be set, and possibly the default values to use when they are not set. Those variables could then be used in other parts of the definition.
My practical use cases comes from needing to set different authorization urls for different environments. Currently I am rendering swagger.json from JSP to implement this myself, but it seems to me this is a very generic use case that many people will face.
See also e.g. https://github.com/OAI/OpenAPI-Specification/issues/169 https://github.com/OAI/OpenAPI-Specification/issues/779 https://github.com/swagger-api/swagger-ui/pull/3410