This is part of the presentation how to generate automatically models, runtime schemas and services from controllers and model classes in .net core web api for angular>22.x.x and react>19.x.x using Typewriter Unofficial Fork 4.9.0 (available for Visual Studio 2022, Rider and VS Code).
Classes, records and controllers taken into generation are marked with [GenerateFrontendType] from AdaskoTheBeAsT.Typewriter.Annotations (4.9.0).
All samples target net10.0 (sdk 10.0.100).
Reusable templates are kept in Angular and React folders, split by serializer (Newtonsoft.Json, System.Text.Json):
| Template | Output | Purpose |
|---|---|---|
models/_AutogeneratedModels.tst |
<Model>.ts |
interfaces, classes, enums and records |
models/_AutogeneratedRuntimeSchemas.tst |
<Model>.schema.ts |
runtime schemas built with @adaskothebeast/typewriter-schema |
models/_AutogeneratedRuntimeRegistry.tst |
typewriter-registry.ts |
single defineTypeRegistry map from .net full type name to schema |
services/_AutogeneratedServices.tst |
angular services / react api functions | typed http calls with schema validation |
React/*/services/_AutogeneratedTanStackQueryServices.tst |
<controller>.queries.ts |
useQuery / useMutation hooks for TanStack Query |
Model generation settings used in templates:
settings
.IncludeCurrentProject()
.IncludeReferencedProjects()
.UseStringLiteralCharacter('\'')
.DisableUtf8BomGeneration()
.UseDateLibrary(DateLibrary.Temporal)
.UseGuidType("Uint8Array")
.UseGuidInitializer("auto")
.UseDecimalType("Decimal")
.UseDecimalInitializer("auto")
;which means dates are emitted as Temporal types (@js-temporal/polyfill) and decimals as Decimal (decimal.js), both with automatically generated initializers.
The frontend clients consume the published Typewriter runtime packages at 10.0.2; no local checkout or TypeScript path mapping to date-interceptors is required.
| Client | Packages |
|---|---|
| Angular | @adaskothebeast/typewriter-http-angular, @adaskothebeast/typewriter-runtime, @adaskothebeast/typewriter-schema |
| React | @adaskothebeast/typewriter-http-fetch, @adaskothebeast/typewriter-runtime, @adaskothebeast/typewriter-schema |
The Angular generated services also serialize query parameters with HttpParamsProcessor 12.0.0 and its @adaskothebeast/http-params-processor-core peer dependency.
Each client has its own lockfile. Install its dependencies from the corresponding ClientApp directory:
yarn install --immutable- Angular sample
- Base class annotated with JsonDerivedType (for generator purposes discriminators are mixed string, number and nameof - which is string - normally you should use one convention) ComplexBaseModel.cs
- TypeScript autogenerated version ComplexBaseModel.ts
- Derived class ComplexAModel.cs
- TypeScript autogenerated version ComplexAModel.ts
- code for generating models
- runtime schema autogenerated version ComplexBaseModel.schema.ts generated by code for generating runtime schemas and registered in typewriter-registry.ts
- sample contains also enum and records generation
- Angular also contains automatic generation of service classes from controllers - by using code for generating services - generated services validate payloads with
withTypewriterRequestSchema/withTypewriterResponseSchemafrom@adaskothebeast/typewriter-http-angular
- React sample
- uses same ideas as in Angular sample ReactWebApiSample
- api functions are generated as
<controller>.api.tson top offetchJsonfrom@adaskothebeast/typewriter-http-fetch - additionally TanStack Query hooks are generated as
<controller>.queries.tsby code for generating TanStack Query services
To show new functionality with polymorphism https://devblogs.microsoft.com/dotnet/system-text-json-in-dotnet-7/#using-type-discriminators Please see in samples:
- Angular sample
- Base class annotated with JsonDerivedType (for generator purposes discriminators are mixed string, number and nameof - which is string - normally you should use one convention) ComplexBaseModel.cs
- TypeScript autogenerated version ComplexBaseModel.ts
- Derived class ComplexAModel.cs
- TypeScript autogenerated version ComplexAModel.ts
- code for generating models
- runtime schema autogenerated version ComplexBaseModel.schema.ts generated by code for generating runtime schemas and registered in typewriter-registry.ts
- sample contains also enum and records generation
- Angular also contains automatic generation of service classes from controllers - by using code for generating services
- React sample
- uses same ideas as in Angular sample ReactWebApiSample2
- api functions plus TanStack Query hooks are generated - see simple.queries.ts
Right now .net 10 allows to create nice dry web api. In version 2.x I used Andrew Lock template named NetEscapades.Templates described in blog post Removing the MVC Razor dependencies from the Web API template in ASP.NET Core. In 2.x small modification was needed to serve static files.
app.UseMvc();
app.UseDefaultFiles(); //added
app.UseStaticFiles(); //addedSwagger is served by Swashbuckle.AspNetCore 10.x - types moved from Microsoft.OpenApi.Models to Microsoft.OpenApi.
Angular v22.0.8, React v19.2.8, Nx v23.1.0, TypeScript v6.0.3, TanStack Query v5 install node v22.x LTS or newer
Basic set of npm packages
npm i -g typescript
npm i -g @angular/cli
npm i -g nx@latest
npm i -g jest
npm i -g npm-check-updatesYarn 4.17.1 is used as a package manager - it is pinned by packageManager field in package.json and enabled by corepack
corepack enableFrontend folder is created in main folder of webapi . For styles scss is used. App is setup without inline templates and styles
npx create-nx-workspace@latestFrontend project was geenrated using NRWL NX
Linting is configured with ESLint flat config (eslint.config.mjs) and typescript-eslint 8.x.
When you generate angular project regular way there is a way to use jest and testcafe based on article Use React tools for better Angular apps In article unit test karma/jasmine combo was replaced by Jest; E2e tests protractor was replaced by testcafe.
Build is based on excelent Cake project. script is located in cake folder and it is composed from two cake files:
- build.cake - main file which is aggregator of steps
- build.steps.cake - steps definitions Right now script is able to run frontend and backend compilation. In future description how to setup sonaqube will be added.
Due to fact that application can be deployed as a web site or as a web application, debugged etc. base tag in angular app can be set manually (and maintained which can be error prone). In sample base tag is autogenerated by following javascript.
(function () {
"use strict";
var r = document.location.href;
var i = r.indexOf("#");
if (i > 0) {
r = r.substring(0, i);
} else if (
r.length > 1 &&
r[r.length - 1] === "/" &&
r[r.length - 2] === "/"
) {
r = r.substring(0, r.length - 2);
}
if (r[r.length - 1] !== "/") {
r = r + "/";
}
document.write('<base href="' + r + '" />');
})();