Skip to content

Proposal: Change format property in Load and Parse to strongly typed value #1952

Closed as not planned
@darrelmiller

Description

@darrelmiller

Using the following classes we can create a strongly typed experience for the format property in Parse and Load methods on OpenApiDocument.

// In Microsoft.OpenApi project
public partial class OpenApiFormat {
    private string _format;

    public static OpenApiFormat Json { get; } = new OpenApiFormat("json");

    public OpenApiFormat(string format)
    {
        _format = format.ToLower();
    }

    // Implicit conversion from OpenApiFormat to string
    public static implicit operator string(OpenApiFormat format) => format._format;

    // Implicit conversion from string to OpenApiFormat
    public static implicit operator OpenApiFormat(string format) => new OpenApiFormat(format);

}

// In Microsoft.OpenApi.Yaml project
public partial class OpenApiFormat {
    public static OpenApiFormat Yaml { get; } = new OpenApiFormat("yaml");
}

This will enable calling code like

var readResult = await OpenApiDocument.LoadAsync(streamOpenApiDoc,OpenApiFormat.Json);

var readResult = OpenApiDocument.Load(new StringReader(stringOpenApiDoc), OpenApiFormat.Yaml);

var readResult = OpenApiDocument.Parse(stringOpenApiDoc, OpenApiFormat.Yaml);

This will also give us a good place to put code like this that is just used for determining if content is yaml or json

private static string GetContentType(string url)
{
if (!string.IsNullOrEmpty(url))
{
#pragma warning disable VSTHRD002 // Avoid problematic synchronous waits
var response = _httpClient.GetAsync(url).GetAwaiter().GetResult();
#pragma warning restore VSTHRD002 // Avoid problematic synchronous waits
var mediaType = response.Content.Headers.ContentType.MediaType;
return mediaType.Split(";".ToCharArray(), StringSplitOptions.RemoveEmptyEntries).First();
}
return null;
}
/// <summary>
/// Infers the OpenAPI format from the input URL.
/// </summary>
/// <param name="url">The input URL.</param>
/// <returns>The OpenAPI format.</returns>
public static string GetFormat(string url)
{
if (!string.IsNullOrEmpty(url))
{
if (url.StartsWith("http", StringComparison.OrdinalIgnoreCase) || url.StartsWith("https", StringComparison.OrdinalIgnoreCase))
{
// URL examples ---> https://example.com/path/to/file.json, https://example.com/path/to/file.yaml
var path = new Uri(url);
var urlSuffix = path.Segments[path.Segments.Length - 1].Split('.').LastOrDefault();
return !string.IsNullOrEmpty(urlSuffix) ? urlSuffix : GetContentType(url).Split('/').LastOrDefault();
}
else
{
return Path.GetExtension(url).Split('.').LastOrDefault();
}
}
return null;
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    priority:p2Medium. Generally has a work-around and a smaller sub-set of customers is affected. SLA <=30 daystype:enhancementEnhancement request targeting an existing experience

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions