I'm making a new NestJS app and after a lot of errors on the first because the multiple modules I created didn't have the correct imports, providers, exports, TypeOrmModule.forFeature etc made me wonder: What was the point?
Why not use only the app.module and just dump everything in it? All the controllers and services and entity types and any other that may come up?
From the documentation:
We want to emphasize that modules are strongly recommended as an
effective way to organize your components
Is that the only reason? Organization?
Does dependency injection play a role of some kind?
Edit:
If organization is the main reason, why not separate in a different folder with a controller and service? Basically a module without the imports, providers etc. Doing the same thing with less boilerplate.
Why not use only the app.module and just dump everything in it?
Better yet, why use multiple files at all? Why not just have a couple thousand line index.js with no types, no organization, just raw JS all the way down?
The answer? Code organization and ease of re-use. By making these modules, you should be grouping together similar logic together. All the code for a single feature should be available by just importing FeatureModule and usable. When it comes to library modules, this becomes pretty apparent: TypeOrmModule has a forRoot/forRootAsync and a forFeature which exposes ways to inject repositories into your services. The JwtModule has a register/registerAsync and exposes a JwtService so you can configure the JwtService once and re-use the provider.
When dealing with entity features this may look messier, but technically it's all still possible, so that in theory you'd be able to take FeatureModule from Application A and drop it into Application B and have everything still working with regards to the FeatureModule, similar to how pulumi has the idea of stacks and applications and you can just spin up new applications using the same group of components.
The module system, once you get the hang of it, and in my opinion, makes it very easy to recognize what all a module will be working with, with regards to other features and how they're connected. It's just a matter of discipline and learning the feature of the framework.
Related
I just started to use i18next in my monorepo (new to it), which has several serverside microservices and a couple of frontends, including several custom library components. Many of the language strings are shared, and some are app specific. I could not decide on a logical way to approach the problem.
Tooling: Typescript - Node/Express - React/Vite - Electron/React (Desktop)
Firstly, questions:
Where should I keep the language resources during development? In another library? App in monorepo? Under each library module?
From where should I serve them? Something like lang.mydomain.com? Re-dividing them under each app during build (e.g. with Vite)?
All examples/tutorials I could reach use a single app and use i18next.js/ts to be included at the app level. I think I need to wrap it into a library module for my purposes. How can I do that, without losing access to its capabilities/types/methods etc? Dynamically creating instances in a higher-order module (the library is extensive, and I'm nearly lost)?
My initial thoughts:
As many translations will be shared, translating each one will be illogical, they should be shared.
As there can be many languages, it seems using i18next-http-backend is logical for web and embed with i18next-fs-backend for desktop app.
Dividing the resources as common/graphs/tables/ui etc will be logical (these will be divided in a library module hierarchy though).
A logical way can be to include a module's language resources in the module but that would not help translators, they should be at the same place at the top level in this respect.
PS: I used to use react-intl-universal, it is really easy, but it's release schedule is falling back.
Thank you in advance...
I come from express.js background and pretty new to loopback framework, especially loopback4 which i am using for my current project. I have gone through the loopback4 documentation few times and got some good progress in setting up the project. As the project is running as expected, I am not much convinced with project structure, Please help me to solve below problem,
As per docs, database operations should be in repositories and routes should be in controllers. Now suppose, My API consist lots of business logic along with database operations say thousand of lines. Which makes controllers routes difficult to maintain. More difficulty would arise, if some API demands version upgrade.
Is there any way to organise the code in controllers in more
scalable and reusable manner? What if i add one more service layer
between controllers and repositories and put business logic there?
how to implement it in the correct way? Is there any official way to
do that which is suggested by loopback community only?
Thanks in advance!!
Is there any way to organise the code in controllers in more scalable and reusable manner?
Yes, services can be used to abstract complex logic into its own separate class(es). Once defined, the service can be injected into the dependent controller(s) which can then call the respective service functions.
How the service is designed is dependent on the user requirements as LoopBack 4 does not necessarily enforce a strict design requirement.
I am trying to understand what the purpose of injecting service providers into a NestJS controller? The documentation here explains here how to use them, that's not the issue here: https://docs.nestjs.com/providers
What I am trying to understand is, in most traditional web applications regardless of platform, a lot of the logic that would go into a NestJS service would otherwise just normally go right into a controller. Why did NestJS decide to move the provider into its own class/abstraction? What is the design advantages gained here for the developer?
Nest draws inspiration from Angular which in turn drew inspiration from enterprise application frameworks like .NET and Java Spring Boot. In these frameworks, the biggest concerns are ideas called Separation of Concern (SoC) and the Single Responsibility Principle (SRP), which means that each class deal with a specific function, and for the most part it can do it without really knowing much about other parts of the application (which leads to loosely coupled design patterns).
You could, if you wanted, put all of your business logic in a controller and call it a day. After all, that would be the easy thing to do, right? But what about testing? You'll need to send in a full request object for each functionality you want to test. You could then make a request factory that makes theses requests for you so it's easier to test, but now you're also looking at needing to test the factory to make sure it is producing correctly (so now you're testing your test code). If you broke apart the controller and the service, the controller could be tested that it just returns whatever the service returns and that's that. Then he service can have a specific input (like from the #Body() decorator in NestJS) and have a much easier input to work with an test.
By splitting the code up, the developer gains flexibility in maintenance, testing, and some autonomy if you are on a team and have interfaces set up so you know what kind of architecture you'll be getting from an injected service without needing to know how the service works in the first place. However, if you still aren't convinced you can also read up on Module Programming, Coupling, and Inversion of Control
From Puppet Best Practices:
The Puppet Labs documentation describes modules as self-contained bundles of code and data.
Ok it's clear.
A single module can easily manage a single application.
So, puppetlabs-apache manages Apache only, puppetlabs-mysql manages MySQL only.
.... So, my module my_company-mediawiki manages Mediawiki only (i suppose... with database and virtual host... because a module is self-contained bundles of code and data).
Modules are most effective when the serve a single purpose, limit dependencies, and concern themselves only with managing system state relating to their named purpose.
But my_company-mediawiki needs to depend by:
puppetlabs-mysql: to create database;
puppetlabs-apache: to manage a virtual host.
And... from a rapid search I understand that many modules refer to other modules.
But...
They provide complete functionality without creating dependencies on any other modules, and can be combined as needed to build different application stacks.
Ok, a good module is self-contained and has no dependencies.
So I have to necessarily use the pattern roles and profiles to accomplish these best practices? Or I'm confused...
The Puppet documentation's description of modules as self-contained is more aspirational than definitive. Don't read too much into it, or into others' echoes of it. Modules are quite simply Puppet's next level of code organization above classes and defined types, incorporating also plug-ins and owned data.
Plenty of low-level modules indeed have no cross-module dependencies, but such dependencies inescapably arise when you start forming aggregations at a level between that and whole node configurations. There is nothing inherently wrong with that. The Roles & Profiles pattern is a good way to structure such aggregations, but it is not the only way, and in any case it does not avoid cross-module dependencies because role and profile classes, like any other, should themselves belong to modules.
My application structure consist of few parts. Public API, Admin API, Admin Console (GUI), Private API, Auth API (oauth2, local, socials), etc. They kinda different each to other, but using the same models. Some routes going to have high number of requests per second and couldn't be cached.
I'm interesting in best practices to split everything properly. I'm also opened to another frameworks or even io.js.
Right now I got 3 variants:
Create separate apps.
Group controllers by folders, and find a way to group routes.
Create another instance of sails app and run it into another process (So I can have all controllers, models, but how should I organize subapp structure using this way?)
I think most answers will be opinionated, but putting controllers into subfolders is the easiest way to share models. (easiest but not only)
And you can easily run policies based on those subfolders as well.
However you really need to flesh out more aspects of your question and think about if there will be more shared (like templates or assets) than different or if differences would prohibit a shared app. Will they all use sessions or will they even use the same sessions.
In the end, based on your limited question, sails can do what you want.