Centralized Configuration Management
The video introduces a structured approach to managing application configuration in a single location. Instead of hardcoding values like host and port, configuration is centralized to improve maintainability and reuse.
Environment Variables for Flexibility
Environment variables are used to configure host, port, environment, and project name. This allows settings to vary across development, testing, and production without modifying source code, and keeps sensitive data out of the codebase.
Config Struct and Parsing with env Package
A configuration struct is created and populated using an external env package. Struct tags define the expected environment variable names, and parsing returns an error if required variables are missing.
Global Environment and Project Name Handling
Environment and project name are exposed with controlled global access and default values. Constants define supported environments (development and production), with development as the fallback if unset.
.env File Setup and Loading
A .env file is created to define exported environment variables such as host, port, environment, and project name. These variables are loaded into the terminal using source .env, since Go does not automatically load them.
Derived Configuration Methods
Methods are added to the config struct to compute derived values, such as a TCP address combining host and port. This encapsulates logic within the configuration layer and prepares the application for server startup.
before we start configuring our server and see the results of our work i want to introduce a way
so we can configure certain settings based on the environment that our application is is running in
right now our application assumes a few things it assumes what host it should run on what port
to listen to what environment is running in and we've been hard coding some of these values in
different places i want a specific place that these values get set and defined so we can reuse
them throughout the application this comes in handy when we start to add more things like
secrets like database credentials or hashing keys and things that we don't want in our source code
right now the environment settings that we have are rather limited we will be able to configure
the app host the port the environment
and the project name and this will all be done through environmental variables now for the
unfamiliar you can think of environmental variables as pieces of configurations that live
outside of your app in your in your operating system they let you change settings without
adding the code and this is very useful when we go from development to testing to production
so for example on your own computer you can have environmental variables set in your terminal and
then you can add them to your own application and then you can add them to your own application and
then you can add them to your own application and then you can add them to your own application and
then you can add them to your own application and then you can add them to your own application and
then you can add them to your own application and then you can add them to your own application and
then you can add them to your own application and then you can add them to your own application and
then you can add them to your own application and then you can add them to your own application and
then you can add them to your own application and then you can add them to your own application and
then you can add them to your own application and then you can add them to your own application and
then you can add them to your own application and then you can add them to your own application and
then you can add them to your own application and then you can add them to your own application and
then you can add them to your own application and then you can add them to your own application and
then you can add them to your own application and then you can add them to your own application and
then you can add them to your own application and then you can add them to your own application and
then you can add them to your own application and then you can add them to your own application and
then you can add them to your own application and then you can add them to your own application and
then you can add them to your own application and then you can add them to your own application and
the environmental variable that we that it should look for is gonna be uppercase
app underscore and then uppercase host then we can copy all of this paste it
down here and then we just need to chain host to port so we have added these
structures what struct tags that specify a different name compared to the field
name and this is more of our convention but it's also to tell the parser that
we're going to add in just a second the the name of the environmental variables
it should look for so now let's specify a new function here so we can actually
create a config say config or error
say cfg which is just config for short create a empty config struct then we're
going to be using a package now called env where we can say pass bit options
you're gonna pass a pointer to the cfg and cfg variable and then we're gonna
say env.options it's just gonna be empty for now and then we're gonna say cfg.options and then we're gonna say cfg.options it's just gonna be empty for now and then we're gonna say cfg.options it's just gonna be empty for now and then we're gonna say cfg.options it's just gonna be empty for now
close that and if the error is not nil simply simply return the error and if
we have no errors we return the config and nil I'm gonna give that a save and
we're gonna have an error here because we're gonna be using this package from
Carlos Zero called env so let me just add this to our go.mod file and if I
restart the LSP it should go away
great and of course we also need to turn an empty config struct if there is an
error now this this package is really really handy and we can specify options
like if an env variable should be required or not so that we actually get
an error if it can't find that env variable so we don't start running our
application without all the expected environmental variables in place now we
have set up our config struct with app host and port but I also mentioned that
we wanted to have environment and project name these values are used
throughout the application and sometimes in places where it can be ordered to
pass an argument like like in our views for example therefore I tend to make
these these global in a sense that we simply expose them directly through the
config package now you should not use global as a general rule of thumb they
make the code harder to test and they can change unexpectedly in this case we
have a limited set of values and we can provide same defaults so we're not
really risking shooting ourselves in the foot for everything else like host port
database credentials whatever we will stick to the to the config struct so
values are explicit and testable we have two environments we have development and
we have production so I want to make sure that we have these as const and we
can then check against these these variables or values throughout the
application so I'm gonna say const dev environments equal to development const
prod environments
environment and it's gonna be equal to production and then I want to use this
get env method from the OS package to look up the value and then we're simply
just gonna return the dev environment if it's not set so to do that we're gonna
create a variable that's gonna be called env consider that equal to our function
that returns a string we're just gonna immediately call that function so if
OS get env and it's gonna be environment in all other case that's not
equal to an empty string then we simply say oh there we go return that value go
and if not then we're gonna return dev environment give that a save and now we
can do the same but for project name so I'm just gonna copy all of this past it
below say project name project name there we go and here we can also provide
a default if you don't want this to be called bleeding yes for example you can
overwrite it but we're gonna be defaulting the project name to be leading edge
All right. Now, the final thing we need to do is we need to add a .env file that will hold these variables.
And the .env is more like a convention rather than a requirement.
You can call it whatever, but a lot of tools will actually look for .env files.
That's why we are going to name it like that.
So I'm in the .env file here, and we're just going to add the .env variable.
So I'm going to say export app host.
It's going to be local host.
Then we're going to say export app port.
I'm going to set it to 8080.
And then we're going to say export environments equal to developments.
And then file.
Finally, export project name.
And I'm going to set it to bleeding.
Again, feel free to overwrite this if you want the block to be called something else.
Now, to actually have these variables in our terminal, we need to source them.
And that is also why I have put this export keyword in front of the variable names.
And this is because Go doesn't automatically load these .env files.
Later on, we will add a tool that will handle this for us automatically.
But for now, we need to go into the terminal and write source space .env.
And then these variables, .env variables, will be set in the terminal.
And finally, I want to show you one more benefit of having all of our .env or environmental variables live on a struct.
And that is we can add methods to this struct to make our life easier.
For example, we are going to be needing a txt.
tcp address that we are going to use for running our server.
And that is going to be a combination of app host and app port.
So to do this, we can simply just add a method, config, and say get tcp adder.
It's going to be a string.
And now we can return fmt, sprintf.
We're going to say as.
And then.
We're going to say app host and app port.
Give that a save.
And now we have all in place so we can finally configure our server and our entry point and start actually running this application.