Skip to content

OpenAPI document generation tool feedback #57044

Open
@martincostello

Description

@martincostello

Playing around with the OpenAPI document CLI generation from Lint generated OpenAPI documents with Spectral I found a few issues and rough edges. Rather than create lots of small issues I figured I'd list them all here, and they can be spun off into dedicated issues based on feedback/triage.

OpenApiDocumentsDirectory is not resolved to a full path

If OpenApiDocumentsDirectory is specified as a relative path (e.g. dotnet build ./src/API /p:OpenApiGenerateDocuments=true /p:OpenApiDocumentsDirectory="./artifacts/openapi"), the path is not resolved to a full path, and then ends up as a path relative to the tool invocation, rather than relative to the current working directory of the command, so the document ends up in the bin\Debug etc. folder rather than the folder the user expected.

Seems like resolving the full path here in the MSBuild targets before invoking the tool would resolve that:

<_DotNetGetDocumentCommand>$(_DotNetGetDocumentCommand) --output "$(OpenApiDocumentsDirectory.TrimEnd('\'))" --project "$(MSBuildProjectName)"</_DotNetGetDocumentCommand>

"Invalid OpenAPI spec version" warning

If the target is run without explicitly an OpenAPI document version to generate, a warning is output:

Generating document named 'api'.
Using discovered `GenerateAsync` overload with version parameter.
Invalid OpenAPI spec version '' provided. Falling back to default: v3.0.
Writing document named 'api' to './artifacts/openapi\API_api.json'.

This comes from here:

_reporter.WriteWarning(Resources.FormatInvalidOpenApiVersion(_context.OpenApiVersion));

If this Enum.TryParse() call fails to parse anything:

if (Enum.TryParse<OpenApiSpecVersion>(_context.OpenApiVersion, out var version))

It looks like there's a few ways to resolve this:

  1. Assign a default value for GetDocumentCommandContext.OpenApiVersion if no value is provided:
    OpenApiVersion = _openApiVersion.Value(),
  2. Don't emit the warning if GetDocumentCommandContext.OpenApiVersion is null/empty (rather than a value that doesn't parse)
  3. Explicitly pass a value for --openapi-version through from the MSBuild target:
    _openApiVersion = command.Option("--openapi-version <Version>", Resources.OpenApiVersionDescription);

No MSBuild property for specifying the OpenAPI version

It's possible to add extra options to work around the above using OpenApiGenerateDocumentsOptions (e.g. /p:OpenApiGenerateDocumentsOptions="--openapi-version OpenApi3_0"), but there isn't a specific MSBuild property for this.

To make usage easier a property could be defined that the user can specify to set the version without needing to explicitly set command line parameters that the MSBuild target could transform and pass through to the tool (e.g. /p:OpenApiGenerateDocumentVersion=3.0 into --openapi-version OpenApi3_0).

MSBuild properties not affecting "up-to-date-ness"

I noticed when the path wasn't being fully evaluated, if I re-ran the build with a different input property the document wouldn't be regenerated.

For example:

❯ dotnet build ./src/API /p:OpenApiGenerateDocuments=true /p:OpenApiDocumentsDirectory="${OutputDirectory}"
Restore complete (1.9s)
You are using a preview version of .NET. See: https://aka.ms/dotnet-support-policy
  API succeeded (16.5s) → artifacts\bin\API\debug\API.dll

Build succeeded in 21.8s

api on  dotnet-nightly [$] via .NET v9.0.100-preview.7.24375.12 took 22s
❯ dotnet build ./src/API /p:OpenApiGenerateDocuments=true /p:OpenApiDocumentsDirectory="${OutputDirectory}2"
Restore complete (0.5s)
You are using a preview version of .NET. See: https://aka.ms/dotnet-support-policy
  API succeeded (1.0s) → artifacts\bin\API\debug\API.dll

Build succeeded in 4.4s

api on  dotnet-nightly [$] via .NET v9.0.100-preview.7.24375.12 took 4s

The first command creates the API document at ${OutputDirectory} in ~20 seconds.

The second command with the output path set to ${OutputDirectory}2 doesn't emit anything and takes ~4 seconds.

It seems like the properties being passed through aren't affecting MSBuild up-to-date checks and causing the document not to be re-generated.

Output directory value isn't checked for

I made a mistake during playing with the tool and accidentally un-defined the variable for the output path. This then causes an ArgumentException to be thrown inside the tool (--output ""). Should something check a value is specified first?

dotnet build ./src/API /p:OpenApiGenerateDocuments=true /p:OpenApiDocumentsDirectory="${OutputDirectory}" /p:OpenApiGenerateDocumentsOptions="--openapi-version OpenApi3_0"
Restore complete (0.6s)
You are using a preview version of .NET. See: https://aka.ms/dotnet-support-policy
  API failed with 6 error(s) (12.4s) → artifacts\bin\API\debug\API.dll
    C:\Users\Martin.Costello\.nuget\packages\microsoft.extensions.apidescription.server\9.0.0-preview.7.24375.8\build\Microsoft.Extensions.ApiDescription.Server.targets(66,5): error : System.ArgumentException: The value cannot be an empty string. (Parameter 'path')
    C:\Users\Martin.Costello\.nuget\packages\microsoft.extensions.apidescription.server\9.0.0-preview.7.24375.8\build\Microsoft.Extensions.ApiDescription.Server.targets(66,5): error :    at System.ArgumentException.ThrowNullOrEmptyException(String argument, String paramName)
    C:\Users\Martin.Costello\.nuget\packages\microsoft.extensions.apidescription.server\9.0.0-preview.7.24375.8\build\Microsoft.Extensions.ApiDescription.Server.targets(66,5): error :    at System.IO.Directory.CreateDirectory(String path)
    C:\Users\Martin.Costello\.nuget\packages\microsoft.extensions.apidescription.server\9.0.0-preview.7.24375.8\build\Microsoft.Extensions.ApiDescription.Server.targets(66,5): error :    at Microsoft.Extensions.ApiDescription.Tool.Commands.GetDocumentCommandWorker.GetDocuments(IServiceProvider services)
    C:\Users\Martin.Costello\.nuget\packages\microsoft.extensions.apidescription.server\9.0.0-preview.7.24375.8\build\Microsoft.Extensions.ApiDescription.Server.targets(66,5): error :    at Microsoft.Extensions.ApiDescription.Tool.Commands.GetDocumentCommandWorker.Process()
    C:\Users\Martin.Costello\.nuget\packages\microsoft.extensions.apidescription.server\9.0.0-preview.7.24375.8\build\Microsoft.Extensions.ApiDescription.Server.targets(66,5): error MSB3073: The command "dotnet "C:\Users\Martin.Costello\.nuget\packages\microsoft.extensions.apidescription.server\9.0.0-preview.7.24375.8\build\../tools/dotnet-getdocument.dll" --assembly "C:\Coding\martincostello\api\artifacts\bin\API\debug\API.dll" --file-list "C:\Coding\martincostello\api\artifacts\obj\API\API.OpenApiFiles.cache" --framework ".NETCoreApp,Version=v9.0" --output "" --project "API" --assets-file "C:\Coding\martincostello\api\artifacts\obj\API\project.assets.json" --platform "AnyCPU" --openapi-version OpenApi3_0" exited with code 11.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-commandlinetoolsIncludes: Command line tools, dotnet-dev-certs, dotnet-user-jwts, and OpenAPIfeature-openapi

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions