Auto Generate Client From OpenAPI Specification (Swagger)
Tags: aspnetcore, swagger, codegen, bash
Published: 2021-04-06 16:17:33

---
title: Auto Generate Client From OpenAPI Specification (Swagger)
published: true
description: 
tags: aspnetcore, swagger, codegen, bash
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2aun4ci5hstu5msi2wur.png
---
*TL;DR - Working script at the end*

In a microservices system, one of the mechanism for one service to talk to another is using Http. For example, if **Service A** wants to invoke an endpoint on **Service B** it can do something like below:
```csharp
var client = new HttpClient();
client.BaseAddress = "https://service-b";
var responseMessage = client.PostAsJsonAsync("/some-endpoint", new Payload(...));
```

The issue here is that the model class `Payload` was already written in `B` but then `A` would have to write it again in order to have typing and whenever there would be a change in specification in `B` then `A` would have to be manually changed also. So coupled and duplication.

Now, lets assume another `Service C` wants to invoke the same endpoint on `B` so, `C` would have to duplicate the code like `A` again.

We can can get rid of this manual and redundant process by auto-generating clients from the services like API SDKs which can then be consumed by another service.

#### To Dos:
1. Integrate with Swagger for your web api
2. Access to auto-generated `swagger.json` based on your web api
3. Tool to auto-generate code according to choice of language

#### 1. Integrate with Swagger for your web api
Pretty easy in ASP.NET Core. Use [Swashbuckle](https://github.com/domaindrivendev/Swashbuckle.AspNetCore) to integrate swagger into your web api. Getting started tutorial [here](https://docs.microsoft.com/en-us/aspnet/core/tutorials/getting-started-with-swashbuckle).

#### 2. Access to auto-generated `swagger.json` based on your web api
When you run your web api app, you can access the `swagger.json` at `http://localhost:<port>/swagger/v1/swagger.json`. Now either you can pass the link to `swagger.json` or make it accessible from file system. If you go the former route then you need to ensure your web api is up somewhere and updated or spin it up locally. I went ahead with downloading the file into file system using [Swashbuckle.AspNetCore.Cli](https://github.com/domaindrivendev/Swashbuckle.AspNetCore#swashbuckleaspnetcorecli) which can generate `swagger.json` from your web api assembly. 

#### 3. Tool to auto-generate code according to choice of language
I only found `NSwag` or [`swagger-codegen`]((https://github.com/swagger-api/swagger-codegen)) for this and went ahead with the latter because it has more options and configurability. A great feature of this tool is that you can control the generated code through the use of mustache templates documented [here](https://github.com/swagger-api/swagger-codegen/wiki/Mustache-Template-Variables). If you want to kickstart your template customization for your preferred language then look [here](https://github.com/swagger-api/swagger-codegen/tree/master/modules/swagger-codegen/src/main/resources). Now, you can execute a command as simple as `swagger-codegen generate -i ./swagger.json -l ruby -o /tmp/test/`.

## Example script
Below is an example of bash script that is generating a customized C# client in a Linux machine.

```sh
#!/bin/bash

swaggerCodeGenCliDownloadLink='https://repo1.maven.org/maven2/io/swagger/codegen/v3/swagger-codegen-cli/3.0.25/swagger-codegen-cli-3.0.25.jar'
swaggerCodeGenCliPath='./swagger-codegen-cli.jar'
finalGeneratedClientPath='./DEV.Client/generated'
swaggerGenOut='./swagger-code-gen-out'
swaggerInputFilePath='./swagger.json' 
swaggerTemplateFolderPath='./swagger-code-gen-templates'
ApiProjectName='DEV.API'
clientProjectName='DEV.Client'

# Color
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
NC='\033[0m' # No Color

function red {
    printf "${RED}$@${NC}\n"
}

function green {
    printf "${GREEN}$@${NC}\n"
}

function yellow {
    printf "${YELLOW}$@${NC}\n"
}

# build api project
dotnet build "$ApiProjectName/$ApiProjectName.csproj"
echo $(green 'Building project done!')

#restore swashbuckle aspnetcore cli tool
dotnet tool restore
echo $(green 'Restored dotnet tools!')

# generate swagger json
dotnet swagger tofile --output swagger.json "$ApiProjectName/bin/Debug/net5.0/$ApiProjectName.dll" v1
echo $(green 'Generating swagger.json done!')

# download swagger code gen cli
if [ ! -f $swaggerCodeGenCliPath ]; then
    echo $(yellow 'Downloading swagger-code-gen cli...')
    curl $swaggerCodeGenCliDownloadLink -o $swaggerCodeGenCliPath
fi

# generate models and apis
java -Dapis -DapiDocs=false -Dmodels -DmodelDocs=false -DapiTests=false -DmodelTests=false -jar $swaggerCodeGenCliPath generate -i $swaggerInputFilePath -l csharp -o $swaggerGenOut -t $swaggerTemplateFolderPath --additional-properties modelPackage=$clientProjectName apiPackage=$clientProjectName packageName=$clientProjectName
echo $(green 'Generating models and apis done!')

# if there was previously generated then delete it
if [ -d $finalGeneratedClientPath ]; then
    echo $(red 'Deleting stale generated folder')
    rm -r $finalGeneratedClientPath
fi

# move the generate code into target client project
mv "$swaggerGenOut/src/$clientProjectName/$clientProjectName/" $finalGeneratedClientPath
echo $(green 'Moving files to client project done!')

# remove temp swagger code generated folder
rm -r $swaggerGenOut
echo $(green 'Removed temp generated directory')
```