NestJS vs. Ditsmod: features of the router
Tags: nestjs, ditsmod, node
Published: 2022-12-02 02:40:21

The description of NestJS specifically states that this framework was designed for "scalable server-side applications". Surprisingly, only in the eighth version it began to support prefixes at the module level, and this feature has a number of significant limitations.

> In this post, NestJS v9.2 and Ditsmod v2.27 are used for comparison. A finished example with nested routes in Ditsmod can be viewed on [github][1]. I am the author of [Ditsmod][2].

In addition to the slow implementation of nested routes in NestJS, its router even now (in the ninth version) does not care about collisions of path in routes. If you are writing a large project and accidentally duplicated a path, the NestJS router will not tell you anything about it. Likewise, it won't say anything if you accidentally duplicated the parameter name: `one/:two/:two`. It's especially easy to make such duplicates when you use third-party modules. Although this is how the Express router works, NestJS could fix this if it positions itself as a framework for "scalable server-side applications".

Currently, NestJS does not support the ability to import a module while simultaneously [adding guards to routes of this module][3]. This feature can also be very useful in large projects, especially for importing third-party modules.

Unlike NestJS, [Ditsmod][2] has been able to add prefixes at the module level since the first version. For example, to serve `/posts/:postId`, the parent module is imported as follows:

```ts
import { rootModule } from '@ditsmod/core';
import { PostsModule } from './posts/posts.module';

@rootModule({
  appends: [
    { path: 'posts/:postId', module: PostsModule }
    // ..
  ],
})
export class AppModule {}
```

And to import the child module serving `/posts/:postId/comments/:commentId`, in Ditsmod it is done as follows:

```ts
import { featureModule } from '@ditsmod/core';
import { CommentsModule } from './comments/comments.module';

@featureModule({
  appends: [{ path: 'comments/:commentId', module: CommentsModule }],
  // ...
})
export class PostsModule {}
```

In Ditsmod, `appends` is a lightweight version of `imports` that only allows you to appending modules, inheriting only the prefix of the current module. No providers or [extensions][7] are imported in this case.

Starting with the eighth version, NestJS can create nested routes in a similar way:

```ts
@featureModule({
  imports: [
    PostsModule,
    CommentsModule,
    RouterModule.register([
      {
        path: 'posts',
        module: PostsModule,
        children: [
          {
            path: ':postId/comments/:commentId',
            module: CommentsModule
          },
        ]
      },
    ]),
  ],
  // ...
})
export class AppModule {}
```

But there are [the following limitations][6]:

- Such configuration import can be done only once for the entire application.
- If imported modules have no controllers, all controllers from their child modules are ignored. That is, if there are no controllers in `PostsModule` from the previous example, then all controllers from `CommentsModule` will be ignored.
- In this case, it is not enough that you pass `PostsModule` and `CommentsModule` to the `RouterModule.register()` method, you also need to directly pass them to the `imports` array of `AppModule` data. Moreover, if you do not make such an import, NestJS will not tell you anything about it, but routes from imported modules will not work.

These limitations very significantly reduce the possibility of scaling projects, their modularity.

## Conclusion

Statistics show that currently NestJS is downloaded about 1.8 million times per week, which shows how much developers like this framework. NestJS took many concepts from Angular. Likewise, many concepts from Angular were taken to design Ditsmod. As the author of Ditsmod, I may not always be objective, but I try to criticize NestJS constructively. If you have anything to add to this criticism, please do so in the comments.

[1]: https://github.com/ditsmod/ditsmod/tree/main/examples/05-nested-routes
[2]: https://ditsmod.github.io/en/
[3]: https://github.com/nestjs/nest/issues/7193
[6]: https://github.com/nestjs/nest/issues/8364
[7]: https://ditsmod.github.io/en/components-of-ditsmod-app/extensions