I am using nestjs to build several small applications, in doing so I would quite like a class library in which all projects can reference to pass the classes from one project to another if they'd like to, or at least standardise the objects to a contract they must adhere to.
Is there a way to approach this where I have a single standalone collection of simplistic domain classes not bound to a specific nestjs project, without specific domain logic involved, moreover the structure of how something should look as opposed to what it does?
Sounds like a perfect use case for using a NestJS Monorepo with a library, or to use something like Nx and use a library from there. In both cases, you're creating a reusable set of code (usually interfaces or classes) to be used throughout different parts of your servers/applications.
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...
After doing a bit of research i found quite some information on how to generally develop NodeJS/docker based microservices. But i still wonder what would be a good approach to provide a common base for a collection of NodeJS microservices that already includes some dependencies and even some architecture/structure presets.
Requirements for every microservice that uses the microservice base would be:
include testing frameworks with execution entry points for every type of tests
update of the base should update every microservice that is dependent on it
use versions of technologies and frameworks defined in the base microservice
shared scripts/automation
Thanks for the help!
I was thinking of wrapping some custom code in external repositories that i could include inside the package.json, but that doesn’t seem to be the ideal solution yet.
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.
I have followed DDD guidelines to structure my project, I have Domain, Infrastructure, Application and Presentation layers.
I have also defined a cross-cutting project called Common. All other projects have dependency on Common.
One of the things that I need in Common project is my config/setting values. I have defined all solution wide settings in a DB table. The Common project reads the settings and any other project can access these settings through Common project...
How should Common project access the DB? Anywhere else in the solution, I use Infrastructure layer to read from DB, but if I reference Infrastructure in Common project, I would get circular dependency.
Should Common project have it's own DB Reader? Or putting all the config in the Common project was not the correct design at the first place?
The common package could be organized by feature. Here the IConfigProvider implementations would live in the same package as the interface.
E.g.
You could also consider global configuration as a supporting BC and implement the appropriate anti-corruption layer in each downstream context, where every context has it's own view and interpretation of such configuration.
Dependencies are always an interesting thing.
Since you haven't specified what languages/environments you are using and I have experience with C# I will use techniques and terminology related to strong typed OO languages like it.
Let's say that we will separate interface and implementation. I will use the c# notation that an interface begins with capital 'I' to make more clear what is an interface.
Your repositories are part of your domain. Lets say you have Account entity and you have AccountRepository for this entity.
What we will do is separate the interface for this repository from it's implementation. We will have IAccountRepository and a concrete implementation (maybe more than one, but this is very rare) for it: AccountRepository.
If we want to use SQL database we may have SQLAccountRepository. If we want to use MongoDB we may have MongoDBRepository. Both of these concrete repositories will implement the interface IAccountRepository.
IAccountRepository is part of your Domain, but the implementations (SQL, MongoDB etc.) are part of your Infrastructure layer as they will access external things (SQL server or MongoDB server in this example).
Your dependencies in this case will be 'Infrastructure -> Domain' not 'Domain -> Infrastructure'. This isolates your domain from the Infrastructure as the Infrastructure has reference to the Domain note vice versa.
By using interfaces your Domain only specifies what it needs not how it needs it.
If you apply the same idea you can define interfaces in your Common project for getting (and setting if necessary) settings (ISettingsProvider, IApplicationSettings etc.) and allow the Infrastructure that references Common to provide implementation for these interfaces (SQLSettingsProvider etc.)
You can use dependency injection, service locator or similar technique to bind implementations to interfaces.
I communicate with the server through jsons, which both in Nodejs and in Actionscript are objects (serialized through string).
Those objects I use in my client, by reading / modifying them and also creating secondary objects (from Classes) relative to what came from the server.
I have one of two options to design my client and I am stuck at deciding which of them is more flexible/futureproof.
Keep data as it comes, create many methods to modify the objects, keep secondary objects somewhere separate.
Convert the data into instances of classes where each class has its own group of methods instead of piling the methods in the same place.
Usually I go with 2 because OOP is delicious but going with 1 seems much simpler in terms of quantity.
I guess my problem is that I can't figure out if my client is basically a View (from MVC) where the server is the Control (also from MVC), or if my client and server are two independent / separate projects that communicate, and I should consider the client as a MVC project in itself.
I would appreciate your 2 cents.
From your question it's not clear what 1. and 2. differ but looks like 1. is tightly coupled while 2. has better separation of concerns.
It depends on your application. Do you need to create client heavy app with rich UI/UX elements, or maybe a mobile app where bandwidth is limited? If the answer is yes, then go with a second approach (2.): build your MVC like structure or use existing MV* libraries, like Ember, Angular, Backbone, Knockout, etc.
If you need SEO support and don't have much of fron-end code, then rendering on the server-side is still an option. Even with this approach ORM like Mongoose can come in handy.
PS: JavaScript doesn't really have classes, because objects inherit from other objects. You can use prorotypal inheritance patterns for that.