OpenAPI.NET icon indicating copy to clipboard operation
OpenAPI.NET copied to clipboard

OpenApiStreamReader.ReadAsync() throws an InvalidOperation exception when using ResolveAllReferences

Open NishantaA opened this issue 4 years ago • 4 comments

Need help resolving remote references.

OpenApiStreamReader.ReadAsync() throws an InvalidOperation exception with the message "This operation is not supported for a relative URI." when using 'ReferenceResolutionSetting.ResolveAllReferences' flag.

what should the BaseUrl be set to ? currently I am not setting it not sure what I need to set it to. I am using the yaml files defined in https://github.com/jdegre/5GC_APIs.

NishantaA avatar Jun 21 '21 23:06 NishantaA

As mentioned in the release notes currently remote references only works for absolute paths.

darrelmiller avatar Jun 25 '21 13:06 darrelmiller

Hi @darrelmiller, I have encountered the same issue. However, I wrote my own JSON preprocessor which correctly turned all relative paths into absolute ones. See here a public gist of the OpenAPI schema for ApplicationInsights

The error remains the same even though there no more relative paths in the initial document itself. Here is a dotnet fiddle snippet to reproduce the issue:

using System;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.OpenApi.Readers;

public class Program
{
	static HttpClient client = new HttpClient();
	
	public static async Task Main()
	{
		var schemaGist = "https://gist.githubusercontent.com/Zaid-Ajaj/f27da5d9ddc8dfeceb26fe2a1f5b75a4/raw/7ca33215e113a8c91ad445a03d7352cd937a2c18/appinsight.json";
		var schema = await client.GetStreamAsync(schemaGist);
		var settings = new OpenApiReaderSettings 
		{ 
			ReferenceResolution = ReferenceResolutionSetting.ResolveAllReferences
		};
		
		var result = await new OpenApiStreamReader(settings).ReadAsync(schema);
	}
}

I guess the error still happens because one of the transitive documents itself has a relative path?

Zaid-Ajaj avatar Jun 27 '21 20:06 Zaid-Ajaj

I'm working on fixing this at the moment. Thanks for the repro instructions.

darrelmiller avatar Jun 27 '21 21:06 darrelmiller

Another half solution I found is changing the custom resource loader when the initial schema url is known and is used as base path. (the following is in F# but you get the idea)

type ExternalResouceLoader(schema: string) =
    interface Interface.IStreamLoader with
        member self.Load(uri: Uri) =
            let absoluteUri =
                if not uri.IsAbsoluteUri then
                    Uri(Uri(schema), uri.OriginalString)
                else
                    uri

            httpClient.GetStreamAsync(absoluteUri)
            |> Async.AwaitTask
            |> Async.RunSynchronously

        member self.LoadAsync(uri: Uri) =
            let absoluteUri =
                if not uri.IsAbsoluteUri then
                    Uri(Uri(schema), uri.OriginalString)
                else
                    uri

            httpClient.GetStreamAsync(absoluteUri)

However, the resolved parts are not really useful: types are not added to the global components and external parameters are empty (except for the Reference property)

Zaid-Ajaj avatar Jun 27 '21 21:06 Zaid-Ajaj