Anto Subash.

Published on

Generate typescript client from swagger / OpenApi

Intro

In this post we will see how to use NSwag to generate typescript client from swagger and open api. We will use abp as a sample app and generate typescript client.

Create an abp App and Run Migrations

Create the App

Run the following command to create the abp app.

1abp new AbpNSwag

Run Migrations

change directory to src/AbpNSwag.DbMigrator and run the migration project

1dotnet run

Fix the type name in the swagger

Create type extension

Change the custom schema id for NSwag generation

1using System;
2using System.Linq;
3using System.Reflection;
4using System.Runtime.Serialization;
5using System.Text;
6
7namespace AbpNSwag
8{
9    public static class TypeExtensions
10    {
11        public static string FriendlyId(this Type type, bool fullyQualified = false)
12        {
13            var typeName = fullyQualified
14                ? type.FullNameSansTypeParameters().Replace("+", ".")
15                : type.Name;
16
17            if (type.IsGenericType)
18            {
19                var genericArgumentIds = type.GetGenericArguments()
20                    .Select(t => t.FriendlyId(fullyQualified))
21                    .ToArray();
22
23                return new StringBuilder(typeName)
24                    .Replace(string.Format("`{0}", genericArgumentIds.Count()), string.Empty)
25                    .Append(string.Format("[{0}]", string.Join(",", genericArgumentIds).TrimEnd(',')))
26                    .ToString();
27            }
28
29            return typeName;
30        }
31
32        public static string FullNameSansTypeParameters(this Type type)
33        {
34            var fullName = type.FullName;
35            if (string.IsNullOrEmpty(fullName))
36                fullName = type.Name;
37            var chopIndex = fullName.IndexOf("[[");
38            return (chopIndex == -1) ? fullName : fullName.Substring(0, chopIndex);
39        }
40
41        public static string[] GetEnumNamesForSerialization(this Type enumType)
42        {
43            return enumType.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static)
44                .Select(fieldInfo =>
45                {
46                    var memberAttribute = fieldInfo.GetCustomAttributes(false).OfType<EnumMemberAttribute>().FirstOrDefault();
47                    return (memberAttribute == null || string.IsNullOrWhiteSpace(memberAttribute.Value))
48                        ? fieldInfo.Name
49                        : memberAttribute.Value;
50                })
51                .ToArray();
52        }
53    }
54}

This file is copied from the here https://github.com/domaindrivendev/Swashbuckle.WebApi/blob/master/Swashbuckle.Core/Swagger/TypeExtensions.cs

Change the custom schema id and operation id

Update AddAbpSwaggerGenWithOAuth method call in your web project.

1options.CustomSchemaIds(type => type.FriendlyId().Replace("[", "Of").Replace("]", ""));
2options.CustomOperationIds(options => $"{options.ActionDescriptor.RouteValues["controller"]}{options.ActionDescriptor.RouteValues["action"]}");

this will fix the generic list problem and simplify the name in the swagger ui.

Now we are ready to generate the typescript client.

Install NSwag

1npm install nswag -g

Generate typescript client

1nswag openapi2tsclient /input:https://localhost:44392/swagger/v1/swagger.json /output:generated/MyProjectModels.ts /typeScriptTemplate Axios

This will generate the Axios client for you to use.

Other generators

Other options is to use the openapi-typescript-codegen package. Install the package globally.

1npm install openapi-typescript-codegen -g

create the local copy of swagger json from here https://localhost:44392/swagger/v1/swagger.json now we can use this json file to generate type script client.

1openapi -i swagger.json -o api -c axios

this will generate axios client with proper structure.

Repo : https://github.com/antosubash/AbpNSwag