Реліз Ditsmod v1.0.0!

Підписуйтеся на Telegram-канал «DOU #tech», щоб не пропустити нові технічні статті.

Реліз Ditsmod v1.0.0!

Після оголошення бети, додано нові фічі, які дуже суттєво покращили можливість розширювати Ditsmod. І оскільки це реліз стабільної версії, опишу тут всі головні особливості цього фреймворку.

Що являє собою Ditsmod

Ditsmod є Node.js веб-фреймворком, його назва складається із DI + TS + Mod, щоб підкреслити важливі складові: він має Dependency Injection, написаний на TypeScript, та спроектований для хорошої Модульності.

Мотивація для створення Ditsmod

Перед створенням Ditsmod я, звичайно ж, шукав готові рішення для моїх цілей. Найближчими по можливостям до Ditsmod є LoopBack v4 та NestJS v7, оскільки обидва ці фреймворки теж написані на TypeScript, мають DI та дозволяють писати модульні застосунки.

Більш зрілий і краще спроектований — це однозначно LoopBack. І хоча четверта його версія була повністю переписана з нуля на TypeScript, але швидкий огляд каже, що у нього є купа (непотрібного) коду для підтримки старих версій, а пустий застосунок з єдиним роутом для «Hello, World!» тупить страшно. Він більше, ніж удвічі повільніший навіть за ExpressJS.

Незважаючи на те, що за LoopBack стоять розробники IBM, цей фреймворк за довгу свою історію не завоював чомусь широкої популярності, за тиждень його скачують біля 40 тис. разів. Підозрюю що все це через те, що він є досить складним фреймворком, повільним, а Pull Requests з фічами на github фільтрують (в моїй теорії) як для ентерпрайзу.

NestJS значно популярніший, за тиждень його скачують біля 600 тис. разів. І хоча його архітектура містить досить суттєві недоліки, але він став популярним, мабуть в першу чергу, через сумісність із ExpressJS. Фани ExpressJS отримали можливість використовувати дуже відчутні переваги роботи з TypeScript, з Dependency Injection, можливість формувати значно кращу модульність своїх застосунків.

Але я не став використовувати і NestJS через наступні критичні (на мою думку) огріхи в його архітектурі:

  • його DI шукає інстанси по назві класів, а не по reference на ці класи;
  • відсутність із коробки підтримки вкладених роутів (коли у батьківському модулі створюється префікс, і усі дочірні модулі додають цей префікс до своїх роутів);
  • by default, інстанси контролерів створюються єдиний раз при першому запиті по конкретному роуті (а в документації немає чітких інструкцій із застереженнями, щоб розробники не створювали змінні на рівні класу в контролерах, тому дуже легко можна «прострілити собі ногу»);
  • експортовані провайдери не перевіряються на колізії, і це вносить непередбачуваність, бо один і той самий провайдер можуть експортувати два і більше модулі;
  • немає можливості підключати чи відключати модулі після старту вебсервера;
  • відсутня система розширень (чи плагінів).

Головні особливості Ditsmod v1.0.0

Вважаю, що на сьогоднішній день сукупність наступних фіч для Node.js фреймворку є унікальною:

  1. Ditsmod написаний на TypeScript (і під капотом немає ExpressJS чи Fastify).
  2. Модульна архітектура на декораторах.
  3. Має ієрархічний Dependency Injection, що дозволяє використовувати класи, а не їхні імена, у якості токена для пошуку.
  4. Чітко розмежовані масиви провайдерів для DI інжекторів на рівні застосунку, модуля, роута чи запиту.
  5. Вбудована підтримка вкладених маршрутів, типу /api/posts/:postId/comments/:commentId , де /api/posts/:postId — це префікс батьківського модуля, а comments/:commentId — це префікс дочірнього модуля.
  6. Перевірка на колізії при імпорті провайдерів. Ця фіча дозволяє виявляти ситуації, коли ви імпортуєте два або більше модулі, в яких експортуються провайдери з однаковим токеном.
  7. Підтримка гардів з параметрами (наприклад, щоб передати ролі користувачів).
  8. Підтримка HTTP-інтерсепторів (вони дуже схожі на middleware, але можуть використовувати DI).
  9. Підтримка мульти-провайдерів.
  10. Підтримка розширень, що можуть асинхронно ініціалізуватись, і що можуть залежати один від одного.
  11. Підтримка груп розширень, з можливістю указати «перед» або «після» якої групи ви хочете запустити свою групу розширень.
  12. Можливість динамічно додавати провайдери та роути у розширеннях.
  13. Можливість динамічно додавати та видаляти модулі після старту вебсервера, без необхідності рестарту. Причому якщо ви невдало підключите певний модуль, можна автоматично відкотитись до попереднього набору модулів. Такий відкат можна робити і неавтоматично, наприклад, якщо помилка сталась не під час підключення нового модуля, а пізніше.
  14. Має підтримку OpenAPI.
  15. Ditsmod — є одним із найшвидших серед Node.js-фреймворків, він навіть швидший за NestJS + Fastify, при умові, що інстанси контролерів створюються за кожним запитом, як і має бути (а не як є by default у NestJS).
👍НравитсяПонравилось3
В избранноеВ избранном2
LinkedIn
Допустимые теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Допустимые теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Хм, реліз NestJS v.8 відбувся майже 4 місяці тому, але я щось в гуглі сходу не знайшов згадки за це.

Може хтось має досвід міграції на цю версію, усе проходить гладко? Цікавить чи працює як очікувалось DI по референсам на класи, і чи RouterModule вже добре працює із префіксами на рівні модуля.

наступні критичні (на мою думку) огріхи в архітектурі NestJS:

— відсутність із коробки підтримки вкладених роутів;

Ну, это же не правда
ibb.co/G7p8YnT

— by default, інстанси контролерів створюються єдиний раз при першому запиті по конкретному роуті (а в документації немає чітких інструкцій із застереженнями, щоб розробники не створювали змінні на рівні класу в контролерах, тому дуже легко можна «прострілити собі ногу»);

Как и это
Лог во время запуска приложения:
ibb.co/3MW51Gv
Это поведение by default

Під «вкладеними роутами» мається на увазі щоб можна було один раз в батьківському модулі створити префікс, і щоб усі дочірні модулі вже додавали цей префікс автоматично. Ось автор NestJS відправляє користувачів до стороннього модуля, що вміє це робити github.com/nestjs/nest/issues/3316

Стосовно створення інстансів контролера, то ваші сервіси в конструкторі на це впливають (і ви очевидно про цю особливість навіть не знаєте). Створіть окремий контролер, додайте лог йому в конструктор і дивіться на результат.

Аа, про роуты понял о чём Вы. Родительские префиксы было бы неплохо иметь, согласен.

Насчёт контроллеров:

то ваші сервіси в конструкторі на це впливають

Вот без сервисов
ibb.co/DWndgk5
Всё так же

Ок, на вашій картинці я бачу один єдиний лог. Де там другий і наступні логи? Я ж якраз кажу, що він створюється єдиний раз...

Чого притихли, побачили про що я кажу за інстанси контролерів?

Щодо «вкладених роутів» зараз уточню у статті, що я маю на увазі.

Ви забули додати ключові слова:
#япіарюсь и #халява

Це більше реклама open source інструменту, а не мій «піар». Хоча, звичайно ж, рекрутери ще більше активізувались, це при тому що у моєму LinkedIn профілі чітко написано, що на даний момент роботи не шукаю.

Щодо «халява»... не зрозумів до чого тут це?

опенсорс — це те, в чому треба довго розбиратись, зроблено хто зна коли і ким, зазвичай погано документовано. А коли зроблено під свої потреби і для себе, і автор тут же роздає щастя, і може пояснити як що й до чого — це халява, «надобрать».

А піаром є все, і нічого в тому поганого нема, навпаки. Жирна ачівка. А от хороший рекрутер ніколи не питатиме, чи шукаєш ти роботу. Навряд чи в тебе пожиттєвий найм. Тому завжди є привід зробити пропозицію. Якщо вона дійсно є, а не тупий спам «ось вам лінк, клікайте»

Подписаться на комментарии