Въведение

Здравейте, момчета!

В момента работя върху рамката TypeScript от страната на сървъра. Моят екип вече широко използва тази рамка в различни проекти за електронна търговия и ERP. Структурата и семантиката са вдъхновени от други популярни рамки като Spring и ASP.NET.

Списък на основните цели:

  1. Тестваем, поддържаем, мащабируем
  2. Минималистичен, идиоматичен, ясен
  3. Интуитивен, четим, разбираем
  4. Мощен

В момента има много възможности:

  1. Описване на маршрутизиране с помощта на контролери и декоратори
  2. Мощно, пълно типизирано инжектиране на зависимости
  3. Валидиране на входящи данни (с помощта на AJV) с различен набор от декоратори
  4. Интегриране на TypeORM (Инжектиране на хранилища, поддръжка на транзакции чрез CLS)
  5. Разширяемо 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 и др.

Да обобщим

Това беше малък преглед на някои функции. Ако се интересувате от повече, проверете Документи.

Очаквайте скоро

  1. AOP
  2. GRPC интеграция
  3. GraphQL
  4. CLI
  5. OpenAPI
  6. и още…

Връзки

  1. GitHub
  2. Документи

Също така, ние се стремим да поддържаме Deno в бъдеще.

Разлика между Nestjs

По принцип има само няколко общи неща с Nestjs: MVC шаблон и декларативен стил. Но има много разлики, като цялата инфраструктура, използваните декоратори, инжектирането на зависимости и много други. За да обобщим разликите:

  • Nestjs използва усилено декоратори, Odi намалява това използване до минимум (за да поддържа кода чист и четим).
  • Odi предоставя вградено валидиране извън кутията за HTTP данни чрез AJV.
  • Поведението на DI/IoT е много различно. В Odi има много повече магия, с няколко думи :)
  • Удостоверяване от кутията, което е напълно интегрирано с други рамкови модули.
  • Контролер и обработка на WebSockets

В бъдеще това ще бъде голямата разлика между всички интеграции и технологии, тъй като Odi е проектиран от самото начало по начин, различен от Nest.

Според мен Nestjs е повече за Spring, но нашата рамка е повече ASP :)

P.S

От самото начало рамката беше проектирана като отворен код. Наистина се нуждая от вашето мнение, много е важно за мен! Освен това, ако ви харесва идеята, оставете звездата в GitHub repo, моля :)