Skip to content

OpenAPI/Swagger Integration

Sannr provides seamless integration with OpenAPI/Swagger documentation generators, automatically converting your validation attributes into OpenAPI schema constraints. This ensures your API documentation stays synchronized with your validation rules.

Overview

Traditional approaches require manual maintenance of both validation attributes and OpenAPI schema definitions. Sannr eliminates this duplication by automatically generating schema constraints from your validation attributes.

Setup

1. Install Dependencies

Ensure you have Swashbuckle.AspNetCore installed:

bash
dotnet add package Swashbuckle.AspNetCore

2. Configure SwaggerGen

In your Program.cs, add the Sannr OpenAPI integration:

csharp
using Sannr.OpenApi;

var builder = WebApplication.CreateBuilder(args);

// Add Swagger with Sannr integration
builder.Services.AddSwaggerGen(options =>
{
    options.AddSannrValidationSchemas();
});

var app = builder.Build();

app.UseSwagger();
app.UseSwaggerUI();

How It Works

Sannr uses a schema filter that post-processes OpenAPI schemas generated by Swashbuckle. The filter examines your model properties, detects Sannr validation attributes, and applies the corresponding OpenAPI constraints.

Schema Filter Process

  1. Base Schema Generation: Swashbuckle creates the initial OpenAPI schema
  2. Attribute Detection: Sannr filter scans properties for validation attributes
  3. Constraint Application: Validation rules are converted to OpenAPI constraints
  4. Schema Enhancement: The schema is updated with validation constraints

Supported Attributes

Sannr AttributeOpenAPI ConstraintExample
[EmailAddress]format: "email""email": {"type": "string", "format": "email"}
[Url]format: "uri""website": {"type": "string", "format": "uri"}
[Range(min, max)]minimum, maximum"age": {"type": "integer", "minimum": 18, "maximum": 120}
[StringLength(max, min)]minLength, maxLength"name": {"type": "string", "minLength": 2, "maxLength": 100}
[FileExtensions]format: "file""avatar": {"type": "string", "format": "file"}

Complete Example

Model Definition

csharp
using Sannr;

public class UserRegistrationRequest
{
    [Required, EmailAddress]
    public string Email { get; set; } = string.Empty;

    [Required, StringLength(100, MinimumLength = 2)]
    public string FirstName { get; set; } = string.Empty;

    [Required, StringLength(100, MinimumLength = 2)]
    public string LastName { get; set; } = string.Empty;

    [Range(13, 120)]
    public int Age { get; set; }

    [Url]
    public string? Website { get; set; }

    [Phone]
    public string? PhoneNumber { get; set; }

    [CreditCard]
    public string? CreditCardNumber { get; set; }

    [FileExtensions]
    public string? ProfileImagePath { get; set; }
}

Generated OpenAPI Schema

json
{
  "UserRegistrationRequest": {
    "type": "object",
    "properties": {
      "email": {
        "type": "string",
        "format": "email"
      },
      "firstName": {
        "type": "string",
        "minLength": 2,
        "maxLength": 100
      },
      "lastName": {
        "type": "string",
        "minLength": 2,
        "maxLength": 100
      },
      "age": {
        "type": "integer",
        "minimum": 13,
        "maximum": 120
      },
      "website": {
        "type": "string",
        "format": "uri"
      },
      "phoneNumber": {
        "type": "string"
      },
      "creditCardNumber": {
        "type": "string"
      },
      "profileImagePath": {
        "type": "string",
        "format": "file"
      }
    },
    "required": ["email", "firstName", "lastName"]
  }
}

Benefits

1. Single Source of Truth

Validation rules and API documentation are always synchronized. When you update validation attributes, the OpenAPI schema automatically reflects the changes.

2. Reduced Boilerplate

Eliminates the need for manual schema definitions and custom MapType configurations in SwaggerGen setup.

3. Type Safety

Validation attributes are checked at compile-time, preventing runtime errors from invalid schema definitions.

4. Maintainability

Changes to validation logic automatically propagate to API documentation without additional maintenance.

Limitations

Required Properties

The [Required] attribute currently doesn't set the required array in OpenAPI schemas. Required properties should be handled at the schema level by Swashbuckle's base functionality.

Complex Validations

Custom validators and model-level validations don't generate OpenAPI constraints. These require manual documentation or custom schema filters.

Conditional Validations

Attributes like [RequiredIf] don't affect OpenAPI schemas as they represent runtime conditional logic.

Troubleshooting

Schema Not Generated

  • Ensure AddSannrValidationSchemas() is called in SwaggerGen options
  • Verify the Sannr package is installed
  • Check that model properties have Sannr validation attributes

Incorrect Constraints

  • Verify attribute parameters match expected values
  • Check for typos in attribute names
  • Ensure attributes are from the Sannr namespace, not System.ComponentModel.DataAnnotations

Build Errors

  • Confirm Swashbuckle.AspNetCore version compatibility
  • Check for conflicting schema filters
  • Verify Sannr package is correctly referenced

Advanced Usage

Custom Schema Filters

You can combine Sannr's automatic schema generation with custom filters:

csharp
builder.Services.AddSwaggerGen(options =>
{
    options.AddSannrValidationSchemas();

    // Add custom filters for complex validations
    options.SchemaFilter<CustomValidationFilter>();
});

Integration with API Versioning

Works seamlessly with API versioning libraries like ASP.Versioning:

csharp
builder.Services.AddSwaggerGen(options =>
{
    options.AddSannrValidationSchemas();

    // API versioning configuration
    options.DocInclusionPredicate((name, api) => true);
});

Migration from Manual Schemas

Before (Manual)

csharp
builder.Services.AddSwaggerGen(options =>
{
    options.MapType<UserRequest>(() => new OpenApiSchema
    {
        Type = "object",
        Properties = new Dictionary<string, OpenApiSchema>
        {
            ["email"] = new() { Type = "string", Format = "email" },
            ["age"] = new() { Type = "integer", Minimum = 18, Maximum = 120 }
        }
    });
});

After (Automatic)

csharp
builder.Services.AddSwaggerGen(options =>
{
    options.AddSannrValidationSchemas(); // Single line!
});

// Model automatically generates schema
public class UserRequest
{
    [EmailAddress] public string Email { get; set; }
    [Range(18, 120)] public int Age { get; set; }
}

Testing

The OpenAPI integration includes comprehensive unit tests covering:

  • Attribute-to-constraint mapping
  • Multiple attributes on single properties
  • Edge cases and error handling
  • Schema filter integration

Run tests with:

bash
dotnet test --filter OpenApiIntegrationTests

Released under the MIT License.