Developing APIs
APIs are the primary way to expose a serviceβs functionality within the Lino ecosystem.
This chapter describes how the framework generates ready-to-use Minimal APIs, how automatic registration via Source Generators works, and which practices we recommend for creating clear, testable, and well-documented endpoints.
Minimal APIs
Lino adopts the Minimal API style by default for endpoint generation, prioritizing:
- Clarity β concise, direct, and expressive code.
- Performance β optimized responses without unnecessary overhead.
Built-in Features
TypedResults: ensure strongly typed responses, aiding readability and OpenAPI generation.
API Versioning: endpoints can evolve without breaking compatibility.
Enriched Documentation: configurable metadata is directly incorporated into OpenAPI, including:
- WithTags β groups endpoints into logical sections in OpenAPI.
- WithName β consistently defines the operationId.
- WithSummary β clearly describes the endpointβs purpose.
- Produces(statusCode, schema) β specifies status codes and response contracts.
- MapToApiVersion β allows exposing different versions of the same endpoint.
Requests and Responses
Record classes are used by default for Requests and Responses:
- They are immutable (reducing side effects and bugs).
- They are concise and easy to read.
Integration with CQRS:
- Requests received via endpoints are transformed into Commands or Queries.
- Results from Commands/Queries are converted into Responses, promoting architectural consistency.
Simplified example:
public record CreatePersonRequest(string Name, int Age);
public record CreatePersonResponse(Guid Id, string Name, int Age);
Creating New APIs
Creating an endpoint with the Lino CLI is simple:
lino new api
The interactive wizard will ask for:
- Service β the service in which the API will be created.
- Module β the module of the service (if applicable).
- Entity β the entity associated with the endpoint.
- API Name β usually aligned with the verb of the operation (e.g., CreatePerson).
- Operation Type β POST, PUT, PATCH, DELETE, or GET.
- Route β route pattern (e.g., /people/{id}).
Example:
When creating a POST API called CreatePerson associated with the Person entity, the CLI automatically generates:
- Endpoint with HTTP mapping.
- Request/Response DTOs.
- Extensions for OpenAPI integration and versioning.
- Typed HttpClient for internal use by other services.
Generated structure:
MyApp/
βββ src/
βββ Services/
β βββ MyService/
β βββ Presentation.API/
β βββ MyApp.MyService.Presentation.API.csproj
β βββ Endpoints/
β βββ People/
β βββ CreatePerson/
β βββ CreatePersonEndpoint.cs
β βββ CreatePersonExtensions.cs
β βββ CreatePersonRequest.cs
β βββ CreatePersonResponse.cs
βββ Integrations/
βββ MyService/
βββ Http/
βββ Contracts/
β βββ Apis/
β βββ People/
β βββ IPersonHttpClient.cs
β βββ CreatePerson/
β βββ CreatePersonRequest.cs
β βββ CreatePersonResponse.cs
βββ Clients/
βββ Apis/
βββ PersonHttpClient.cs
Endpoint Registration with Source Generators
Lino eliminates the need for manual endpoint mapping or heavy use of Reflection at runtime.
Instead, it uses Source Generators to automatically produce registration code during compilation.
How it works
For each created endpoint, the generator produces classes/partial classes that call:
MapGet, MapPost, MapPut, MapDelete, etc.
This replaces the need to manually add all mappings in Program.cs.
Advantages:
- Compile-time registration β avoids runtime errors.
- Lean Program.cs β smaller surface for manual configuration.
- AOT compatibility β removes Reflection dependency.
- Integrated documentation β metadata (tags, summary, produces) is generated along with the mapping.
This model ensures that APIs created in Lino are:
- Self-documented
- High-performance
- Consistent with the frameworkβs CQRS architecture
