DEV Community

Cover image for Auto Generate Client From OpenAPI Specification (Swagger)

Posted on

Auto Generate Client From OpenAPI Specification (Swagger)

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:

var client = new HttpClient();
client.BaseAddress = "https://service-b";
var responseMessage = client.PostAsJsonAsync("/some-endpoint", new Payload(...));
Enter fullscreen mode Exit fullscreen mode

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 to integrate swagger into your web api. Getting started tutorial here.

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 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 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. If you want to kickstart your template customization for your preferred language then look here. 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.



# Color
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

# 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

# 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')
Enter fullscreen mode Exit fullscreen mode

Top comments (0)