Document REST-API in ASP.Net Core

What I mean by API-documentation is a document that tells me which endpoints that exists, what kind of input that endpoint and method the endpoint uses. Then also gives me what I can expect back from the endpoint.

Documentation is a set of documents provided on paper, or online, or on digital or analog media, such as audio tape or CDs. Examples are user guides, white papers, on-line help, quick-reference guides. It is becoming less common to see paper (hard-copy) documentation. Documentation is distributed via websites, software products, and other on-line applications.

Professionals educated in this field are termed documentalists. This field changed its name to information science in 1968, but some uses of the term documentation still exists and there have been efforts to reintroduce the term documentation as a field of study. Wikipedia

td;tr

death-to-project-documentation-with-extreme-programming-1-638-2

What I am using to automate API documentation is Swagger to get an OpenApu document. Then I have a small razor page app where I use ReDoc to get a user-friendly interface for the Swagger document.

The documentation site is configured through appsettings.json file and easily deployed to the enviroments using Octopus Deploy.

Documentation options

In C#, writing documentation on every method, is boring and I think I never see anyone do that. Documenting the endoints methods in a REST-api project makes more sense and is useful to export that in the generated documentation.

/// <summary></summary>
/// <param name="todoId"></param>
/// <param name="searchQuery"></param>
/// <returns></returns>
public async Task<IActionResult> Get(int todoId, string searchQuery)
{
    throw new NotImplementedException();
}

Enabling the documentation file and setting a path and name for where that should end up while compiling is a good thing to do.

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
  <DocumentationFile>bin\$(Configuration)\$(TargetFramework)\$(AssemblyName).xml</DocumentationFile>
</PropertyGroup>

Swagger

Swagger is an open source software framework backed by a large ecosystem of tools that helps developers design, build, document, and consume RESTful Web services. While most users identify Swagger by the Swagger UI tool, the Swagger toolset includes support for automated documentation, code generation, and test case generation. Wikipedia

public void ConfigureServices(IServiceCollection services)
{
   services.AddSwaggerGen(options =>
   {
       options.IgnoreObsoleteActions();
       options.IgnoreObsoleteProperties();
   });
   services.ConfigureSwaggerGen(options =>
   {
       options.SwaggerDoc("v1", new Info
   {
       Title = "REST Service",
       Version = "v1",
       Description = "REST Service",
       TermsOfService = "None"
   });

    var filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, pathToDoc);
        options.IncludeXmlComments(filePath);
        options.DescribeAllEnumsAsStrings();
    });
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    app.UseSwagger(c =>
    {
        c.PreSerializeFilters.Add((swagger, httpReq) => swagger.Host = httpReq.Host.Value);
    });

    app.UseSwaggerUI(options =>
    {
        options.RoutePrefix = "docs";
        options.InjectStylesheet("/swagger-ui/custom.css");
        options.InjectOnCompleteJavaScript("/swagger-ui/custom.js");
        options.SwaggerEndpoint("/swagger/v1/swagger.json", "");
        options.ShowJsonEditor();
    });
}

ReDoc and ASP.Net Core Razor Page App

When I have multiple ASP.Net Core REST services, adding Swagger and SwaggerUI to each of them is fine, but what I want is to have one site for the documenation. That site can know about the Swagger json document for each service and just view the documentation in a user-friendly way.

redoc-demo

Templates                                         Short Name         Language          Tags
----------------------------------------------------------------------------------------------------------------------------
Console Application                               console            [C#], F#, VB      Common/Console
Class library                                     classlib           [C#], F#, VB      Common/Library
Unit Test Project                                 mstest             [C#], F#, VB      Test/MSTest
xUnit Test Project                                xunit              [C#], F#, VB      Test/xUnit
Razor Page                                        page               [C#]              Web/ASP.NET
MVC ViewImports                                   viewimports        [C#]              Web/ASP.NET
MVC ViewStart                                     viewstart          [C#]              Web/ASP.NET
ASP.NET Core Empty                                web                [C#], F#          Web/Empty
ASP.NET Core Web App (Model-View-Controller)      mvc                [C#], F#          Web/MVC
ASP.NET Core Web App                              razor              [C#]              Web/MVC/Razor Pages
ASP.NET Core with Angular                         angular            [C#]              Web/MVC/SPA
ASP.NET Core with React.js                        react              [C#]              Web/MVC/SPA
ASP.NET Core with React.js and Redux              reactredux         [C#]              Web/MVC/SPA
Razor Class Library                               razorclasslib      [C#]              Web/Razor/Library/Razor Class Library
ASP.NET Core Web API                              webapi             [C#], F#          Web/WebAPI
global.json file                                  globaljson                           Config
NuGet Config                                      nugetconfig                          Config
Web Config                                        webconfig                            Config
Solution File                                     sln                                  Solution

Examples:
    dotnet new mvc --auth Individual
    dotnet new viewimports --namespace
    dotnet new --help
dotnet new rezor

For that I found ReDoc and it is super easy to integrate into an ASP.Net Core Rexor Page application. First I created an application and create a new razor page that I just named the same as the service. Then I am using the CDM alternative so no need to install teh NPM packape.

Alternative 1:
npm install redoc --save
<script src="node_modules/redoc/bundles/redoc.standalone.js"> </script>

Alternativ 2:
<redoc spec-url="url/to/your/spec"></redoc>

When that is done, it is almost ready to test. It is missing a couple of lines in the created razor page that should host the Swagger documentation.

<redoc spec-url='@Model.SwaggerUrl'></redoc>
<script src="https://cdn.jsdelivr.net/npm/redoc@next/bundles/redoc.standalone.js"> </script>

@Model.SwaggerUrl is the url to the Swagger json document. I created a property in the PageModel and setting the prperty from the AppSettings that is set in the appsettings.json.

public class TestModel : PageModel
{
    private readonly AppSettings _appSettings;

    public TestModel(IOptions<AppSettings> appSettings)
    {
        _appSettings = appSettings.Value;
    }

    public string SwaggerUrl => _appSettings.OrganisasjonServiceSwaggerUrl;

    public void OnGet()
    {
    }
}

Automation

Using Swagger and this simple little documentation application can be automated as far as I am interested to automate the process. I still need to create the razor page and that little information on the page, but even that can I create a template to automate if I really want to.

What I am most interested in is to automate the deployment through Octopus Deploy. Since everyuthing that is changeing between enviroments is specified in the appsettings.json file, that is made easy by the json configuration in the IIS deployment step.

- Happy Coding!

Links

Teis Lindemark

Passionate software developer and beer brewer

Bergen, Norway https://teilin.net