apigenie-generatorOpenAPI serversserver aspnet
server aspnet
Generate an ASP.NET Core server in C#, built on Minimal APIs.
From an AsyncAPI document, the command generates an ASP.NET Core Kafka application instead; see apigenie-generator server aspnet (AsyncAPI).
Usage
apigenie-generator server aspnet [...OPTIONS] INPUT_FILE
Description
The input must be an OpenAPI 3.0, 3.1 or 3.2 document. Convert Swagger 2.0 documents with
apigenie convert, and bundle documents referencing other files
with apigenie bundle.
The generated project targets .NET 8 (or 9 and 10, see target_framework) and uses only the
shared framework, without NuGet packages:
PetStore.csproj
Program.cs the host, written only when missing
README.md
ApiRegistration.cs MapPetStoreApi(): maps the endpoints of all operations
Apis/IPetsApi.cs one interface per group of operations
Apis/PetsApi.cs its implementation, written only when missing
Endpoints/PetsEndpoints.cs routes, parameter binding, validation and metadata
Models/Pet.cs records and enums of the schemas
Infrastructure/*.cs helpers used by the generated code
Operations are grouped by their first tag (or by the first segment of their paths). Each group gets an interface whose methods return the responses of the operation as a union of typed results, so the compiler accepts only declared responses:
public interface IPetsApi
{
/// <summary>Find a pet</summary>
/// <remarks>GET /pets/{petId}</remarks>
Task<Results<Ok<Pet>, NotFound, GoneResult<Error>>> GetPet(long petId, CancellationToken cancellationToken);
}
Implementations return TypedResults.Ok(pet), TypedResults.NotFound() and the like. Statuses
without a TypedResults method (403, 410, 429, 500, …) have result types of their own, created
with ApiResults.Gone(error). All results describe their responses in the endpoint metadata, so
OpenAPI documents produced by ASP.NET Core match the input.
The endpoints bind parameters from the path, the query, headers and cookies, with the styles of the document (exploded or delimited arrays), JSON, text, binary, form and multipart bodies, and resolve the implementation from the services of the request:
var app = builder.Build();
app.MapPetStoreApi();
Models are records with required properties, System.Text.Json attributes and DataAnnotations
attributes for the constraints of the schemas (minimum, maxLength, pattern, format: email,
maxItems, …). An endpoint filter checks them, and the values of enums, before the
implementation is called, and answers invalid requests with 400 validation problem details.
oneOfandanyOfwith a discriminator become abstract records with[JsonPolymorphic]attributes, and their variants derive from them. On .NET 8, System.Text.Json reads the discriminator only as the first property of an object.allOfreferencing a schema with a discriminator becomes inheritance; otherallOfschemas are merged into one record.- String enums become C# enums whose converters read and write the values of the document, e.g.
in-progress. Integer enums keep their values. Thex-enum-varnamesextension names members. - Inline object and enum schemas get types named after their location, e.g.
PetOwnerfor theownerproperty ofPet. Identical inline schemas share a type. - Schemas whose names would clash with types of .NET (
Task,File,Environment, …) get aModelsuffix.
Operations with security requirements call RequireAuthorization(); configure the authentication
schemes in Program.cs, which lists the schemes of the document.
Not supported: oneOf and anyOf without a discriminator whose members have different types
(typed object; members of one type, e.g. strings of different formats, give that type), not,
if/then/else, separate request and response variants of models with readOnly and
writeOnly properties (such properties are optional), prefixItems, patternProperties,
multipleOf, dependentRequired, dependentSchemas, unevaluatedProperties, object query
parameters (deepObject, left out with a warning), parameters described by content (left out
with a warning), the deepObject encoding and the constraints of form fields, response headers,
more than one media type per response (JSON wins: no text/event-stream, JSON Lines or binary
alternatives), callbacks and webhooks, operation and path servers (every route is below the path
of the first server), and OAuth 2.0 scopes (operations only call RequireAuthorization() with the
default policy).
Extensions
| Extension | Effect |
|---|---|
x-apigenie.codegen.controller-name |
on an operation or its path item: the group (API interface) of the operation, whatever grouping says |
x-apigenie.codegen.action-name |
name of the method of an operation, when action_naming lists extension |
x-apigenie.codegen.disabled |
true on an operation or its path item leaves the operation out, unless skip_disabled is false |
x-internal |
true on an operation leaves it out |
x-enum-varnames, x-enum-names |
names of the members of an enum, in PascalCase |
x-enum-descriptions, x-enumDescriptions |
documentation comments of the members of an enum |
x-defaultMapping |
defaultMapping of a discriminator in OpenAPI 3.0 and 3.1 documents: the schema of the values whose discriminator value isn’t mapped |
The extensions can live in an overlay for this target instead of in the document, e.g.
aspnet.overlay.yaml:
overlay: 1.0.0
info:
title: ASP.NET names
version: 1.0.0
actions:
- target: $.components.schemas.PetStatus
update:
x-enum-varnames: [Available, OnHold, Sold]
- target: $.paths['/pets']
update:
x-apigenie:
codegen:
controller-name: Animals
apigenie-generator server aspnet openapi.yaml --overlay aspnet.overlay.yaml -o out
Options
-c, –config
Path to the configuration file to use. See the “Configuration” section for more information.
–overlay OVERLAY
Path to an OpenAPI Overlay (1.0 to 1.2) applied to the input before generating, e.g. one setting the
extensions of the “Extensions” section. Can be repeated: the overlays apply in order, after those
listed under commands.generate.server_aspnet.overlay in the configuration file (with paths
relative to it). Warnings and errors about a value an overlay set point to the overlay.
–strict
Makes an overlay action whose target selects nothing an error (exit status 2, nothing is generated)
instead of a warning (OVERLAY:LINE:COL: action #N (TARGET) selects no nodes.).
-o, –output
Directory where the project is generated.
–package-name
Root namespace of the generated code, e.g. Acme.PetStore; also the name of the project.
Defaults to the title of the API.
–package-version
Version of the project. Defaults to the version of the API when it’s a valid .NET version, or
1.0.0.
-p, –property NAME=VALUE
Sets an option (see below), e.g. -p layout=sources; can be repeated. Options given on the
command line take precedence over the configuration file. OpenAPI documents only: using it with an
AsyncAPI document is an error.
Configuration
The options are read from commands.generate.server_aspnet. Its asyncapi section configures
the generation from AsyncAPI documents (see
apigenie-generator server aspnet (AsyncAPI)).
version: '1.0'
commands:
generate:
server_aspnet:
namespace: Acme.PetStore
target_framework: net10.0
grouping: url
| Option | Values | Description |
|---|---|---|
layout |
project, sources |
project (default): a complete project (.csproj, Program.cs, README.md); sources: only the generated sources, for an existing project |
namespace |
namespace | Root namespace of the generated code (also --package-name); derived from the API title by default |
target_framework |
net8.0, net9.0, net10.0 |
Target framework of the project (default: net8.0) |
grouping |
tag, url |
Grouping of operations into API interfaces: by their first tag (default), or by the first segment of their paths |
action_naming |
id, extension, url |
Sources of method names, in order of preference (default: id, url) |
validation |
filter, none |
filter (default): an endpoint filter validates parameters and bodies against their DataAnnotations; none: attributes only |
authorization |
require, none |
require (default): operations with security requirements call RequireAuthorization(); none: no authorization metadata |
base_path |
servers, none |
servers (default): routes are prefixed with the path of the first server URL; none: no prefix |
program |
true, false |
Generate Program.cs and stub implementations of the API interfaces (written only when missing; default: true) |
skip_deprecated |
true, false |
Don’t generate deprecated operations (default: false) |
skip_disabled |
true, false |
Don’t generate operations disabled with the x-apigenie extension (default: true) |
model_suffix |
text | Suffix of model names, e.g. Dto |
version |
version | Version of the project (also --package-version); defaults to the version of the API |
Unknown options are errors.