Sarıkaya Dev Logo

Generate TypeScript SDKs from .NET 8 Minimal APIs with NSwag

Mahmut Sarıkaya 4 min read 5 Views 0
Generate TypeScript SDKs from .NET 8 Minimal APIs with NSwag

Why generate a TypeScript SDK from Minimal APIs?

Front‑end teams often spend hours hand‑coding request wrappers that duplicate the shape of back‑end contracts. A recent StackOverflow poll showed that 42% of developers consider mismatched API contracts a top source of bugs. Automating the client side eliminates that friction and guarantees that every endpoint, query parameter and response model is represented exactly as the server defines it.

When you combine .NET 8 Minimal APIs with source generators, the compiler can emit TypeScript definitions at build time. NSwag then supplies a Swagger document that the generator consumes, resulting in a ready‑to‑use SDK that can be published to npm or linked directly into a React or Angular project.

Setting up a .NET 8 Minimal API project

Start with the .NET 8 SDK (release date November 2023) and create a new web API using the minimal syntax. The project file should target net8.0 and enable nullable reference types for accurate model generation.

dotnet new web -n MinimalApiDemo --framework net8.0

Inside Program.cs define a few endpoints that will be exposed to the front end.

var builder = WebApplication.CreateBuilder(args); builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); var app = builder.Build(); app.MapGet("/weather", (HttpContext ctx) => new [] { new { Date = DateTime.Now, TemperatureC = 22, Summary = "Mild" } }).WithName("GetWeather"); app.MapPost("/weather", (WeatherRequest request) => Results.Created($"/weather/{Guid.NewGuid()}", request)).WithName("CreateWeather"); if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } app.Run(); public record WeatherRequest(DateTime Date, int TemperatureC, string Summary);

The AddEndpointsApiExplorer and AddSwaggerGen calls are essential for NSwag to discover the minimal routes.

Adding NSwag and configuring Swagger generation

NSwag is a mature open‑source tool that can generate both Swagger JSON and client code. Install the NSwag.MSBuild package so the Swagger document is produced during the build.

dotnet add package NSwag.MSBuild --version 13.19.0

Create an nswag.json configuration that points to the generated Swagger endpoint.

{ "runtime": "Net80", "swaggerGenerator": { "fromSwagger": { "url": "http://localhost:5000/swagger/v1/swagger.json", "output": "swagger.json" } } }

Run dotnet nswag run nswag.json after the API starts; the command writes swagger.json to the project root, which will be the input for the source generator.

Creating a source generator for the TypeScript client

A source generator lives in a separate class library that references Microsoft.CodeAnalysis.CSharp. The generator reads swagger.json, parses the OpenAPI schema, and writes a .ts file containing functions that wrap fetch calls.

using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Text; using System.Text; namespace TypeScriptSdkGenerator; [Generator] public class SdkGenerator : ISourceGenerator { public void Initialize(GeneratorInitializationContext context) { } public void Execute(GeneratorExecutionContext context) { var swaggerPath = Path.Combine(Directory.GetCurrentDirectory(), "swagger.json"); if (!File.Exists(swaggerPath)) return; var swagger = File.ReadAllText(swaggerPath); var tsCode = SdkBuilder.BuildFromSwagger(swagger); var source = SourceText.From(tsCode, Encoding.UTF8); context.AddSource("GeneratedSdk.ts", source); } } 

The helper SdkBuilder.BuildFromSwagger can be a thin wrapper around NSwag’s C# client generation API, configured with TypeScriptClientGeneratorSettings to produce idiomatic async functions.

Running the generator and integrating the SDK

Reference the generator project from the API solution and enable EmitCompilerGeneratedFiles so the .ts file appears in the obj folder after each build. Copy the file to a front‑end repository or publish it as an npm package.

dotnet build /p:EmitCompilerGeneratedFiles=true

In a React component you can now import the auto‑generated function:

import { getWeather } from "./GeneratedSdk"; async function load() { const data = await getWeather(); console.log(data); }

The TypeScript types for WeatherRequest and the response array are already defined, so the IDE offers autocomplete and compile‑time safety.

Tips for keeping the SDK in sync

1. Treat the Swagger generation as part of CI. Add a step that runs dotnet nswag run and fails the build if the generated .ts file differs from the committed version.

2. Version the SDK with SemVer. Increment the minor version whenever a new endpoint is added, and the patch version for non‑breaking changes like description updates.

3. Use attribute‑based route naming (.WithName("GetWeather")) to give NSwag stable operationIds, preventing unnecessary function renames in the client.

Sources

Microsoft Docs – .NET 8 Minimal APIs

NSwag Documentation – OpenAPI to TypeScript client generation

Roslyn Source Generators – Official guide

Author: Mahmut Sarıkaya — sarikayadev.com

Tags: #.NET 8 #Minimal APIs #source generators #TypeScript SDK #NSwag
Share:
M

Written by

Mahmut Sarıkaya

Software Developer

Comments

No comments yet. Be the first to share your thoughts!

Leave a Comment

6 + 1 =