Skip to content

Document Processors and Operation Processors

Rico Suter edited this page Jun 6, 2019 · 34 revisions

Document and operation processors are used to transform a Swagger document or Swagger operation after they have been generated or exclude an operation with a custom rule.

See also Schema Processors (transform DTO schemas).

Custom processors can be added with the settings object, e.g.

settings.OperationProcessors.Add(new MyOperationProcessor());
settings.DocumentProcessors.Add(new MyDocumentProcessor());

Document Processors

The document processors are executed after the Swagger document has been completely generated. Operation processors are specified on the Swagger generator settings or as command parameters.

public class MyDocumentProcessor : IDocumentProcessor
{
    public void Process(DocumentProcessorContext context)
    {
        // TODO: Process context.Document
    }
}

Sample: Add additional types from an assembly

public class MyDocumentProcessor : IDocumentProcessor
{
    public void Process(DocumentProcessorContext context)
    {
        var assembly = GetType().GetTypeInfo().Assembly;
        var types = assembly.ExportedTypes
            .Where(t => t.FullName.StartsWith("MyNamespace.") && t.GetTypeInfo().IsClass);

        foreach (var type in types)
        {
            if (!context.SchemaResolver.HasSchema(type, false))
            {
                await context.SchemaGenerator.GenerateAsync(type, null, context.SchemaResolver);
            }
        }
    }
}

Operation Processors

Execution order:

  1. All operations from settings.OperationProcessors (contains the default processors which generate parameters, responses, etc.)
  2. SwaggerOperationProcessorAttribute on controller class
  3. SwaggerOperationProcessorAttribute on operation method

Important: If you want to filter out some operations, insert the operation processor at index 0 (i.e. settings.OperationProcessors.Insert(0, new MyOperationProcessor())) so that no unnecessary DTO schemas are generated.

To implement a custom operation processor, just create a class which implements the interface IOperationProcessor:

public class MyOperationProcessor : IOperationProcessor
{
    public bool Process(OperationProcessorContext context)
    {
        // TODO: Process context.Document
        return true; // return false to exclude the operation from the document
    }
}

You can register the custom IOperationProcessor to transform each operation:

services.AddOpenApiDocument(document => 
    document.OperationProcessors.Add(new MyOperationProcessor()))

You can also specify a operation processor for a single operation:

[SwaggerOperationProcessor(typeof(MyOperationProcessor))]
public void MyOperation()
{

}

For better usability of this construct, you can now implement your own attribute:

public class MyOperationProcessorAttribute : SwaggerOperationProcessorAttribute
{
    public MyOperationProcessorAttribute(string param1)
        : base(typeof(MyOperationProcessor), param1)
    {

    }
}

// usage: 
[MyOperationProcessor("Foo")]
public IActionResult MyOperation()
{
    // ...
}

Avoid unused schemas

Operation processors which are used to exclude operation must be inserted at the beginning of the processor pipeline as it they will filter out the operation before the DTO schemas are generated and added to the document.

settings.OperationProcessors.Insert(0, new IncludeControllersInSwagger())