[BUG] Disable derefencing of $ref by default.
Describe the bug.
asyncapi/parser version: 3.4.0
Currently, By default $ref is dereferenced during parsing or validation. We need to disable this default behaviour. We tried couple of ways to disable it, however, we could not achieve it.
const parser = new Parser(); const data = await parser.validate(spec, { resolve: { http: false, https: false, file: false } )};
parser.validate(spec, { resolve: { external: false } }
resolve: { external: false, file: {
resolve: () => {
throw new Error('File resolution blocked');
}
},
http: {
resolve: () => {
throw new Error('HTTP resolution blocked');
}
}
}
Expected behavior
$ref pointing to external references (http, https, file etc) should be disabled by default.
Screenshots
During validate method calls, we could observe that http calls were made when trying to de-refence the $refs in the schemas.
How to Reproduce
Take any sample async api specification that has an external reference pointing to http endPoint. const data = await new Parser().validate(spec); During this validate call, by default dereferencing takes place, including http calls.
🖥️ Device Information [optional]
- Operating System (OS): Mac
- Browser: Google Chrome
- Browser Version: 138.
👀 Have you checked for similar open issues?
- [x] I checked and didn't find similar issue
🏢 Have you read the Contributing Guidelines?
- [x] I have read the Contributing Guidelines
Are you willing to work on this issue ?
None
Welcome to AsyncAPI. Thanks a lot for reporting your first issue. Please check out our contributors guide and the instructions about a basic recommended setup useful for opening a pull request.
Keep in mind there are also other channels you can use to interact with AsyncAPI community. For more details check out this issue.
Hi team,
Any updates on this ticket. We need to disable default dereferencing of external references from the schema.
Hi team,
Any updates on how to disable default referencing of external refs.
This issue has been automatically marked as stale because it has not had recent activity :sleeping:
It will be closed in 120 days if no further activity occurs. To unstale this issue, add a comment with a detailed explanation.
There can be many reasons why some specific issue has no activity. The most probable cause is lack of time, not lack of interest. AsyncAPI Initiative is a Linux Foundation project not owned by a single for-profit company. It is a community-driven initiative ruled under open governance model.
Let us figure out together how to push this issue forward. Connect with us through one of many communication channels we established here.
Thank you for your patience :heart:
@magicmatatjahu is this relevant issue?? if yes, I'll work on it
Hi! I've implemented a solution for this issue.
Summary:
I've added a new resolveExternal option to ResolverOptions that allows users to disable external reference resolution (http, https, and file URIs) while keeping internal JSON pointer references working.
Key Features:
- Added
resolveExternal?: booleanoption toResolverOptionsinterface - When set to
false, external references (http/https/file) are not resolved - Internal JSON pointer references (like
#/components/messages/message) continue to work regardless - Defaults to
truefor backward compatibility (existing behavior unchanged)
Usage:
const parser = new Parser({
__unstable: {
resolver: {
resolveExternal: false
}
}
});
Or can be passed in validate()/parse() methods as well.
I've added comprehensive tests covering all scenarios, and all existing tests still pass. The PR is ready for review! 🚀
@AnshumohanAcharya thx for the update. I have also seen this. However I have another use case where I need to extract the payload in the form of a json schema definition. The extracted json schema definition in the asyncapi definition is using references to other types under the components/schemas. I'd like to avoid that the referenced types are not derefenced in the final json representation of the json schema. Instead I want to keep these as-is and capture the references under "definitions" field in the json schema.
So what do you think?
@akrepon Thanks for sharing that use case. This is different from the external reference resolution feature and involves JSON Schema bundling.
Current behavior:
When calling schema.json(), the parser returns a fully resolved schema with $ref references dereferenced inline.
What you're asking for: A bundling/bundling-style output where:
-
$refreferences tocomponents/schemas/*are preserved (not dereferenced) - Referenced schemas are collected and placed in a
definitionsfield - The main schema uses relative references like
$ref: "#/definitions/SomeType" - Result is a self-contained JSON Schema document
Example transformation:
# AsyncAPI schema with reference
payload:
type: object
properties:
user:
$ref: '#/components/schemas/User'
components:
schemas:
User:
type: object
properties:
name: { type: string }
Desired JSON Schema output:
{
"type": "object",
"properties": {
"user": {
"$ref": "#/definitions/User"
}
},
"definitions": {
"User": {
"type": "object",
"properties": {
"name": { "type": "string" }
}
}
}
}
Considerations:
- This would be a new feature, separate from the external reference resolution fix.
- Potential implementation approaches:
- Add a
toJSONSchemaBundled()method to the Schema model - Or add a
bundleDefinitions: booleanoption to control output format
- Add a
- Edge cases to handle:
- Circular references
- Nested references in definitions
- References in
allOf,anyOf,oneOf - Whether to include only referenced schemas or all component schemas
This seems like a reasonable enhancement. Should I create a separate issue for this feature so we can track it independently?
Thx @AnshumohanAcharya for the proposals. I think this is a good approach. I am mainly interested in this feature for building pipelines for extracting json schema definitions from the asyncapi spec and use these standalone somewhere else, such as generating models or importing schemas in schema registries. This would be definitely worth it.
Perfect! Since the current PR will take some time to merge, I can start working on the bundling feature right away on a separate branch.
The two features are independent, so I'll:
- Work on the bundling feature in parallel
- Create a separate PR for it
- Both can be reviewed independently
I'll create an issue first to discuss the implementation approach, then start coding.