angular-architects / nx-ddd-plugin

Nx plugin for structuring a monorepo with domains and layers
313 stars 56 forks source link

Feature Request > NestJS/Universal schematics #21

Open wSedlacek opened 4 years ago

wSedlacek commented 4 years ago

When working in monorepos one of the biggest benefits is sharing code between multiple applications. This is particularly useful when you have backend and front end that can share an interface as a sort of contract between the two.

NestJS by design is extremely similar to Angular in architecture and I believe Domain Driven Design would be very appropriate for it.

There are three challenges I would like to see a NestJS feature tackle.

  1. Code Organization. In the current model we use the libs folder as a list of domains. This may become disorganized if libraries are created that are not domains like api-interfaces. I would like to see some thought given to a pattern that would keep things organized and for the schematics to follow that pattern and for it to be documented in the README.md.

  2. NestJS Schematics. This one is pretty simple, I would like to see NestJS schematics added to generate domains and features specific for NestJS.

  3. Universal Schematics. I would like to see schematics added that would allow a domain to be consumed either by Angular or by NestJS. Of course the features in that domain will need to be either Angular or NestJS specific but it would be nice to keep a universal domain with two entry points.

One more thing could be added to push this to the next level, automatically tagging generated libraries. This would be very useful for restricting imports from Angular to NestJS and vice versa.

Given the naming of this library @angular-architects this feature request very well may be out of scope, however given the request for Universal Schematics, I don't believe a new library focused around NestJS domain driven design would be appropriate either. I would really like some feedback on this whole idea @manfredsteyer. I would be happy to contribute in anyway I can.

johannesschobel commented 3 years ago

Dear @wSedlacek and @manfredsteyer , this is a very good idea - i was just browsing the library for the exact same idea. Is it possible to apply the DDD principles to a nestjs application? Are there any prebuilt schematics? What are best practices to structure the api (i.e., nestjs application) for ddd purposes?

All the best

benpsnyder commented 3 years ago

Also very interested!

benpsnyder commented 3 years ago

@wSedlacek, @johannesschobel, @manfredsteyer @johannesschobel, @pascalbe-dev, @peterbsmith2 -- ready to assign some of my developers to code/implement this but we need help deciding on folder/library architecture and principles. The best article I have found so far for inspiration is https://medium.com/better-programming/onion-architecture-with-nest-js-and-nx-d9b5c7126b37 ... and I just implemented #35 ... and we have major projects kicking off within the next 2 weeks and I want to design the angular and nestjs library structures in the best way possible using DDD principles. So please put your best thoughts/suggestions down here and we'll take it under consideration when coding! Otherwise, I am going to go with the best approach that I can think of on my own.

wSedlacek commented 3 years ago

@benpsnyder That's probably the most challenging part of this request. Well that and handling multiple entry points on universal modules, one for Angular and one for NestJS.

I would take this request in chunks starting with the MVP of a folder structure for a feature/domain for NestJS specific modules.

Then during a second pass building schematics.

And in a third pass designing a pattern for handling multiple entry points to avoid polluting your Angular's project with NestJS packages. This part may benefit from something like dependency injection for what Module \ NgModule and Service to decorator use. Something to be mindful of is that buildable libraries are particular about their package name matching the import.

For handling the entry points I would take inspiration from how NestJS packages internally dynamically import modules so they can be optional dependencies.

What ever your team accomplishes be sure to share what you learn!

I'm personally working on a project that uses React and Angular together using DDD and in some ways this is simpler since I simply construct my services in the module they are exported from then either add them to the providers in my shared Angular module (or a feature module) or add them to a context in React.

benpsnyder commented 3 years ago

@wSedlacek thank you for the response. For now we implemented #35 which will allow us to run a command such as

nx generate @angular-architects/ddd:domain --name=accounting --addApp --appsDirectory=portal --libsDirectory=frontend --ngrx

This would produce directory structures such as:

apps/portal/accounting/src/app/app.component.ts
libs/accounting/frontend/domain/src/lib/accounting-frontend-domain.module.ts

Next I plan on introducing NestJS schematics that will produce such a directory structure:

libs/accounting/backend/domain/src/lib/accounting-backend-domain.module.ts

For now this can be achieved using @nrwl/nest schematics

nx generate @nrwl/nest:library --name=domain --directory=accounting/backend --no-interactive

Working on this as fast as I can... we are keeping it simple on the first implementation. Merging this all under a single directory without segregating by "backend" and "frontend" will take time and thought ... and I have projects starting soon so I need to do this quickly, in such a way that perhaps we can migrate it later.

wSedlacek commented 3 years ago

@wSedlacek thank you for the response. For now we implemented #35 which will allow us to run a command such as

ng generate @angular-architects/ddd:domain --name=accounting --addApp --appsDirectory=portal --libsDirectory=frontend --ngrx

This would produce directory structures such as:

apps/portal/accounting/src/app/app.component.ts
libs/accounting/frontend/domain/src/lib/accounting-frontend-domain.module.ts

Next I plan on introducing NestJS schematics that will produce such a directory structure:

libs/accounting/backend/domain/src/lib/accounting-backend-domain.module.ts

For now this can be achieved using @nrwl/nest schematics

nx generate @nrwl/nest:library --name=domain --directory=accounting/backend --no-interactive

Working on this as fast as I can... we are keeping it simple on the first implementation. Merging this all under a single directory without segregating by "backend" and "frontend" will take time and thought ... and I have projects starting soon so I need to do this quickly, in such a way that perhaps we can migrate it later.

I am not quite sure how I feel about having the platform under domain name, but splitting the actual domain module by platform.

This feels like duplication to me. I would much rather the domain itself either being specifically frontend, backend or universal. It would be useful if these were tagged in nx.json and linting rules prevented importing modules that were not valid for the platform.

manfredsteyer commented 3 years ago

That would be a very cool PR.

markush97 commented 3 years ago

That would be a very cool PR.

  • It would be even cooler if we could use this to generate End2End CRUD forms

Just checking in if anybody as information about an ongoing PR? Otherwise I would like to start working on one. Is there a folder-structure in place? Don´t want to do any duplicate work :)

Otherwise I would introduce a new level with something like app/domain/feature so so you could have

api/customer/search and web/customer/search