Currently the DOM is designed so that strong types such as OpenAPISchema can be marked as a reference. This enables the model to know that these types are explicitly being re-used from the components collection.
Currently references are loaded immediately upon parsing a document so that references are always represented by the correct types and those instances contain all the referenced data. This is convenient when working with the object model as referenced objects and non-referenced can be interacted with transparently.
When it comes to loading references from external documents, this approach presents some challenges:
- Loading from an external document should be async. Transparently loading external references would push async all the way through the model to the main load even if there were no external references in a particular document.
- What if someone wanted to process a set of documents that contained external references but didn't need to load them to perform the updates? Should we not support loading documents without dereferencing external references? If so how should those references be represented in the model?
- How do you construct a DOM with an external reference? Do you need an instance of the external DOM to do it?
It feels like we cannot get away from having a model type that can have a OpenApiReference instance but be in an "unresolved" state.
var unresolvedSchema = new OpenApiSchema {
Reference = new OpenApiReference("common.json#/components/schema/cat")
};
Does this mean that we need to put a guard clause in every get accessor that prevents reading the regular properties? How do we construct a reusable object to be added to Components? Do we create it without the reference and then when adding it to the components collection a reference gets added automatically?
Or do we change the approach to the way we deal with references and instead of using the same object in the components collection and the reference to it, we create a new SchemaReference type that does aggregation and delegation.
e.g.
content.Schema = new SchemaReference("cat",doc.Components.Schemas["cat"]);
This would require the SchemaReference to re-surface the entire Schema API. This would provide a nice place to put the guard against derefencing an unresolved reference, but it would also mean either creating an ISchema interface, or deriving from Schema and making all the properties virtual. Both of which are high maintenance approaches.