So let's get started writing some code and we'll start with a very simple Web application, and that'll
be the basis for pretty much everything we do in the remainder of this course.
So I have Visual Studio code open and I don't have a project folder.
So I'll open the Explorer, click open folder, go to my Visual Studio Cotes project folder and create
a new directory, which I'll call Goldstrike.
You can call it whatever you want.
Just remember where you created it.
OK, so I'll open that folder and the first thing I'll do is open a terminal window and type go mode
in it and I'll give it some name.
Not typically would go GitHub dot com or whatever your name is and whatever your project name is.
But I'm just going to go my app because I have a different version I've committed to get out.
OK, so that creates a Gombauld file.
Now I'm going to create a folder at the root level of my project called CMD, and that will hold the
front end, the main entry point to our application.
And I'll create another folder which I'll call Internal and we'll use that one.
Oh, I don't want it there.
Delete that.
I want it beside CMT Internal there and inside my command folder.
I'll create a new folder which I'll call with.
And I'm also going to create another one called API, which we won't get to for a while.
But I'm going to use this single code base to produce two different binaries, one for the front end
and one for the back end.
And in a project as small as this, that's not absolutely necessary.
But this project will grow over time.
And at some point I might want to split the load between two applications, perhaps on two different
servers.
And this is also a great opportunity to show how you can produce multiple binaries from the same code
base.
So inside my Web folder, I'll create a new file, which I'll call Mango.
And this will be the entry point to our Web version, the front end of our application, and I'll give
it a package declaration, Maine.
And I'm going to set up a couple of constants as well.
The first one I'll call version, and that's just going to be a string and I'll set it to one point
zero point zero.
And the second one will be another constant, which I'll call txt version.
And that's going to be equal to one.
And what I'm going to use that for is I'm going to append that to any external txt files or JavaScript
files.
And when I increment it, that will force most browsers to bring the new version down.
And it just saves me the trouble of having to clear the cache when things aren't working the way that
I expect them to.
Just a simple little trick.
The next thing I'll do is I'll create a type and I'm going to call that config.
And this will hold configuration information for our application.
And I'm going to put a bunch of fields in here, some that will use in this section of the course and
some of that we won't use until later on.
So first of all, port in what port do I want to listen?
And I'll make that an int.
And then what environment are we in EMV?
And I'll make that a string that will be like production or development and also have API.
What you, Earl, do I call to my backend API.
So that'll be a string as well.
And I'll also create one that I'm not going to use this time around.
But it's a database DB and it's just a struct.
And it has one field which is called D and the data source name.
How do we connect to the database?
And that's just a string.
We're also going to have to have stroke information and I'll make that a struct as well.
And there's only two things to worry about.
What is my secret key, which I'll call secret and it's a string and what is my publishable key, which
I'll just call key and it's also a string.
So there's my config type.
Now I'll create another type that I'll use as the receiver for the various parts of my application and
I'll just call it application.
And again, it's a struct and it has.
Well, first of all, I want to have the config of type config that we just defined.
We're also going to have a couple of logger's or call one info log and it's a type pointer to log logger
and I'll let the studio code do the import.
And it did and I'll have an error log and it's a type log longer a pointer to it again.
I'll also have, say, a template cache and we'll get to that in a while.
But this is going to be a map of type string and the content of each entry will be a pointer to template
template and make sure you get the one from HTML template, not text template.
You want HTML templates.
OK, and finally I'll just put version which is a string.
OK, so there are my two types.
Now let's get our main function going function and the first thing I'll do is create a variable and
I'll call that variable cfg ver ciggy of type config and I want to populate that variable.
With some information and I'll get some of it at least from the command line Fleck's, so we'll use
the flight package flag DOD and I want first of all and infer right there, then that should have done
the import for flag for me.
Let's make sure it did.
Yes, it did good so far.
And I want to read this command line flag into my config variable and I want port and I'll call it port.
That'll be the command line flag.
I'll give it a default value of four thousand and a little description server port to listen on.
Now duplicate that line and change this one to a stringer.
And what I'm going to read in next is my environment and I'll use EMV and I'll give it a default value
of, say, development and I'll give the description just application environment
with a default of development or production.
Those are the possible values.
And I also want the API.
So config API call the command line Fleg API and I'll make the default HDB colon slash slash localhost
port four thousand and more
and I'll call this new URL to API.
OK, so there's the three things I want to read in right now.
So let's pass the flags flagged up first.
And now I also need to get that stripe secret key and the stripe publishable key, but I don't want
to read those from the command line.
The reason being when someone actually is logged into the server, they could type dash X or a U X and
possibly get that secret key.
And I don't want that to be available anywhere.
So instead, I'll read both the stripe key and the stripe secret from environment variables.
And that's pretty CFT stripe.
The key is equal to and I'll use the built in OS package from the standard library OS don't get on it
again.
OS get on right there and I'll get stripe
key and duplicate that and get the secret.
So now let's set up our lawyers and I'll set up, first of all, info log and I'll just make that assign
the value of from the log package dot new and the first parameters just os start standard.
That's where I want to write.
And I'll prefix it with info and a tab and I'll use logged on a date and a pipe and logged all time.
OK, so that's my info log.
Now let's create our error.
Look, I'll call this one error with a tab, and I'll have logged our date logged all time and also
where the error take place.
So I'll add another pipe and put log dot l short file and that will give me some meaningful feedback
when we have problems.
Now I'm going to create a map for my template cache, which we're not using yet, but we'll get to that
shortly.
And that's certain.
The value of make map.
String and pointer to template, template and a very simple template, right template.
OK.
Now, let's create an application variable app to sign the value of and I'm going to use a reference
to an application and I'll populate the necessary fields, the config will be equal to CFG.
The info log will be equal to the full log, which we just created.
The analog will be equal to error along the template cache will be equal to Tsay and final version will
be equal to version.
OK, so that's our app variable.
Now we want to create an actual web server and I could just start the web server right here.
But what I'm going to do instead is come up here and create another function and I'm going to call that
func and it's going to have the receiver of app of type pointer to application and I'm going to call
it server.
And up here I'll create a variable called Salvy.
Should they should return an error potentially there, serve as a sign the value of and I'm going to
call from the HTP package HTP DOD server.
I thought.
And I'll populated with things like the address, which will be used use format as print F and it will
be a string followed by a column followed by the D and I'm a substitute app config part.
OK, so that's the address handler will get to in a minute.
So I need to have a handler and I'll just put it in.
What's going to be there Abda.
It doesn't exist yet but it will shortly and I'll give it some nice default idle time out.
I'll set that to say 30 seconds, 30 times time dot second and I'll have the read time out and I'll
set that to say 10 seconds time dot second.
That seems logical and I'll give it a read header timeout and I'll set that to five seconds, five times
time dot second
and finally we'll give it right timeout.
Five times timed second, and that's more than adequate for our purposes.
OK, and I'll print something to the log using my app DOT info log and I'll print line and I'll just
say starting HDP server on porked percent and app dot config port.
Actually let's put this as well, HDP server in s mode and we'll prefix that with APTA config dot.
It's on.
And that's in part OK.
So is this a message and I will actually start the server, return served, listen and serve and that
will return no error if everything starts the way it's supposed to and it'll return an error if something
fails to start up for some reason.
Now we need to set up some application routes.
So in my Web folder, I'll create a new file, which I'll call Routes Duco.
And it's in Package Maine, and what I'm going to do is open my terminal and import a nice rooting package
and I want I'm going to use is Pachi Road, so I'll just go get that.
Go get GitHub dot com slash.
Go Ducci slash.
Cheese.
And I'm going to get version five if there's a later version out, you may want to use that.
But if you want to follow along.
Exactly, use version five that goes and gets it adds it to our government file or close the terminal
and up here or create a new function roots.
And it has the receiver of application.
And it returns as it has to an http dot handler and I'll create a new router, which I'll call Mux for
multiplexed, and that's a sign the value of Ketut new router.
And I'll just say return mux for now and make sure that everything looks the way that it should.
So we have this GOCE like this version five.
That's fair.
OK, so now if I go back to my main dock, go, is there an error now?
There is I'm not using the app variable down here, I simply say there is a sign, the value of app
to surf.
And check for error, and this has to be an assignment operator, if error is not equal to nil, then
I'll say Abdol error log dot, print one.
The air print the air and I'll just say logged off, we'll get to log entries, but that's fine.
OK, so this should actually compile, shouldn't do anything, but it should actually run.
So let's try.
It will open our terminal window, clear the screen and type go run dot com slash web.
And there it is.
It started up the application server.
OK, so that's enough to give us a framework that we can put some roots in and start serving some pages
and we'll get started on that in the next election.