<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Panos</title>
    <description>The latest articles on DEV Community by Panos (@zzpzaf).</description>
    <link>https://dev.to/zzpzaf</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F801322%2F6b65ef92-4c6c-431d-8bfb-7c6bd630a13f.jpeg</url>
      <title>DEV Community: Panos</title>
      <link>https://dev.to/zzpzaf</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/zzpzaf"/>
    <language>en</language>
    <item>
      <title>Step ahead fast, with NestJS environment configuration</title>
      <dc:creator>Panos</dc:creator>
      <pubDate>Wed, 26 Jan 2022 09:48:42 +0000</pubDate>
      <link>https://dev.to/zzpzaf/step-ahead-fast-with-nestjs-environment-configuration-4dpf</link>
      <guid>https://dev.to/zzpzaf/step-ahead-fast-with-nestjs-environment-configuration-4dpf</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8DCVV4Jk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4n2mldbsoyc8vdpkchcb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8DCVV4Jk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4n2mldbsoyc8vdpkchcb.png" alt="Image description" width="880" height="313"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Find how quickly you can start implementing your externally defined configuration settings in NestJS.&lt;/p&gt;

&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;You have probably spent some time working with the awesome NestJS framework and now it’s time to see how to get some externally defined values for your configuration settings like some key or global variables, e.g.:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;App listening port number&lt;/li&gt;
&lt;li&gt;API global route prefix&lt;/li&gt;
&lt;li&gt;JWT parameters (token secret, token expiration time, e.g. in seconds)&lt;/li&gt;
&lt;li&gt;Database connection parameters (type, host, port, username, password, database)&lt;/li&gt;
&lt;li&gt;etc.,&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://docs.nestjs.com"&gt;NestJS&lt;/a&gt; provides the necessary &lt;a href="https://docs.nestjs.com/techniques/configuration"&gt;documentation&lt;/a&gt; for working with different environments (development, production, etc.) using external configuration files and environment variables. So, if you have already taken a look there, then the below provided cases, will give you a hand to start implementing your (relatively simple) project as well.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NB&lt;/strong&gt;: It is supposed that you have already installed the &lt;a href="https://www.npmjs.com/package/@nestjs/config"&gt;@nestjs/config&lt;/a&gt; package for your project and it is also good if you have also installed the &lt;a href="https://www.npmjs.com/package/@nestjs/jwt"&gt;@nestjs/jwt&lt;/a&gt; package and started working with &lt;a href="https://jwt.io/"&gt;JSON Web tokens&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So, below you can find 3 of the most simple and common cases to use in your implementation(s).&lt;/p&gt;




&lt;h2&gt;
  
  
  The basics
&lt;/h2&gt;

&lt;p&gt;The .env.dev environment configuration file with defined properties and their values (like key/value pairs)&lt;/p&gt;

&lt;p&gt;The .env.dev&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;APP_PORT=3000
APP_GLOBAL_PREFIX=tickets
JWT_SECRET=abcdABCD1234554321
JWT_EXP=3600s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The scripts in the package.json file&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;. . .
    "start:dev": "STAGE=dev nest start --watch",
    "start:debug": "STAGE=debug nest start --debug --watch",
    "start:prod": "STAGE=prod node dist/main",
. . .
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;For instance, we can run the dev configuration in our terminal by&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm run start:dev&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Configuring the ConfigModule globally in the AppModule&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;.forRoot()&lt;br&gt;
This static method loads the environment variables in the ConfigModule, configures the ConfigService provider and makes it module-wide, and since this is the AppModule, it makes it available across the app.&lt;/p&gt;

&lt;p&gt;isGlobal&lt;br&gt;
We use the isGlobal property and we set it to true, so we can use the ConfigModule generally in our project without to have to import it in each one module separately.&lt;/p&gt;

&lt;p&gt;envFilePath&lt;br&gt;
We use the envFilePath property to load the environment variables from a file – we pass the full-path name of the file containing them.&lt;/p&gt;

&lt;p&gt;Now, it’s time to use the externally defined values (via the ConfigModule) in our project.&lt;/p&gt;


&lt;h2&gt;
  
  
  &lt;strong&gt;Using the ConfigService in a class/repo/service&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;First, we have to add it in the imports property array of the Module that this clas/property/service belongs to.&lt;/p&gt;

&lt;p&gt;First, we have to add it in the imports property array of the Module that this clas/property/service belongs to.&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;imports: [AuthModule, ConfigModule],&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Declaring (Importing) the ConfigModule in the UsersModule&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Note, that in our case, we have already set the ConfigModule for global use in our AppModule (i.e. we have set the isGlobal property to true), and thus, there is no need to import the ConfigModule in imports property array.&lt;/p&gt;

&lt;p&gt;Then, we have to inject it in the constructor of that class/repo/service:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;br&gt;
And finally, we can use it ‘normally’:&lt;br&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;





&lt;h2&gt;
  
  
  Using the ConfigService in the main.ts
&lt;/h2&gt;

&lt;p&gt;Since the main.ts contains just the bootstrap() function, we can get the ConfigService instance/context as a const, like that:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;const configService = app.get(ConfigService);&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;After that, we can use the get method of the instance, the normal way, e.g. for the application listening port:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;const appPort = configService.get&amp;lt;number&amp;gt;('APP_PORT', 3000); &lt;br&gt;
await app.listen(appPort);&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;As you can see (and as the official documentation states) “The get() method also takes an optional second argument defining a default value, which will be returned when the key doesn’t exist, as shown” above for the application listening port, for which the default value is 3000.&lt;/p&gt;

&lt;p&gt;The same we can do for any other key declared in an environment file.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;An example of a main.ts file&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;





&lt;h2&gt;
  
  
  Injecting and using the ConfigService in a dynamically imported module (that it is being imported in imports property array of a Module)
&lt;/h2&gt;

&lt;p&gt;This is for instance the case when we import the &lt;strong&gt;JwtModule&lt;/strong&gt; in another module, eg. in the Authorization module: &lt;strong&gt;AuthModule&lt;/strong&gt;. Below, is how we can import the &lt;strong&gt;JwtModule&lt;/strong&gt; and register directly the values of its parameters/properties: &lt;strong&gt;secret&lt;/strong&gt; and &lt;strong&gt;expiresIn&lt;/strong&gt; in &lt;strong&gt;signOptions&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A first hint here is to register the JwtModule Asynchronously, e.g.:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;JwtModule.registerAsync(. . .)&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;This is necessary because we have to read external files such as .env files asynchronously.&lt;/p&gt;

&lt;p&gt;Then, we have to add the ConfigModule in the inject property array. After that we can provide/inject the ConfigService instance dynamically, (and asynchronously), using the useFactory().&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;An example of a full version of the AuthModule&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;br&gt;
Again here, there is no need to also declare the ConfigModule in the modules property array, since we have already set the isGlobal: true in AppModule.




&lt;p&gt;That’s it!&lt;br&gt;
Thanks for reading and happy coding!&lt;/p&gt;

</description>
      <category>nestjs</category>
      <category>typescript</category>
      <category>configuration</category>
    </item>
  </channel>
</rss>
