-
Notifications
You must be signed in to change notification settings - Fork 373
Supporting $ref to relative path #227
Comments
JSON Reference resolution is handled by json-refs and there is a known issue for supporting this: whitlockjc/json-refs/issues/11. I will keep this open in here until this issue is resolved in json-refs. |
This should be fixed but there is currently a bug in json-refs/issues/24 that you need to be careful of. No circular remote/relative references? Things will work like you want. |
It's not working for me. Am I doing something wrong? http://pastie.org/private/0ozh5wm8li9qrrifl9cbua (swagger.yaml) |
How are you loading swagger.yaml? |
With Swagger UI. Also, it seems to request the main file 8 times when I reference the video file, but it doesn't request the video file itself. |
swagger-ui does not support relative references. |
I'm going to reopen the issue until I have unit tests showing it works but swagger-ui is not related to swagger-tools. |
Thanks @whitlockjc, I guess it's this one: swagger-api/swagger-ui#1456. |
It would be great to be able to run this example: https://github.com/swagger-api/swagger-spec/tree/master/examples/v2.0/yaml/petstore-separate |
The problem we have right now with supporting this is that swagger-tools does not know where the original document was loaded from so doing relative reference resolution isn't possible without providing that context. swagger-tools uses path-loader and json-refs which both support relative references but they do it based on That being said, to support this I would need to update all APIs in swagger-tools to support passing this option to json-refs/path-loader. It's not impossible but it would change the APIs a bit. I need to think about this a little more. |
I'm having a little tough time following, is this only an issue only with swagger-ui? I'm unable to get it to work using the swagger-node module loading swagger.yaml (completely in node, no browser in the chain at all) Relevant snippet swagger.yaml (snipped)
error.yaml
Then when running swagger-node's validate I get this:
|
Your |
Good catch although it appears to be tangential. I changed errors.yaml as a test to be:
|
What's the error now? I doubt swagger-node supports relative references just yet since it uses swagger-tools which is known not to support relative references except under certain conditions. |
Sorry I should have been more clear. Its the same error as before.
Under what conditions does swagger-tools support relative references? I could maybe force them or look thru swagger-node to figure out how to get them to work. |
The paths must be relative to # ...
$ref: './api/swagger/users.yaml#/definitions/User'
# ... |
Not sure if it's relevant, but what we're doing is using swagger-parser (3.0.0-alpha.5) to dereference our swagger.yaml file (with relative paths), and then we save it as swagger.json and serve that. |
swagger-tools dereferences references too but relative references weren't a thing until recently. When we started work on breaking up swagger-tools, we started swagger-core-api and it does work with relative references. In face, swagger-core-api does better validation than swagger-tools at this point. The reason I bring this up is swagger-tools will be deprecated in the future and will be replaced by swagger-core-api and per-server middlewares/plugins that build on top of swagger-core-api. |
@whitlockjc I use swagger-editor currently, and it seems that I must wait for it to be updated to use swagger-core-api in order to be usable with relative URLs. Am I getting that right? |
Yes. We are in the process of migrating swagger-editor to swagger-core-api. Also, supporting relative references for the swagger-editor will likely involve some other work since it's intended right now to be a single-file UI but this could change that. |
I'm currently in the process of designing a fairly large set of APIs with various widgets/types reused. I'd like the Swagger Spec itself to be decomposed into one spec file per path referenced through $ref in YAML. Then the referenced spec file itself reference JSON schema definitions all through HTTP-based relative $ref's -- since the hostname would be tier/deployment-specific: So (in pseudo-code):
My questions are:
Any thoughts on the current/upcoming capabilities or recommended patterns around this? |
The underlying library swagger-tools uses for JSON Reference resolution (json-refs) supports relative references but to use it requires swagger-tools to know where the loaded Swagger document came from, which it doesn't, and it needs a way to pass this information to json-refs. To support this we need to alter all APIs to take an |
Thank you for the response. I was able to get the Node side to work by making sure the relative refs were off-of Is there any way to get Swagger Editor (or UI) to expand the schemas into a more human-friendly view (like it would if the definitions were local and not ref'ed)? Regarding your comment on |
swagger-ui is its own thing and they do their own stuff. swagger-editor uses swagger-tools but remember that references then become relative to I'll work on getting swagger-tools to have an API for specifying the document root so relative references work universally. Then it's up to swagger-editor and others to use the new support. |
Thanks again for the response. So is your recommendation for now (until all tools in the ecosystem support the doc root) to just go with a single specification document with all references local to the doc? Having one large YAML with thousands of lines of specification sounds rather monolithic to me -- so as a newcomer to swagger/tools, I would appreciate your insight on what the prevalent industry patterns are for composing a large set of APIs (essentially around reuse and physical refactoring of the specification document). |
What server environment are you using? |
Has anything changed recently with Sway in the way it resolves relative references from within JSON schemas:
I get the following error when I start the project:
This used to work OK until a couple months ago. |
Upgrade, I released a fix Friday. |
Thanks. I just upgraded Sway. Still get the same error with |
I meant to upgrade swagger-tools. Sway hasnt seen a release and shouldn't be causing issues. |
Upgraded swagger-tools. At |
Try using Sway at master then. I'm not sure what is up because Sway hasn't had any releases to cause any problems and swagger-tools is not doing anything for relative references still. The approach I documented above is probably better but I'm not sure why something just started failing. Run with |
|
Also, why is SwaggeExpress.create() does not seem to follow the callback pattern for errors. Here's a simplified example:
And here's the output (it never gets to the callback function). It seems to be throwing, instead.
|
Here's another finding that may be helpful. It looks like the relative references ( Previously, I believe the relative references ( If I change my Was this a breaking change that was introduced recently? |
Some more information: I have a fairly succinct This is the working configuration:
For example, in the following snippet of a JSON schema, the
Here's the set of dependencies and their versions (higher versions of mw or tools seem to have breaking changes): "dependencies": { |
swagger-tools and sway are really old so the chances they have bugs does not surprise me. The more interesting dependency version would be Upgrading swagger-tools will give you better output for the failure you're seeing. You can also run |
Are $ref's to other files going to be supported soon?
Inside The error comes from both swagger-tools cli and swagger-node cli validation. |
Will you please read some of the comments before yours? Not only is the answer to your question there but so is the workaround. On another note, Swagger forbids |
Is there a way to set Json-Ref's options.relativeBase from swagger-tools.initializeMiddleware(doc, cb())? I have split by yaml files, but I have to include the full paths for every reference. I would like to be able to set a relative base for the docs instead. |
This is the problem with the current swagger-tools API. To allow for you to pass options downstream, every API has to change and that is a breaking change. So I'd have to release |
Thanks for the quick update, good to know! |
Hello! Is there any update on this? I'd love to be able to split up my swagger.yaml file into multiple directories (e.g. paths, definitions, etc.) |
This problem still exists in current version. I saw json-ref has an additional option 'relativeBase' but spec.js doesn't pass in this option. As for the amount of invocations in spec.js or other files demanded to modify, I suggest to add a new method in json-ref specified for initial default options globally, including 'relativeBase'. Adding a wrapper above json-ref should also do. This way might ease the code work. |
Of course this problem still exists, the issue is still open. The suggested workaround is all you will get for now because rewriting swagger-tools to support this isn't going to happen. I mentioned this above. Just use |
Here is another workaround for those who want to use const JsonRefs = require('json-refs');
const YAML = require('js-yaml');
const SwaggerExpress = require('swagger-express-mw');
const app = require('express')();
// export setup Promis for testing
module.exports = new Promise(function (resolve, reject) {
JsonRefs.resolveRefsAt('./api/swagger/swagger.yaml', {
// Resolve all remote references
filter: ['relative', 'remote'],
loaderOptions: {
processContent: (res, cb) => cb(undefined, YAML.safeLoad(res.text))
}
})
.then(results => {
const config = {
appRoot: __dirname, // required config
swagger: results.resolved
};
SwaggerExpress.create(config, function (err, swaggerExpress) {
if (err) { throw err; }
// install middleware
swaggerExpress.register(app);
const port = process.env.PORT || 10010;
app.listen(port, function() {
if (swaggerExpress.runner.swagger.paths['/hello']) {
console.log('try this:\ncurl http://127.0.0.1:' + port + '/hello?name=Scott');
}
resolve(app);
});
});
})
.catch(function (err) {
console.error(err.stack);
process.exit(1);
});
;
}); |
@canercandan thank you very much for the workaround! @whitlockjc So I guess there will be no fix at all? Did you already close the lid on this one? |
I have a Swagger 2.0 spec
api/spec.json
and inside there I want to have a reference to a local fileapi/defs.json
for my definitions. So inspec.json
I'm doing something like:where
defs.json
looks likeBut I just get
#/paths/~1message/post/parameters/0/schema/$ref: Not a valid JSON Reference
on initI've tried several variations like:
This starts but fails with
#: Reference could not be resolved: ./defs.json
when a request is sent.I have read that $ref supports internal and remote (with an absolute URL), but not been able to find any documentation on relative paths.
Here is a mention that this might be possible already: OAI/OpenAPI-Specification#275 (comment)
Here is a mention that it has just been implemented in swagger-js: swagger-api/swagger-js#417
Are relative paths supported at all?
The text was updated successfully, but these errors were encountered: