Въведение
Здравейте, момчета!
В момента работя върху рамката TypeScript от страната на сървъра. Моят екип вече широко използва тази рамка в различни проекти за електронна търговия и ERP. Структурата и семантиката са вдъхновени от други популярни рамки като Spring и ASP.NET.
Списък на основните цели:
- Тестваем, поддържаем, мащабируем
- Минималистичен, идиоматичен, ясен
- Интуитивен, четим, разбираем
- Мощен
В момента има много възможности:
- Описване на маршрутизиране с помощта на контролери и декоратори
- Мощно, пълно типизирано инжектиране на зависимости
- Валидиране на входящи данни (с помощта на AJV) с различен набор от декоратори
- Интегриране на TypeORM (Инжектиране на хранилища, поддръжка на транзакции чрез CLS)
- Разширяемо JWT базирано удостоверяване
Всички части на рамката са напълно типизирани и интегрирани с цялата инфраструктура.
За най-добра производителност под капака се използва Fastify. Рамката е декларативна, но също така избягва използването на декоратори, ако е възможно. Така че всичко е просто, чисто и минималистично.
Преглед
Контролер
Контролерите служат като прост, но мощен механизъм за маршрутизиране в минималистичен стил.
@Controller('foo') export class FooController extends IController { @RoutePatch('{id}') bar(id: string, payload: FooDTO) { ...some updates.. return Ok(); }
@Get index() { return 'Foo'; } }
Така че, както виждате, няма нужда да предоставяте допълнителни декоратори на параметри за инжектиране на данни от HTTP заявката. Това е само малък преглед на контролера, има много други възможности. Можете да прочетете повече в docs.
Инжектиране на зависимост
Odi разполага с мощен механизъм за инжектиране на зависимост. (Нека си представим, че вече имаме FooRepository
)
//foo.service.ts @Service() export class FooService { @Autowired() repository: FooRepository; public getFoo(id: string) { return this.repository.findOne(id); } }
//foo.controller.ts @Controller('foo') export class OrderController extends IController { @Autowired() fooService: OrderService; @Get async '{id}' (id: string) { const foo = this.fooService.getFoo(id); if(!foo) return NotFound();
return foo; } }
Както можете да видите, всички зависимости ще бъдат автоматично предоставени на всички компоненти на приложението.
В момента Odi поддържа 3 начина на инжектиране:
- По конструктор
- По собственост
- По метод
Класове, които не са компоненти на Odi, могат да участват в DI. Можете просто да дефинирате поведение с предварително зададени свойства и аргументи на конструктора.
class Pet { ... }
define(Pet) .set('default', { constructorArgs: [...], props: {...}, type: 'singleton' }) .set('special', { constructorArgs: [...], props: {...}, type: 'scoped' });
DTO
Често срещан сценарий е, когато уеб сървърът трябва да потвърди данните преди обработката. DTO може да оптимизира и автоматизира този процес.
@Data()
export class TodoDTO {
@MaxLength(80)
title: string;
@IsOptional()
@MaxLength(255)
esctiption: string;
}
След това трябва да се добави DTO клас като аргумент за метода на контролера
@Controller('todo')
export class TodoController extends IController {
@Autowired()
todoService: TodoService;
@Post async index(payload: TodoDTO) {
...
}
}
И това е всичко! Odi автоматично ще инжектира потвърденото тяло на заявката в този аргумент. Ако има някои грешки по време на валидирането, ще бъде изпратен код за състояние 400 с описание на грешките.
Odi предоставя широк набор за описание на DTO, поддържащ вложени DTO, масиви, enum и др.
Да обобщим
Това беше малък преглед на някои функции. Ако се интересувате от повече, проверете Документи.
Очаквайте скоро
- AOP
- GRPC интеграция
- GraphQL
- CLI
- OpenAPI
- и още…
Връзки
Също така, ние се стремим да поддържаме Deno в бъдеще.
Разлика между Nestjs
По принцип има само няколко общи неща с Nestjs: MVC шаблон и декларативен стил. Но има много разлики, като цялата инфраструктура, използваните декоратори, инжектирането на зависимости и много други. За да обобщим разликите:
- Nestjs използва усилено декоратори, Odi намалява това използване до минимум (за да поддържа кода чист и четим).
- Odi предоставя вградено валидиране извън кутията за HTTP данни чрез AJV.
- Поведението на DI/IoT е много различно. В Odi има много повече магия, с няколко думи :)
- Удостоверяване от кутията, което е напълно интегрирано с други рамкови модули.
- Контролер и обработка на WebSockets
В бъдеще това ще бъде голямата разлика между всички интеграции и технологии, тъй като Odi е проектиран от самото начало по начин, различен от Nest.
Според мен Nestjs е повече за Spring, но нашата рамка е повече ASP :)
P.S
От самото начало рамката беше проектирана като отворен код. Наистина се нуждая от вашето мнение, много е важно за мен! Освен това, ако ви харесва идеята, оставете звездата в GitHub repo, моля :)