Autogenerate SDK clients for .NET APIs using Autorest and OpenAPI

How to create API libraries for your DotNET project using SwashBuckle Swagger annotations and build-time client generation

  • Table of contents

DotNET web projects with REST APIs can provide typed API client libraries automatically using OpenAPI and related tooling. If you have an HTTP API that is used by a frontend, other services internally, or is a public API consider generating SDK clients. In this tutorial we will demonstrate how to use Autorest, OpenAPI (Swagger) and SwashBuckle with .NET projects to scaffold and publish development kits.

Setup a .NET project

To use OpenAPi with DotNET create a new project. Add the Swashbuckle package references shown to your .csproj to enable annotations and the CLI for generation of the open api spec:

<!-- inside *.csproj -->
<ItemGroup>
    <PackageReference Include="Swashbuckle.AspNetCore" Version="6.3.1" />
    <PackageReference Include="Swashbuckle.AspNetCore.Annotations" Version="6.3.1" />
</ItemGroup>

Annotate controller endpoints

For each web controller endpoint that your wish to expose in your library add a SwaggerOperation annotation.

[HttpGet]
[Route("/user")]
[SwaggerOperation(OperationId = "getUser")]
public async Task<ActionResult<User>> GetUserAsync()
{
    var userId = _authHelper.GetUserId();
    User resultUser = await _userService.GetUserAsync(userId);
    return StatusCode(200, resultUser);
}

Add post build generation step

In your csproj and a post build step to generate the swagger JSON file from the project dll.

<!-- generate swagger spec on build -->
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
    <Exec Command="dotnet tool restore" />
    <Exec Command="dotnet swagger tofile --output swagger.json $(OutputPath)\$(AssemblyName).dll v1" />
</Target>

Create a devops pipeline to build and publish

To build your project in Azure Devops and publish a client to an Artifact Repository create an azure-pipelines.yml file and add the following:

trigger:
  branches:
    include:
    - refs/heads/master
stages:
- stage: build
  displayName: Build
  pool:
    vmImage: ubuntu-18.04
  jobs:
  - job: Build
    steps:
    - checkout: self
      clean: true
      fetchDepth: 1
    - ${{ if in(parameters.stages, 'all', 'build') }}:
      - task: UseDotNet@2
        displayName: Use .NET Core sdk 3.1.420
        inputs:
          version: 3.1.420
      - task: DotNetCoreCLI@2
        displayName: dotnet restore
        inputs:
          command: restore
      - task: DotNetCoreCLI@2
        displayName: dotnet build
        inputs:
          command: build
          

Then include the steps below to install autorest and generate a client in Typescript

- task: CmdLine@2
  displayName: Build package
  inputs:
    script: |
      npm install autorest
      ./node_modules/.bin/autorest autorest.config.yml --package-version='1.$(Build.BuildId).0' --typescript
    failOnStderr: true
- task: Npm@1
  displayName: Install client
  inputs:
    workingDir: client
    command: install 
- task: Npm@1
  displayName: Publish client
  inputs:
    workingDir: client
    command: publish
    publishRegistry: useFeed
    publishFeed: <your-devops-artifact-feed>