Environment Variables and their Validation
In this lesson, we'll learn how we can securely store sensitive and environment-based variables using our .env file. We'll also learn how AdonisJS adds type-safety to these variables using our env.ts file as validation.
- Author
- Tom Gobich
- Published
- Feb 04
- Duration
- 4m 16s
Developer, dog lover, and burrito eater. Currently teaching AdonisJS, a fully featured NodeJS framework, and running Adocasts where I post new lessons weekly. Professionally, I work with JavaScript, .Net C#, and SQL Server.
Adocasts
Burlington, KY
Transcript
Environment Variables and their Validation
-
[music]
-
So although our cache service works as intended,
-
it's storing information in memory for at least the duration of our server's lifetime,
-
there is a better, more scalable option that we can utilize instead called Redis.
-
And AdonisJS has first-party support for Redis.
-
Now, Redis has a server of its own,
-
so we're going to need to connect to it through our AdonisJS application.
-
And in order to do that, we're going to need a way to set connection details
-
based on the environment with which we're in.
-
For that purpose, environment variables exist,
-
and you can find them within your .env file within your application.
-
If we click into this right now, it's going to be a very bare-bones list
-
of key-value pairs that we have in this .env style syntax.
-
You have the key on the left-hand side of the equals,
-
and then you have the value on the right-hand side of the equals.
-
Now, as you can see, so far within this file,
-
we have basic information about the specific environment that we're running within.
-
We have the host that our application is running on,
-
the desired port that our application should run on,
-
the time zone, log information, the environment itself.
-
So these are all variables that could be different
-
depending on the specific environment that our application is running on.
-
It could be something on my computer and something entirely different on yours, for example.
-
And for a fact, the node.env will definitely be switched to production
-
whenever our application is out running on our production server.
-
In addition to just being environment-specific, they also hold secrets.
-
For example, our app key is a secret that we don't want people to know
-
because it's used by the encryption module to sign our encrypted values.
-
So if you ever have anything that is environment-specific
-
or a secret that you don't want to be shared with anybody else,
-
the environment variables is the place that you want to put it.
-
Now, in addition to this key-value pair here,
-
AdonisJS also provides type safety for this via the env.ts
-
that we saw earlier within our start directory.
-
This is going to define what we expect to be within the .env.
-
And if AdonisJS finds anything within the .env file declaration
-
that doesn't match our literal .env file, it will fail to boot our application.
-
For example, let's go ahead and dive into our terminal, stop our server.
-
Let's dive back into our code base, jump into our .env,
-
and let's remove the app key. I'm just going to cut it out for right now.
-
We'll paste it back in whenever we're done.
-
If we dive into our env.ts now, it has a declaration for the app key
-
that states that it should be a type of string.
-
And our app key also doesn't have optional specified on it, so it is required.
-
If it were optional, it would look something like this.
-
So let's go ahead and remove that, and let's try to boot up our server.
-
So I'm going to hide our text editor back away to get down to our terminal.
-
And now that we have removed the app key from our .env file,
-
let's go ahead and try to boot our server up with npm run dev.
-
I'm going to hit Enter. We'll see it run, and look at that.
-
Our HTTP server has died, though it's still watching for changes.
-
So if we were to fix this error, it would boot right back up.
-
The only reason that it died is because it's missing the environment variable
-
app key, which is expected because we removed it from our .env file.
-
So the validation failed for one or more environment variables,
-
and it's using that env.ts file within our start directory to check that.
-
So we have two options here to remedy the issue that we've created.
-
We can either make that environment variable optional,
-
or we can add it back into our .env file.
-
So let's open our text editor back up. Now the app key is actually something
-
that is required by AdonisJS itself.
-
If we make this optional, it will fix the issue that we're specifically seeing,
-
but it will create others. So let's go ahead and make this optional
-
so that we can see that this is a valid option to fix this particular issue.
-
So let's give this a save, hide our text editor back away, and there we go.
-
We see a completely different error, though our server still died.
-
The error is now missing app.app_key.
-
The key is required to encrypt values. Let's dive back into our code base,
-
remove the optional that we added in because this is something
-
that is required for our application to run successfully.
-
Hence, why we'll want to specify it as required within our env.ts.
-
We can give our env.ts a save and add our app key back in.
-
Give that a save, hide our text editor back away,
-
and voila, our server is back up and running.
-
We can verify that within our browser. We saw it do a refresh.
-
We'll go ahead and do a sanity check there, and everything's still A-OK.
-
We can hide that back away, and we still see our cache is getting hit within our terminal.
-
So in the next lesson, we'll install Redis, configure it within our application,
-
and swap our cache system out so that we are using something
-
a lot more scalable as opposed to
-
our singleton service within our application.
-
Introduction
-
Fundamentals
-
2.0Routes and How To Create Them5m 23s
-
2.1Rendering a View for a Route6m 29s
-
2.2Linking Between Routes7m 51s
-
2.3Loading A Movie Using Route Parameters9m 17s
-
2.4Validating Route Parameters6m 6s
-
2.5Vite and Our Assets6m 38s
-
2.6Setting Up Tailwind CSS9m 5s
-
2.7Reading and Supporting Markdown Content4m 32s
-
2.8Listing Movies from their Markdown Files8m 51s
-
2.9Extracting Reusable Code with Services7m 4s
-
2.10Cleaning Up Routes with Controllers4m 52s
-
2.11Defining A Structure for our Movie using Models9m 38s
-
2.12Singleton Services and the Idea of Caching6m 11s
-
2.13Environment Variables and their Validation4m 16s
-
2.14Improved Caching with Redis10m 44s
-
2.15Deleting Items and Flushing our Redis Cache6m 46s
-
2.16Quick Start Apps with Custom Starter Kits6m 28s
-
2.17Easy Imports with NodeJS Subpath Imports8m 40s
-
-
Building Views with EdgeJS
-
3.0EdgeJS Templating Basics8m 49s
-
3.1HTML Attribute and Class Utilities6m 9s
-
3.2Making A Reusable Movie Card Component10m 24s
-
3.3Component Tags, State, and Props4m 53s
-
3.4Use Slots To Make A Button Component6m 56s
-
3.5Extracting A Layout Component5m 13s
-
3.6State vs Share Data Flow2m 59s
-
3.7Share vs Global Data Flow6m 7s
-
3.8Form Basics and CSRF Protection6m 13s
-
3.9HTTP Method Spoofing HTML Forms3m 3s
-
3.10Easy SVG Icons with Edge Iconify7m 57s
-
-
Database and Lucid ORM Basics
-
4.0Configuring Lucid and our Database Connection4m 3s
-
4.1Understanding our Database Schema9m 35s
-
4.2Introducing and Defining Database Migrations18m 35s
-
4.3The Flow of Migrations8m 28s
-
4.4Introducing Lucid Models5m 43s
-
4.5Defining Our Models6m 49s
-
4.6The Basics of CRUD11m 56s
-
4.7Defining Required Data with Seeders11m 11s
-
4.8Stubbing Fake Data with Model Factories13m 48s
-
4.9Querying Our Movies with the Query Builder15m 30s
-
4.10Unmapped and Computed Model Properties3m 24s
-
4.11Altering Tables with Migrations7m 6s
-
4.12Adding A Profile Model, Migration, Factory, and Controller2m 57s
-
4.13SQL Parameters and Injection Protection9m 19s
-
4.14Reusable Query Statements with Model Query Scopes8m 11s
-
4.15Tapping into Model Factory States9m 15s
-
4.16Querying Recently Released and Coming Soon Movies4m 59s
-
4.17Generating A Unique Movie Slug With Model Hooks7m 59s
-
-
Lucid ORM Relationships
-
5.0Defining One to One Relationships Within Lucid Models5m 49s
-
5.1Model Factory Relationships2m 54s
-
5.2Querying Relationships and Eager Vs Lazy Loading5m 17s
-
5.3Cascading and Deleting Model Relationships5m 16s
-
5.4Defining One to Many Relationships with Lucid Models6m 56s
-
5.5Seeding Movies with One to Many Model Factory Relationships5m 24s
-
5.6Listing A Director's Movies with Relationship Existence Queries8m 41s
-
5.7Listing and Counting a Writer's Movies8m 41s
-
5.8Using Eager and Lazy Loading to Load A Movie's Writer and Director5m 18s
-
5.9Defining Many-To-Many Relationships and Pivot Columns9m 48s
-
5.10Many-To-Many Model Factory Relationships4m 50s
-
5.11A Deep Dive Into Relationship CRUD with Models18m 5s
-
5.12How To Create Factory Relationships from a Pool of Data13m 55s
-
5.13How To Query, Sort, and Filter by Pivot Table Data9m 47s
-
-
Working With Forms
-
6.0Accepting Form Data12m 15s
-
6.1Validating Form Data with VineJS9m 29s
-
6.2Displaying Validation Errors and Validating from our Request7m 16s
-
6.3Reusing Old Form Values After A Validation Error2m 3s
-
6.4Creating An EdgeJS Form Input Component5m 28s
-
6.5Creating A Login Form and Validator5m 1s
-
6.6How To Create A Custom VineJS Validation Rule9m 7s
-
-
Authentication & Middleware
-
7.0The Flow of Middleware7m 49s
-
7.1Authenticating A Newly Registered User4m 14s
-
7.2Checking For and Populating an Authenticated User2m 10s
-
Logging Out An Authenticated User2m 24s
-
Logging In An Existing User6m 54s
-
Remembering A User's Authenticated Session6m 55s
-
Protecting Routes with Auth, Guest, and Admin Middleware5m 36s
-
-
Filtering and Paginating Queries
-
Creating A Movie List Page3m 43s
-
Filtering A Query By Pattern Likeness7m 9s
-
Filtering Our List by Movie Status5m 47s
-
How To Apply A Dynamic Sort Filter To Your Query7m 12s
-
Joining SQL Tables To Order By A Related Column4m 49s
-
Validating Query String Filter Values7m 23s
-
How To Paginate Filtered Query Results9m 15s
-
Pagination First, Last, Next, and Previous Buttons4m 2s
-
Join The Discussion! (0 Comments)
Please sign in or sign up for free to join in on the dicussion.
Be the first to Comment!