
Спільні TypeScript-контракти між Angular і NestJS
- Angular
- NestJS
- TypeScript contracts
- OpenAPI
- API schema
- code generation
- backward compatibility

Спільні TypeScript-контракти між Angular і NestJS
Angular і NestJS використовують TypeScript, але це не робить internal models безпечним shared contract. Types зникають у runtime, HTTP серіалізує values, deployments відбуваються в різний час, а старий browser build може викликати новий API. Надійний contract визначає wire shape, semantics, validation і compatibility незалежно від implementation.
Практичні варіанти — малий shared package, generation з OpenAPI або schema-first source для runtime validators і static types. GARNO.TECH поєднує розробку Angular та розробку NestJS, обираючи strategy за repository ownership, release cadence, consumers і governance.
Поширюйте wire contract, а не implementation
Ніколи не експортуйте ORM entities до browser. Entities містять persistence columns, relations, lazy-loading behavior, audit fields і sensitive properties, зміни яких не мають ставати API changes. Backend decorators також можуть затягнути server-only dependencies у frontend build. Перетворюйте domain objects на явні request і response contracts на transport boundary.
Визначте required, optional і nullable fields, dates, timezones, money, identifiers, enum evolution, pagination та errors. Angular HttpClient generic є compile-time assertion, а не runtime validation. NestJS має валідувати input, а consumers — responses там, де цього потребує trust або independent change.
Використовуйте shared package у контрольованому monorepo
Shared package дієвий у monorepo або за контрольованого publishing. Залишайте його dependency-light і transport-only: primitive aliases, stable enum values, request/response shapes та framework-neutral schemas. Виключіть NestJS decorators, ORM models, repositories, domain services і frontend state.
Версіонуйте package як external dependency, тестуйте serialization examples і забороняйте deep imports. Одночасна зміна package та двох apps доводить лише сумісність newest versions. Тестуйте old consumer з new server і new consumer з кожним supported old server.
// packages/order-contracts/src/public.ts
export const orderStatuses = ["pending", "paid", "cancelled"] as const;
export type OrderStatus = (typeof orderStatuses)[number];
export interface OrderSummaryContract {
id: string;
status: OrderStatus;
totalMinor: number;
currency: string;
createdAt: string; // RFC 3339 on the wire
}
export interface OrdersPageContract {
items: readonly OrderSummaryContract[];
nextCursor?: string;
}
// Keep ORM entities and Angular view models elsewhere.Генеруйте clients з OpenAPI між repositories
OpenAPI є сильнішою boundary для кількох consumers, окремих repositories, інших мов або independent teams. NestJS генерує document із controllers і DTO, але reflection не бачить кожний interface, generic чи union. Використовуйте decorators, extra models або Swagger CLI plugin і перевіряйте artifact.
Публікуйте versioned specification, lint-те її, виявляйте breaking changes і repeatably генеруйте Angular client. Не редагуйте generated files. Сховайте transport за малим Angular service. Перевіряйте errors, authentication, content types, nullability та pagination.
npm --workspace api run export:openapi -- --output artifacts/openapi.json
# Fail CI on incompatible changes, then regenerate.
npx openapi-diff baseline/openapi.json artifacts/openapi.json --fail-on-incompatible
npx openapi-typescript artifacts/openapi.json
--output apps/web/src/generated/api-schema.ts
git diff --exit-code -- apps/web/src/generated/api-schema.tsОбирайте schema-first, коли веде runtime validation
Schema-first визначає executable schemas і виводить types. Він пасує runtime validation на обох сторонах, event payloads або framework-neutral governance. Переконайтеся, що conversion не втрачає OpenAPI та validation features. Schema не реалізує authorization, cross-field domain rules чи database invariants.
Не підтримуйте той самий payload у кількох незалежних definitions. Оберіть одне source of truth, генеруйте secondary artifacts, фіксуйте tool versions і тестуйте valid та invalid examples на кожній boundary. Generated types зменшують transcription errors, але не доводять semantic compatibility.
Версіонуйте contracts через compatibility rules
Надавайте перевагу additive changes. Додавання required request field, видалення чи перейменування field, зміна meaning або nullability, narrowing input чи повторне використання enum value є breaking. Enum additions також ламають exhaustive clients, тому визначте unknown-value behavior.
Застосовуйте expand-and-contract: server приймає old і new forms, consumers мігрують із telemetry, потім old form видаляється після support window. Semantic versions потрібні packages, HTTP versions — лише genuine breaks. Contract tests і production usage роблять removal доказовим.
Чекліст contract strategy
- Оберіть shared package, OpenAPI чи schema-first за repositories, consumers, runtime validation і releases.
- Не включайте entities, domain behavior, framework decorators і frontend state до wire contract.
- Явно визначте dates, money, identifiers, nullability, enums, pagination, errors та unknown fields.
- Генеруйте artifacts детерміновано та перевіряйте drift і breaking changes у CI.
- Тестуйте old/new consumer-server combinations і видаляйте deprecated shapes за usage evidence.
Чи може Angular імпортувати NestJS DTO classes?
Чи валідують TypeScript types API responses?
Чи завжди OpenAPI краща за shared package?
Чи compatible нове optional response field?
Наші дослідження
Дослідження та розробка рішень на основі штучного інтелекту для оптимізації бізнес-процесів і підвищення ефективності прийняття рішень.
Аналіз моделей машинного навчання для прогнозної аналітики у фінансовій сфері, електронній комерції та SaaS-платформах.
Дослідження технологій обробки природної мови та комп'ютерного зору для посилення автоматизації, персоналізації та підтримки клієнтів.


