Automate SDK creation for ASP.NET APIs
Supported SDK languages:
TypeScript / Javascript | Java / Kotlin | Python | C# | Go | PHP |
---|---|---|---|---|---|
✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
- Before getting started make sure you have a liblab account and the liblab CLI installed.
- If you don't have an existing project but want to try out liblab then check out our standalone tutorials.
Providing an SDK for your API can significantly ease the development process for users, ensuring quicker integration and encouraging wider adoption due to the streamlined development experience.
In this doc you'll learn how to take your existing ASP.NET API and generate user-friendly SDKs for most major programming languages using the liblab SDK generator. After a short bit of setup you'll have a pipeline that will automatically generate SDKs for your API whenever you make changes.
Initializing the SDK
First, create a new directory to store your SDK. This directory should be separate from your existing project directory:
mkdir ASP-NET-sdk
cd ASP-NET-sdk
And initialize your project to create a liblab.config.json
file:
liblab init
Getting an OpenAPI Spec File
In order to auto-generate SDKs from an ASP.NET project you need an OpenAPI Spec File. The OpenAPI file contains information that describes your API like servers, paths, operations, parameters, responses, and security schemas.
Installing Microsoft.AspNetCore.OpenApi
ASP.NET Core in .NET 8.0 generates OpenAPI specs differently than .NET 9.0.
If you're using .NET 8.0 check the official documentation on how to Generate OpenAPI documents.
You can generate OpenAPI spects for your ASP.NET project using Microsoft.AspNetCore.OpenApi
. To install the package into your project, run the following command:
- .NET CLI
- Visual Studio
dotnet add package Microsoft.AspNetCore.OpenApi
Install-Package Microsoft.AspNetCore.OpenApi
To generate the OpenAPI spec, you have to add the AddOpenApi extension method on the app builder's service collection and map the endpoints using the MapOpenApi extension method on the app. Two examples of how to configure this in your app are shown below:
- Minimal API
- Controller
//...
var builder = WebApplication.CreateBuilder();
builder.Services.AddOpenApi();
var app = builder.Build();
app.MapOpenApi();
app.MapGet("/hello", () => "Hello world!");
app.Run();
//...
// Program.cs
builder.Services.AddOpenApi();
var app = builder.Build();
app.MapOpenApi();
app.MapControllers();
app.Run();
// ...
// HelloController.cs
[ApiController]
public class HelloController : ControllerBase
{
[HttpGet("/hello")]
public IResult Hello()
{
return Results.Ok("Hello world!");
}
}
//...
The OpenAPI spec will be available at https://localhost:<port>/openapi/v1.json
.
Configure the Metadata
Metadata can be added to your endpoints to provide useful information for the users of your SDK in one of the following ways:
- In controller-based APIs, metadata is defined using attributes like
[EndpointDescription]
,[HttpPost]
, and[Produces]
. - In minimal APIs, metadata can be collected from metadata attributes (like in controller-based APIs) or by using extension methods and typed results in route handlers as shown in the examples below.
- Minimal API
- Controller
To add summaries and descriptions to your endpoints, you can use the WithSummary
and WithDescription
extension methods:
//...
app.MapGet("/hello", () => "Hello world!")
.WithSummary("Get a greeting")
.WithDescription("This endpoint returns a friendly greeting.");
//...
To add summaries and descriptions to your endpoints, you can use the [EndpointSummary]
and [EndpointDescription]
attributes:
// HelloController.cs
//...
[EndpointSummary("Get a greeting")]
[EndpointDescription("This endpoint returns a friendly greeting.")]
[HttpGet("/hello")]
public IResult Hello()
{
return Results.Ok("Hello world!");
}
//...
- Minimal API
- Controller
If you need to group related endpoints in the OpenAPI spec, you add tags to your endpoints using the WithTags
extension method:
//...
app.MapGet("/hello", () => "Hello world!")
.WithTags("Greetings");
//...
In controller-based APIs, the controller name is automatically assigned as a tag for all its endpoints. However, you can modify this default behavior by using the [Tags] attribute.
```csharp title="Adding tags"
// HelloController.cs
//...
[Tags("Greetings")]
[HttpGet("/hello")]
public IResult Hello()
{
return Results.Ok("Hello world!");
}
//...
- Minimal API
- Controller
To describe the endpoint parameters, you can use the Description
attribute:
using System.ComponentModel;
//...
app.MapGet("/hello/{name}", (
[Description("The name that will be greeted.")] string name
) => $"Hello {name}!");
//...
To describe the endpoint parameters, you can use the Description
attribute:
using System.ComponentModel;
// HelloController.cs
//...
[HttpGet("/hello/{name}")]
public IResult Hello([Description("The name that will be greeted.")] string name)
{
return Results.Ok($"Hello {name}!");
}
//...
The [Description]
attribute can also be applied to properties in data models to provide additional details.
public record Person
{
[Description("The person's name.")]
public string Name { get; init; }
[Description("The person's age.")]
public int Age { get; init; }
}
ASP.NET has extensive documentation for configuring OpenAPI Specs, customizing metadata, and transforming metadata.
Complete Example
Putting the above steps together produces a complete example of an ASP.NET API that generates an OpenAPI spec file:
- Minimal API
- Controller
using Microsoft.OpenApi.Models;
using System.ComponentModel;
var builder = WebApplication.CreateBuilder();
builder.Services.AddOpenApi();
var app = builder.Build();
app.MapOpenApi();
app.MapGet("/hello/{name}",
([Description("The person's name.")] string name) => $"Hello {name}!")
.WithSummary("Get a greeting")
.WithDescription("This endpoint returns a friendly greeting.");
app.Run();
Click to see the OpenAPI spec for the Minimal API Example
{
"openapi": "3.0.1",
"info": {
"title": "helloMinimal | v1",
"version": "1.0.0"
},
"servers": [
{
"url": "http://localhost:5127"
}
],
"paths": {
"/hello/{name}": {
"get": {
"tags": [
"helloMinimal"
],
"summary": "Get a greeting",
"description": "This endpoint returns a friendly greeting.",
"parameters": [
{
"name": "name",
"in": "path",
"description": "The person's name.",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "OK",
"content": {
"text/plain": {
"schema": {
"type": "string"
}
}
}
}
}
}
}
},
"components": { },
"tags": [
{
"name": "helloMinimal"
}
]
}
// Program.cs
using Microsoft.AspNetCore.Mvc;
using System.ComponentModel;
using Microsoft.OpenApi.Models;
var builder = WebApplication.CreateBuilder();
builder.Services.AddControllers();
builder.Services.AddOpenApi();
var app = builder.Build();
app.MapOpenApi();
app.MapControllers();
app.Run();
// ...
// Define a simple controller with a GET endpoint
// HelloController.cs
[ApiController]
[Route("hello")]
public class HelloController : ControllerBase
{
[HttpGet("/hello/{name}")]
[EndpointSummary("Get a greeting")]
[EndpointDescription("This endpoint returns a friendly greeting.")]
public IResult Hello([Description("The name that will be greeted.")] string name)
{
return Results.Ok($"Hello {name}!");
}
}
Click to see the OpenAPI spec for the Controller Example
{
"openapi": "3.0.1",
"info": {
"title": "hello | v1",
"version": "1.0.0"
},
"servers": [
{
"url": "http://localhost:5149"
}
],
"paths": {
"/hello/{name}": {
"get": {
"tags": [
"Hello"
],
"summary": "Get a greeting",
"description": "This endpoint returns a friendly greeting.",
"parameters": [
{
"name": "name",
"in": "path",
"description": "The name that will be greeted.",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "OK"
}
}
}
}
},
"components": { },
"tags": [
{
"name": "Hello"
}
]
}
Copy Your Spec
Once you're done adding the metadata and customizing your API with transformers, restart your ASP.NET server:
dotnet run
To view your OpenAPI spec, navigate to the /openapi/v1.json
endpoint on your server (e.g. http://localhost:5127/openapi/v1.json
).
If the OpenAPI spec appears, then you're ready to proceed. Save your openapi.json
file to the liblab project directory you created during the initializing step. This is typically something like:
cd ../ASP-NET-sdk
curl -o openapi.json http://localhost:5127/openapi/v1.json
Configuring liblab
Now you'll need to make some minor updates to your liblab.config.json
file in your ASP-NET-sdk folder:
- Point the
specFilePath
parameter to the location of your OpenAPI spec file (ex../openapi.json
). - Specify the
baseUrl
of your API. This is the URL that the SDK will use to make requests to your API.
The top of the file should then looks something like this:
{
"sdkName": "ASP-NET-sdk",
"apiVersion": "1.0.0",
"apiName": "ASP-NET-api",
"specFilePath": "./openapi.json",
"baseUrl": "http://localhost:PORT",
"languages": [
"go",
"java",
"python",
"typescript",
"csharp"
],
"auth": [
"bearer"
]
}
liblab's SDK generator supports many more advanced URL and environment configuration options than the basic configuration shown here.
Explore the configuration documentation to discover all the available settings and enhancements or review the SDK customization options for tailored adjustments.
Generate the SDK
During build you might see warnings about the OpenAPI spec. These are often minor issues that can be fixed later.
Now that you have an OpenAPI spec file and have finished setting the liblab.config.json
file, it's time to generate our SDK:
liblab build
The CLI will validate the OpenAPI spec and notify you about any issues with it or the liblab.config.json
.
The output will look something like this:
✓ No issues detected in the liblab config file.
No hooks found, SDKs will be generated without hooks.
⚠ Validation succeeded with warnings
Created /Users/username/projects/ASP-NET-sdk/output/api-schema-validation.json with the full linting results
Detected 8 potential issues with the spec:
⚠ Info object must have "contact" object.
⚠ Info "description" must be present and non-empty string.
⚠ Operation "description" must be present and non-empty string. (3 occurrences)
⚠ Operation tags must be defined in global tags. (3 occurrences)
? It is important to fix your spec before continuing with a build. Not fixing the spec
may yield a subpar SDK and documentation. Would you like to attempt to build the SDK
anyway? (Y/n)
You can go ahead and confirm by typing Y
.
Next you'll see the builds started and once they're done you'll see a message like this:
Ignoring the spec errors and attempting to build with the spec
Your SDKs are being generated. Visit the liblab portal (https://app.liblab.com/apis/ASP-NET-sdk/builds/1234) to view more details on your build(s).
✓ C# built
✓ Go built
✓ Java built
✓ Python built
✓ TypeScript built
✓ Generate package-lock.json for TypeScript
Successfully generated SDKs for Python, Java, Go, TypeScript, C#. ♡ You can find them inside: /Users/username/projects/ASP-NET-sdk/output
If we go inside the output
directory, we will see a directory for each of our SDKs:
ls output/
api-schema-validation.json go python
csharp java typescript
Try out your SDK
The following instructions assume you have already set up the respective development environment for the language you are testing. If necessary refer to each language's official documentation before proceeding.
Learn more about the language versions liblab generated SDKs support.
The generated SDKs are intended to be deployed to package managers for end users. The instructions below to test your SDK locally will differ from user-facing instructions.
- TypeScript / JavaScript
- Python
- Java
- C#
cd output/typescript/examples
npm run setup
npm run start
cd output/python/examples
chmod +x install.sh
./install.sh
source .venv/bin/activate
python3 sample.py
cd output/java/example
chmod +x run.sh
./run.sh
cd output/csharp/Example
dotnet run --framework net9.0
Next Steps
Now that you've packaged your SDKs you can learn how to integrate them with your CI/CD pipeline and publish them to their respective package manager repositories.
We currently have guides for: