Skip to content

harvzor/swashbuckle-vs-nswag

Repository files navigation

Introduction

Both Swashbuckle and NSwag provide a UI (Swagger) for easily making API requests to your dotnet API. Swashbuckle appears to be the go-to solution, but development recently has come to a halt.

This repo compares the state of the two packages.

Conclusion

Swashbuckle main benefits:

  • slightly better documentation
  • generally favoured (by developers and Microsoft)
  • doesn't depend upon Newtonsoft Json.NET

NSwag main benefits:

  • actively developed
  • sponsored so development is likely to continue

My conclusion: both packages are very good, however I slightly favour NSwag as if I have an issue, it seems more likely it would be fixed (especially if I make a PR).

Comparison

Swashbuckle NSwag Thoughts
GitHub https://github.com/domaindrivendev/Swashbuckle.AspNetCore https://github.com/RicoSuter/NSwag
GitHub Stars 5k 6.3k Comparing stars is not fair as NSwag has more functionality than Swashbuckle, so perhaps people are starring different specific things.
NuGet Nuget NuGet Version
NuGet downloads (per day average) 172.1k 18.1k Swashbuckle has 9x more downloads.
Swagger UI version shipped v4.15.5, Wed, 09 Nov 2022 06:53:00 v5.7.2, Mon, 18 Sep 2023 07:42:57 Used JSON.stringify(versions) in console to find the version. Swagger UI could be swapped out for a more recent version regardless of the generator.
OpenApi version v3.0.1, Dec 7 2017 3.0.0, Jul 26 2017 Latest is v3.1.0, Feb 16 2021.
GitHub commits to master (2023) 1 ~97
Owners domaindrivendev RicoSuter Doesn't seem like either repo allows any other users to have admin rights.
Sponsorship No sponsorship is labeled. Sponsors are clearly labeled. NSwag clearly has sponsorship which gives the creator incentive to continue to support it.
Microsoft docs Get started with Swashbuckle and ASP.NET Core

Improve the developer experience of an API with Swagger documentation
Get started with NSwag and ASP.NET Core The basic docs from Microsoft are almost exactly the same, but the training module focuses on using Swashbuckle.

Stats true as of 12/01/2024.

Feature comparison

Feature Swashbuckle NSwag Thoughts
Supports Minimal APIs
Supports remapping types I found it easier remap in Swashbuckle but perhaps because I have more experience with it. Documentation in NSwag doesn't currently compile as it's out of date and it doesn't explicitly tell you how to add the overwritten schema to the TypeMappers.
Supports open generics when remapping types Neither allow you to dynamically remap open generic types. I have a PR open on Swashbuckle to fix this.
Supports System.Text.Json NSwag currently uses the latest version (v13.0.3) of Newtonsoft Json.NET. There's a thread to track trying to switch to using STJ but RicoSuter has not commented since late 2021. It seems that there are fears that fully switching to STJ will change how NSwag generates the JSON schemas so would be a breaking change.

However, you can already use attributes such as [JsonPropertyName("propertyName")] in your DTOs and NSwag will support it. Support for STJ appears to have been shimmed in:

> Currently we map the System.Text.Json “rules” manually to the newtonsoft metadata with a custom contract resolver.

RicoSuter/NJsonSchema#1014 (comment)

Default JSON

Swashbuckle:
{
  "openapi": "3.0.1",
  "info": {
    "title": "SwashbuckleVsNSwag.Swashbuckle",
    "version": "1.0"
  },
  "paths": {
    "/WeatherForecast": {
      "get": {
        "tags": [
          "WeatherForecast"
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/WeatherForecastDto"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/WeatherForecastDto"
                  }
                }
              },
              "text/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/WeatherForecastDto"
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "WeatherForecastDto": {
        "type": "object",
        "properties": {
          "date": {
            "type": "string",
            "format": "date-time"
          },
          "temperatureC": {
            "type": "integer",
            "format": "int32"
          },
          "temperatureF": {
            "type": "integer",
            "format": "int32",
            "readOnly": true
          },
          "summary": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      }
    }
  }
}
NSwag:
{
  "x-generator": "NSwag v14.0.1.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))",
  "openapi": "3.0.0",
  "info": {
    "title": "My Title",
    "version": "1.0.0"
  },
  "servers": [
    {
      "url": "http://localhost:5047"
    }
  ],
  "paths": {
    "/WeatherForecast": {
      "get": {
        "tags": [
          "WeatherForecast"
        ],
        "operationId": "WeatherForecast_Get",
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/WeatherForecastDto"
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "WeatherForecastDto": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "date": {
            "type": "string",
            "format": "date-time"
          },
          "temperatureC": {
            "type": "integer",
            "format": "int32"
          },
          "temperatureF": {
            "type": "integer",
            "format": "int32"
          },
          "summary": {
            "type": "string",
            "nullable": true
          }
        }
      }
    }
  }
}

Remapping types

Swashbuckle:

options.MapType<TimeSpan>(() => new OpenApiSchema
{
    Type = "string",
    Example = new OpenApiString("00:00:00")
});

NSwag:

configure.SchemaSettings.TypeMappers.Add(new PrimitiveTypeMapper(typeof(TimeSpan), schema =>
{
    schema.Format = "string";
    schema.Type = JsonObjectType.String;
    schema.Example = "00:00:00";
}));

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages