After publishing a six-part series about my EcommerceDDD project, I’m dedicating this post to highlight a major improvement: automated API client generation.
This enhancement significantly simplifies API consumption across frontend and backend layers, replacing verbose, manual HttpClient
requests with strongly typed, SDK-style clients.
I’ll walk through the rationale behind this shift, the choice of tools (Kiota and Koalesce), and how together they solve real-world integration challenges in distributed systems.
Why Generating API clients?
Manually invoking HTTP endpoints with HttpClient
, string-based URIs, and handcrafted request/response models always felt error-prone and redundant, especially when both ends of the wire are within my control.
Leveraging existing OpenAPI
definitions, I wanted a maintainable, safer, less redundant, and more expressive approach. Code generation provides exactly that.
Why Kiota?
Kiota helps by:
- Eliminate boilerplate HttpClient calls.
- Ensuring compile-time safety for routes, parameters, and data models.
- Reducing redundant DTOs, ViewModels, and manual object matching.
- Align SDK usage with your domain naming and semantics.
- Enhancing developer experience via IntelliSense and clean APIs.
With Kiota, consuming an endpoint like PUT /quotes/{quoteId}/items
in TypeScript becomes a clean and intuitive one-liner:
Frontend (Angular/Typescript)
1
await quotesClient.api.quotes.byQuoteId(quoteId).items.put(request);
Backend (C#)
1
await _quotesClient.Api.Quotes[quoteId].Items.PutAsync(request);
No longer worrying about paths, headers, serialization, or model mismatches, is bliss!
Why Koalesce? 🐨
Kiota requires a single OpenAPI definition for client generation. But EcommerceDDD’s microservice architecture means multiple individual APIs, each with its own spec. Without a single merged spec, I’d have to generate multiple separate API clients.
At the same time, the frontend SPA (Single Page Application)
interacts with the backend only through a unified API Gateway, unaware of the distributed backend architecture.
That’s where the development challenge began. As we saw previously in the Part 5 - Wrapping up infrastructure (Docker, API gateway, IdentityServer, Kafka), Ocelot aggregates microservices into a single entry point but doesn’t merge or expose a unified OpenAPI definition.
But what if we could do it, and give a single OpenAPI definition to Kiota generate a single client all at once?
That’s precisely the problem Koalesce solves. After looking for merging tools but not finding any that could do it seamlessly with .NET, I created Koalesce, a lightweight open-source .NET library designed to merge multiple OpenAPI documents into one.
Putting It All Together
Now my workflow looks like this:
- Each microservice holds its own OpenAPI definition.
- Koalesce merges them into a single spec at the API Gateway.
- Kiota generates TypeScript (frontend) and C# (backend) SDK clients from the merged spec.
- Backend microservices leverage Kiota for service-to-service calls.
- Frontend views directly consume API endpoints through Kiota clients.
Hands-on
Generating a Single OpenAPI Definition with Koalesce
According to its README file, Koalesce simply needs URIs for OpenAPI specs, typically configured in appsettings.json
:
With Koalesce, you can merge OpenAPI definitions in two ways:
Middleware approach (dynamic merge)
Add the Koalesce middleware to your .NET application pipeline (e.g., Program.cs) to expose a merged document on-the-fly at runtime.
✅ Pros
- Always up-to-date; changes reflect immediately.
- Speeds development; no manual regen or CI/CD needed.
❌ Cons
- Dependent on live services; failure in a microservice skips its definition.
- Can slow startup and Swagger load times.
- Misalignments between microservice specs (e.g. incompatible OpenAPI versions) can cause runtime errors.
CLI (Command Line Interface) approach
Use the Koalesce.OpenAPI.CLI
tool to output a .json
or .yaml
file containing the merged spec on the hard drive.
✅ Pros
- Because you run it manually, and when you know the services are available, the risk of runtime merging failure is reduced.
- Once merged, the single spec can be served without depending on microservices being online (great for CI/CD or sandbox environments).
❌ Cons
- Requires manual regeneration on API changes.
- Risk of stale specs without automation.
My Approach to the project (Hybrid)
I always tested endpoints before having a UI, either relying on Swagger UI/or using Postman. While developing the EcommerceDDD
, I used Koalesce on both ways, for different occasions.
Middleware (for API Gateway in active development):
More recently, after applying Kiota across the project, having all services displayed and accessible from a single Swagger UI proved really handy. I let the API Gateway leverage hosting the single definition through using the Middleware approach by installing the Koalesce.OpenAPI nuget package in the EcommerceDDD.ApiGateway
itself, and adding Koalesce to its execution pipeline in Program.cs
like this:
1
2
3
4
5
6
7
8
9
10
11
12
// Register Koalesce
services.AddKoalesce(builder.Configuration)
.ForOpenAPI();
...
// Enable Koalesce before Swagger Middleware
app.UseKoalesce();
...
// Enable Swagger UI
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint(koalesceOptions.MergedOpenApiPath, koalesceOptions.Title);
});
Then, the ApiGateway now exposes a Swagger UI at http://localhost:5000/swagger/index.html like this:

Pretty cool, right? And since the frontend only knows the Gateway server URI, generating frontend Kiota typescript clients in the SPA itself was a one-liner command:
Install Kiota as .NET tool
1
dotnet tool install --global Microsoft.OpenApi.Kiota
Generate clients from the API Gateway OpenAPI definition
1
kiota generate --openapi http://localhost:5000/swagger/v2/apigateway.yaml --language TypeScript --output ./src/app/clients --clean-output && npm run fix:kiota-imports
⚠️ In package.json file you will find the npm
dependencies to inject and use KiotaClientService
with Angular components. I also added a node script, so you can run npm run generate:kiota
whenever you want to generate the clients again.
⚠️ I had to deal with compilation issues due to imports through that fix-kiota-imports.js
. I’m still looking for better ways to handle it.
CLI (Standalone backend project)
Afterwards, with more enhancements, I wanted to also replace manual service-to-service HttpClient
calls that happen in the backend, required for cases where responses must happen more quickly instead of relying on message brokers, like Kafka, as well as to benefit from the code-cleanup Kiota can bring to the backend.
For that, I added a crosscutting
project, EcommerceDDD.ServiceClients, to host a C#-client
implementation of the same ApiGateway definitions we now use on the frontend.
Here I used the Koalesce.OpenAPI.CLI
, after installing it as .NET tool with:
1
dotnet tool install --global Koalesce.OpenAPI.CLI --version --version 0.1.1-alpha.2 # Replace with latest version if available
While running the application, I could generate the merged OpenAPI definition as the apigateway.yaml file with:
1
koalesce --config src\Crosscutting\EcommerceDDD.ApiGateway\appsettings.json --output src\Crosscutting\EcommerceDDD.ServiceClients\apigateway.yaml

To finally generate C# Kiota clients with:
1
kiota generate -d src\Crosscutting\EcommerceDDD.ServiceClients\apigateway.yaml -l CSharp -c ApiGatewayClient -n EcommerceDDD.ServiceClients.ApiGateway -o Kiota
⚠️ I added an automatic execution for Kiota generation while in DEBUG in the EcommerceDDD.ServiceClients.csproj.
Finally, under /Kiota
files and folders, we now have the ApiGatewayClient.cs
, and it can be injected anywhere when service-to-service communication is required.
Final Thoughts
Automated API clients using Kiota provide clear maintainability, reliability, and developer experience benefits. Though relatively new, Kiota elegantly solves API consumption with an opinionated, focused approach, reducing complexity and enhancing community adoption.
As for Koalesce, merging multiple OpenAPI definitions into a monolithic-style client—as I’ve done—only makes sense depending on your project’s complexity, scale, and CI/CD pipeline. It’s not a one-size-fits-all solution, but for EcommerceDDD, it proved to be a great fit.
I’m still experimenting with this approach, and Koalesce remains under active development. That said, it’s already been valuable in streamlining my workflow, and I hope it proves useful to others as well. The project is open to feedback and contributions.
If you’re interested, you can find both projects here:
Thanks for reading — see you in the next post!