ConfigService advantages over dotenv - javascript

Is there any advantages (or disadvantages) on using #NestJS/Config instead of using dotenv to retrieve envvar? In both cases I could create a class that is responsible for all envvars, but should I?
I know #NestJS/Config uses dotenv behind the curtains, but is there any reason why one should choose one over the other?

The two big advantages are the ability to use Joi or class-validator or whatever else you want as a schema validator to ensure you have your env values correct to begin with, before trying to access them at runtime and getting an error. Earlier feedback loop means fewer failures later on. The other big advantage is the use of DI meaning it's easier (usually) to mock the env variable value in your test cases, rather than having to assign to process.env itself. There's also slight speed improvements, as Nest caches the value so if you read it again you don't need to read from process.env, but other than that there's not too much to mention. If you don't want to use it, don't feel like you have to. There is also the disadvantage of not being able to use the ConfigService inside a decorator

My understanding is using #nestjs/config is easy for you to manage your config/envvars as a module in your project. So it can be easily swapped in different place:
e.g. if you need a different set of config for test, you don't have to actually modify your process.env.xxx or use a different .env file.
However if you do that, it requires all/most your other services to utilize this pattern as well. It wouldn't be so helpful if you have all your other service to be a pure function export.

Related

Calling internal nodes programmatically on CONNECT platform

When programmatically calling internal nodes on CONNECT platform, should you use the original path or is it okay to just use an alias? This question mainly refers to what the best practice would be, as aliases might introduce additional dependencies and may result in errors in the future.
well it really depends on what you want to do. 'aliasing' basically is a mechanism for dependency injection on CONNECT platform, meaning other packages will be able to replace some nodes with a specific alias silently, so that other nodes depending on that functionality will seamlessly be calling the 'injected' node.
to give an example, if you have something like '/firestore/insert', which is aliased by '/db/insert', then no other package can overwrite '/firestore/insert' path, but they can overwrite the alias on '/db/insert' path. so when you are making your call, if you make it directly to '/firestore/insert', it would definitely do the insert on firestore, while if you are making the call to '/db/insert', it would invoke the insert node on any database backend that is being used.
as a rule of thumb, it is always recommended to make calls to aliases so that you can take full advantage of the dependency injection system. however in some cases you might want finer control, in which case you can make your calls to the original path. in case of a package, this can get pretty tricky, as it might affect the internal workings of your package and you might want to not allow injection into that flow. however, consider the situation, and if it is not the case, i.e. if you can allow other packages to inject nodes into the flow of your package, then make your calls to the aliases. otherwise, make strict calls to the actual paths.

Using constant integers in front and back-end

Say I have the following constants defined in my back-end API:
User::USER_ROLE_NORMAL; // Equal to 0
User::USER_ROLE_ADMIN; // Equal to 1
In my back-end I can now make the following comparisons:
if($user->role == User::USER_ROLE_NORMAL)
What is the best practice for when I have to apply logic in my front-end? (where these constants are unknown)
It doesn't feel right to hard code the numbers in the front-end, like so:
if(ajaxData.role == 0)
For context: I need to apply logic in the front-end based to change layouts
As frontend and backend logics do not have to be necessarily (and should not be) coupled, the best approach here I think is to define those same constants in the frontend code. Bear in mind that the frontend code should always be in consonance with the API specifications.
The way you do it is up to you (many good alternatives can be found).
An (easy) approach could be with some global variables or using some kind of service if you're using some framework.
Something like:
const role {
USER_ROLE_NORMAL: 0,
USER_ROLE_ADMIN: 1,
};
Then you can use them as follow:
if(ajaxData.role == role.USER_ROLE_NORMAL) {}
Another option (not very used) is that you could create a service in the backend API which provides those values for the frontend to use it. So before the frontend code could use any value regarding to roles (for instance), a request must be made to the backend in order to get those constant values and save it in the frontend in order to use it in future operations.
You could also generate the content of the JS file with all constants using backend. In this way you manage those data in one place, which may be the benefit.
A first solution would be to create another file, for the frontend javascript to use, defining the constants. But this has a big disadvantage: you will have to make sure both files (frontend constants and backend constants) are the same. If you change one, you'll have to remember to change the other.
But firstly, note that this disadvantage also exists if you just hard-code the constants in the first place (this is terrible, and absolutely not an option).
The solution is to have an automated process (the so-called build step of development), that auto-generates the frontend constants file based on the backend constants file.
In javascript development, it's very common to have a build step: Webpack, Grunt, Gulp, etc... If you already have one of those, add to the build step a script that auto-generates the frontend constants file.
If you don't have a build step in your development process, this is a great time to start.

How to enforce dependency rules in javascript/typescript/webpack

Simply put, I need a way to restrict dependencies, much like you would with different projects (libraries) in java/c#. Friend or internal access modifiers if you will.
I'm toying with some ideas to do that (like creating loaders to ensure only allowed dependencies are used), but I can't imagine it hasn't been done before.
Of course, I'm talking about more than class encapsulation. My way right now would be to make modules only able to directly reference modules under their own folder structure or index files of other modules.
Is this really something no one ever needed?
You can use dependency cruiser to validate code base against your own rules based on regex literals. You can use it as part of your CI chain.
https://github.com/sverweij/dependency-cruiser
The eslint plugin for import statements may have some of what you are looking for. Specifically no-relative-parent-imports which allows you to error on any relative parent lookup (../).

Avoiding re-evaluation and dynamically unloading objects called with `require`

i'm studying how nodejs module system works.
I've found so far this literature:
https://nodejs.org/api/modules.html
http://fredkschott.com/post/2014/06/require-and-the-module-system/
http://www.bennadel.com/blog/2169-where-does-node-js-and-require-look-for-modules.htm
It helps me to understand a few points however is still have these questions:
If i have a expensive resource (let's say database pooling connection) inside a module, how can i make sure that by requiring the module again i am not re-evaluating the resource?
How can i dynamically unload a disposable resource once i already called the 'require' on it?
It's important because i have some scenarios that demands me to make sure that i have a single instance of database pool. because of this i'm exporting modules which are able to receive parameters instead of just require the expensive resource.
Any guidance is very appreciated.
Alon Salont has written an EXCELLENT guide to understanding exports in NodeJS (which is what you're accessing when you call require()) here:
http://bites.goodeggs.com/posts/export-this/#singleton
If you study the list of options for what a module can export, you'll see that the answer to your question depends on how the module is written. When you call require, NodeJS will look for the module loaded in its cache and return it if it already had it loaded elsewhere.
That means if you choose to export a Singleton pattern, are monkey-patching, or creating global objects (I recommend only the first one in your case), only ONE shared object will be created / will exist. Singleton patterns are good for things like database connections that you want to be shared by many modules. Although some argue that "injecting" these dependencies via a parent/caller is better, this is a philosophical view not shared by all, and singletons are widely used by software developers for shared-service tasks like this.
If you export a function, typically a constructor, require() will STILL return just one shared reference to that. However, in this case, the reference is to a function, not something the function returns. require() doesn't actually CALL the function for you, it just gives you a reference to it. To do any real work here, you must now call the function, and that means each module that requires this thing will have its own instance of whatever class the module provides. This pattern is the more traditional one where a class instance is desired / is the goal. Most NPM modules fit this category, although that doesn't mean a singleton is a bad idea in your case.

Using Angular, where should I store my constants?

This question has less to do with how to do something, but more about best practices and what do others do?
I have a few services where I am using some kind of an external API (in this case the session storage api in the browser), where I am reusing the same constant string, the name of the company and the application, let's call it "ACME.Storage.", and this I want to prepend at the start of every "key" string. I see my options as:
I can just reuse the string "ACME.Storage." in every call.
I can create a JavaScript function where I create a new storage object that is configured with "ACME.Storage." once. That way, "ACME.Storage." appears once in my code.
I can create a local variable ans store "ACME.Storage." in it, then reuse that. Again, the string literal appears only once in my code.
I can create a separate javascript object that I can share.
I can use an AngularJS "constant"
I can add as a field to the app of config file.
I can store it somewhere where localized literal strings (even though this particular string isn't localized) and get it through a translation service.
I'm leaning toward using the "constant" service 'cause it's the one that's easily injectable. My only concern is that it's less encapsulated than some of the other options.
Opinions on the best practice?
To expand upon what Whishler posted, you can (and probably should) use the Constant module that Angular provides. Complete docs are found here: http://docs.angularjs.org/api/ng/type/angular.Module. Services are a common place for constants, but the Constant modules get applied before other provide methods. Another option would be Value, but it does pretty much the same thing.
Generally, I put constants into a service.
Depending what I'm doing, I may create a service that does nothing but store related constants. Or I may add them to another service representing a 'model'.
I'll also add that JavaScript doesn't officially have constants; so unless you wrote some code--such as your own accessors--you're just dealing with a variable that could be changed during the execution.

Categories

Resources