RicoSuter / NSwag

The Swagger/OpenAPI toolchain for .NET, ASP.NET Core and TypeScript.
http://NSwag.org
MIT License
6.69k stars 1.23k forks source link

When filtering webapi paths using operation processors their parameters and responses are still included in swagger #1687

Open hoidenG opened 5 years ago

hoidenG commented 5 years ago

I have a requirement to be able to white list which endpoints to include in our swagger file. For this requirement I use an operation processor. I have managed to control the filtration of paths, however, the parameters and responses from the filtered endpoints still appears in the swagger file.

I have looked through the wiki and the code for a setting but I cannot seem to find it. Am I missing something? or is this by design? or is this an issue?

Thanks

RicoSuter commented 5 years ago

Implement a custom operation processor and return false for the ones you want to exclude... did you do that?

hoidenG commented 5 years ago

Yes, I implemented a custom operation processor - the result was that the path was excluded from the swagger document but its parameters and response objects still appeared in the definitions section in the swagger document

RicoSuter commented 5 years ago

Try to insert the operation processor at the beginning of the list... the order of the document processors is how they are executed and yours must be the first one (before parameter and the response processor which are already in the list)

hoidenG commented 5 years ago

Thanks, I will try that on Monday and get back to you

hoidenG commented 5 years ago

That works when using C#, however, we use the command line tool to generate swagger as a step in our continuous deployment and I am only able to append to list using /OperationProcessors, not prepend.

If there is no way to do this when using the command line I can properly find a work around using C#.

Again, thanks for your help

RicoSuter commented 5 years ago

however, we use the command line tool to generate swagger as a step in our continuous deployment and I am only able to append to list using /OperationProcessors, not prepend.

This is a big problem and will be solved soon. With this PR you can configure everything in your app and then run the CLI with it: https://github.com/RSuter/NSwag/pull/1655

image

document contains all settings like OperationProcessors etc.

chy600 commented 4 years ago

That works when using C#, however, we use the command line tool to generate swagger as a step in our continuous deployment and I am only able to append to list using /OperationProcessors, not prepend.

I'm facing this exact issue in a ASP.NET Web API project. Tried switching to using nswag.json in my build step: <Exec Command="$(NSwagExe_x86) run nswag.json /variables:TargetDirectory=$(TargetDir)" /> Yet it is still generating all the models in the output swagger file.

What am I missing here to be able to prepend the custom OperationProcessor in the command line situation in ASP.NET Web API? Or is it only available to ASP.NET Core project like in the above screenshot?

For reference, here's the nswag.json opened in NSwagStudio showing the custom processors: image

Thank you.

RicoSuter commented 4 years ago

What am I missing here to be able to prepend the custom OperationProcessor in the command line situation in ASP.NET Web API? Or is it only available to ASP.NET Core project like in the above screenshot?

I think the command line always appends operation/document processors - so this is currently not possbile via the CLI (web api).

With ASP.NET Core you register the processors in the AddOpenApiDocument(...) call and there you are much more flexible as you don't have to load them via CLI but the CLI just runs the project code...

The Web API generator is deprecated and I will not improve it anymore.

chy600 commented 4 years ago

Ahh thanks for clearing that out!

I researched a bit on how the CLI is handling the operation processors. Looks like it's these lines that are adding them to the end of operation list: https://github.com/RicoSuter/NSwag/blob/085e8aeb95e4f1723f956fa6137bbc07bd5527a6/src/NSwag.Commands/Commands/Generation/OpenApiGeneratorCommandBase.cs#L359-L366

What if we add an optional boolean argument that defaults to false, and if true then prepend the passed in operation processors?

It'll be something like:

[Argument(Name = "PrependOperationProcessors", IsRequired = false, Description = "Prepend operation processors to avoid generating unused schemas (default: false).")]
public bool PrependOperationProcessors { get; set; } = false;

And some modification to the current logic:

            if (OperationProcessorTypes != null)
            {
        var prependIndex = 0;
                foreach (var p in OperationProcessorTypes)
                {
                    var processor = (IOperationProcessor)assemblyLoader.CreateInstance(p);
                    if (PrependOperationProcessors)
            {
            Settings.OperationProcessors.Insert(prependIndex++, processor);
            }
            else
            {
                        Settings.OperationProcessors.Add(processor);
            }
            }

If you think this approach is acceptable, I can create a PR for it.

Thank you!

RicoSuter commented 4 years ago

Maybe it is easier to not add a new setting but a convention: For example if the element in OperationProcessorTypes starts with ":" it is prepended (insert at 0) otherwise appended. This way we dont need new settings, you can decide per type and it is not a breaking change because ":" cannot be in a type name. What do you think?

chy600 commented 4 years ago

Hey I didn't know about the ':' convention. Would it be something like this?


if (OperationProcessorTypes != null)
{
    var prependIndex = 0;
    foreach (var p in OperationProcessorTypes)
    {
        var processor = (IOperationProcessor)assemblyLoader.CreateInstance(p[0] == ':' ? p.SubString(1) : p);
        if (p[0] == ':')
        {
            Settings.OperationProcessors.Insert(prependIndex++, processor);
        }
        else
        {
            Settings.OperationProcessors.Add(processor);
        }
    }
}
RicoSuter commented 4 years ago

I came up with this convention - it’s just an idea to easily introduce a flexible solution. Do you know a better convention?

chy600 commented 4 years ago

Nope, that sounds good to me :) I'm pretty late to the party haha, thought there was a ':' convention in the NSwag community.. I will create a PR in the coming days. Thank you for the prompt reply!

chy600 commented 4 years ago

PR created. This is my first PR to NSwag so please let me know if I missed anything.