Skip to content

References and Reference Resolution

Alex Wichmann edited this page May 25, 2025 · 6 revisions

References

References are handled through specific reference types. When adding references to a document it must be done using the proper reference uri

Adding a server component reference could be done like so.

var document = new AsyncApiDocument
{
    Info = new AsyncApiInfo
    {
        Title = "MyDocument",
    },
    Servers = new Dictionary<string, AsyncApiServer>
    {
        { "server1", new AsyncApiServerReference("#/components/servers/myServer") },
    },
    Components = new AsyncApiComponents
    {
        Servers = new Dictionary<string, AsyncApiServer>
        {
            {
                "myServer", new AsyncApiServer
                { 
                    Host = "example.com",
                    Protocol = "https",
                }
            },
        },
    },
};

var yaml = document.SerializeAsYaml(AsyncApiVersion.AsyncApi2_0);

The above yields the following yaml

asyncapi: 2.6.0
info:
  title: MyDocument
servers:
  server1:
    $ref: '#/components/servers/myServer'
components:
  servers:
    myServer:
      url: https://example.com
      protocol: 

References created programmatically are NOT resolved until (de)serialization, meaning that de-referencing will not work. De-referencering only works on documents coming from a reader.

We can see the dereferencing in action using the following test

 // The document model
 var document = new AsyncApiDocument
 {
     Info = new AsyncApiInfo
     {
         Title = "MyDocument",
     },
     Servers = new Dictionary<string, AsyncApiServer>
     {
         { "server1", new AsyncApiServerReference("#/components/servers/myServer") },
     },
     Components = new AsyncApiComponents
     {
         Servers = new Dictionary<string, AsyncApiServer>
         {
             {
                 "myServer", new AsyncApiServer
                 {
                     Host = "example.com",
                     Protocol = "https",
                 }
             },
         },
     },
 };

 // Serialize to yaml v3
 var yaml = document.SerializeAsYaml(AsyncApiVersion.AsyncApi3_0);

 // deserialize (like we would with ingress specifications)
 var doc = new AsyncApiStringReader().Read(yaml, out var diagnostics);
 
 var resolvedReference = doc.Servers.First().Value;
 
 // Dereferencing due to reference resolution happening during deserialization.
 Assert.AreEqual("example.com", resolvedReference.Host);
 Assert.AreEqual(true, resolvedReference is AsyncApiServerReference);
 Assert.AreEqual(false, ((AsyncApiServerReference)resolvedReference).UnresolvedReference);
 Assert.AreEqual("#/components/servers/myServer", ((AsyncApiServerReference)resolvedReference).Reference.Reference);

As you'll notice form the first Assertion, the consumer does not have to care (much), whether its a reference or not as we dereference the resolved reference directly (even for multiple levels of references). However, in some cases (where a reference is not required) it might be nice to check whether it is a reference, and whether it has been resolved or not. Particularly with external references, if they arent resolved, due to error or otherwise you might hit some null refs.

Reference Resolution

Reference resolution only happens when deserializing from a specification.

Internal references are resolved by default. This includes component and non-component references e.g #/components/messages/MyMessage and #/servers/0.

External references can be resolved by setting ReferenceResolution to ResolveAllReferences.
The default implementation will resolve anything prefixed with file://, http:// & https://, however a custom implementation can be made, by inhereting from the IStreamLoader interface and setting the ExternalReferenceLoader in the AsyncApiReaderSettings.
External references are always force converted to Json during resolution. This means that both yaml and json is supported - but not other serialization languages.

var settings = new AsyncApiReaderSettings { ReferenceResolution = ReferenceResolution.ResolveAllReferences };
var document = new AsyncApiStringReader(settings).Read(json, out var diagnostics);

Reference resolution can be disabled by setting ReferenceResolution to DoNotResolveReferences.

Clone this wiki locally