 In this video, I'm going to walk you through getting started on writing a new web application in Go, using JIN, a Go web framework, Heroku as your deployment platform, Go for JAS so you can write Go instead of JavaScript for your client-side code, and PostgreSQL for your database. I'm going to assume you already have a basic understanding of Go, Git, HTTP, HTML, CSS, JavaScript, SQL, basic web development and Go language stuff already, but if your knowledge of these topics is really rudimentary, you still can probably just follow the steps I give you by rote and still do okay. So in our stack, we're going to be using Go 1.11, and that's important to use the latest version because it has this new feature, Go modules, which is a new way of doing dependency management built into the Go tool itself. So we're not going to use Go vendor or Go depths or any of those alternative dependency management systems. We'll use Git, of course, for version control like most people do these days, JIN is a Go line web framework in quotes here, because I don't think it really quite constitutes a full framework, which is, I think, good. It's more like a library that provides some conveniences for you. I find it pleasant enough to work with, and it's something that you can take piecemeal. It's not imposing a huge amount of structure on your code that's going to be difficult to extract later. We'll be using Heroku for the hosting platform because it's easy to get going and free for a simple starter project. Even if later on you want to move to some other hosting platform, that won't be a huge problem down the line. Heroku is just a good way to get started. We'll use Go for JS so that we can write Go code that compiles into JavaScript so that it can run within the browser, allowing us if we choose to bypass writing any JavaScript whatsoever, which I like because you can just stick in one language for both the server side and the client side. Although if your client code, if you think it's not going to get very elaborate, if it's going to stay very, very small, I don't think there are many advantages to go at that scale. But the larger your client side code gets, the more you're going to want static typing and also just some other niceties that I appreciate about Go that's certainly relative to JavaScript. And lastly, we're using Postgres for the database. That's generally the best option these days. And Heroku makes it quite easy to integrate Postgres into your project. So first things first to get started, you're going to want to install Go, making sure you have version 1.11 or later. Install Git. If you don't have it already, you can install the Go for JS compiler assembly with this command. Go get you github.com. Go for JS. Go for JS. And if you don't already, make sure that your Go path bin directory is in your path so that you can just type Go for JS in any directory and it'll recognize the command. Lastly, you'll need to create a Heroku account if you don't have one already and install the Heroku command line interface. Once we have everything installed, we want to get a simple Go web app written with the GIN framework running on a local system. So if you haven't already for your new project, create the new repo on github, make sure to check the box to knit the readme and then clone from github to your directory of choice. And because we're using Go modules, you don't have to put the directory under the Go path. In fact, I would recommend you put it just elsewhere. So once you have a new project directory inside that directory, create main.go and put the text you see here on the right in that file. Create a templates slash home.temple file and it doesn't really matter what's in there. Just put any HTML if you like. I'll show you some sample HTML in the next slide you might put in there. And next, because we need to tell the Go compiler that this project is going to be using Go modules in the directory, you want Go mod in it. That'll create a Go.mod file in your directory, which contains a list of all the dependencies of your project, which for now is just going to be the GIN framework. So for everything else we're using is in the standard library. And when now we run Go build, the Go tool will recognize the Go mod file. And then as it compiles our code, it looks at the imports and adds any dependencies into the Go.mod file as appropriate. Like it's going to add the GIN import into our Go.mod file. And this just happens every time you run Go build. It looks for any new imports that aren't yet in the Go.mod file. And it just automatically adds them. And in the Go.mod file on each dependency, it'll put a version number. And automatically it's just assuming right now that you want to use the latest version number. But it's important that it records the latest version now because down the line as we continue working on our project, if a new version of GIN comes out, what we don't want to have happen is for the Go tools to automatically fetch that latest version. We want to approve if we're going to use new versions of our dependencies. So the point of the Go module system is that it gives us control when our dependencies update. We have to actually positively affirm that we want to use the newest version rather than just stick with the version that's been working for us. So that's the primary thing Go modules are about, which might sound like a bit of extra work, but it's generally the saner policy. Next, because we're deploying to Heroku, the way Heroku works is that your whole repository gets pushed up to the Heroku server and it's run in a Docker container. And it expects to find everything it needs to build your program in that repository. And so we're going to need to actually bring the source of our dependencies into our project directory. And we can do that with Go.mod vendor. It automatically will create a subdirectory called vendor. And in there, it'll store all the source of our dependencies at this point, gin and all of its dependencies. So be clear that when we bring in new dependencies, we're going to first need to rebuild our project to update the Go.mod file and then run Go.mod vendor again. So it can copy anything that's not already in vendor into the vendor directory because otherwise we're going to push up to Heroku and it's going to be missing dependencies that it needs to build. Okay. So now everything's in place and we can actually run this program. And if you look over at the code, you'll see that the port our server is going to run on is specified through an environment variable port. When deployed to Heroku, port will automatically be set to 80, as you expect for a web server. But here on a local system, we'll want to use some other port number. And in the Unix shell in Bash, when you run a command, when you run a program, you can set environment variables just for that execution. And so we do that here. Whatever your executable is called, you put that after .slash. But before that, you specify, let's say 5,000 for the port. And when that command, our server will launch and you can go into your browser at localhost colon 5,000 and you should see your webpage. I'm not going to go into any details about the gym framework here. It's a quite straightforward framework. And if you've done any web server programming before, it's easy to pick up the documentation is quite clear. But just really briefly, what's going on here on the right is gin.new that creates a new router. We set up serving template files from our templates directory. Later on, we're going to need a static directory for serving so static resources like your CSS, your JavaScript files, et cetera. And other than that, we define simply one route, the root for slash, which is just going to simply render the home.template file, which is just going to have whatever HTML you put in it. After all of our routes are registered, in this case, just the one. Last thing we do in main is we call run on the router, specifying what the port number is. And that's what actually kicks off the web server. That's when it begins serving. So what about that HTML? Well, again, it doesn't really matter what it looks like at this point. You just want to see something on the screen. But I would recommend, firstly, making sure your HTML has a title so that you can recognize it in the tabs of your browser. If you're like me, you tend to have a million tabs open, so it's nice to be able to quickly identify your tab. Also, for that reason, it's a good idea to very early on in your project, make sure you have a FAB icon set up. You don't have to pick the ideal FAB icon, just something that's recognizable. There are a lot of sites online you can go to find icons and there are sites you can use. It'll convert like pings and gifts and whatever into the eco format. So just make sure you have a FAB icon file in your static directory and then this link tag will tell the browser where to find your FAB icon. And also be sure to early on set up a CSS file. Otherwise it'll be tended to put all your styles directly on tags, which is a very sloppy style as much as possible. You want to put your style stuff into a CSS file. So that's a good start on your HTML. Now how do we actually deploy to Heroku? Well, from the command line, once you have the Heroku command line interface installed, first do the Heroku login command, which will prompt you for your Heroku password. And then using Heroku create, you pick a new Heroku app name, which has to be unique among all existing Heroku apps. So if you pick a name that's over there in use, you're gonna get an error. You might at this point just omit the name and Heroku will pick one for you. It'll just generate some nonsense name for you. Anyway, do make sure to execute the create command in the directory of your project because it'll recognize there's a Git repo there and it will set up a new Git remote for you called Heroku. And so if you then Git push Heroku master, that'll push the master branch of your local repo up to Heroku and it'll automatically then try to build your project. And if it's successful, then your application will be deployed at the URL of whatever your project name is .herokuapp.com. As a convenience from the directory of your project, you can type Heroku open and it'll open that URL in your browser. Be clear that although we deploy by Git pushing to Heroku, you really should not be using Heroku for version control. In fact, I don't think they make any guarantee of preserving the remote repo on their end. If you shut down the application, it may actually lose your code, I believe. So you're gonna be using your GitHub account or whatever Git service you use as the real remote repository for your project. So say you're working on your project, you make some commits and then you push them up to GitHub and then only when you're ready to deploy do you also push to Heroku. And when you coordinate with other people on the project, when you pull, you're always pulling from GitHub. I'm not even sure what happens if you try and pull from Heroku. I think it might actually give you an error. So in general, you're just pushing to Heroku simply when you want to deploy and that's it. Okay, now let's bring go4js into the picture. We're gonna create a subdirected gojs for all of our client-side go code and in there we'll create a main.go. Doesn't have to be called main.go. You can call whatever you want, but it has to be a package main file. And in this package we're importing the go4js.js package, which is a package that lets us from our go4js code access the JavaScript environment to get and set global variables and through it effectively access the browser APIs. So here in the main function, js.global is the global namespace object and from that we're getting the document variable in the global namespace and assigning it here to doc. And then the next line we use print line to print out the console. What you don't want to do is use fumped. If you use fumped.print or print line, it doesn't actually print out the console. And also the problem is the fumped package because it uses reflection. Anytime you bring in the fumped package in your go4js code, it inflates the size of the compiled code by like a megabyte, it's huge. So the general rule in go4js as we avoid fumped and any package which relies upon reflection because reflection code for a variety of reasons requires bringing in all this stuff, which is huge in the compiled output. So be careful about that. So having created the subdirectory gojs and main.go inside it, we then want to build it. So we CD into the directory and use go4js build, which is just like go build, except instead of an executable, it'll spit out a js file in that same directory. And we want our web server to be able to serve this js file. So we're going to add a static route that exposes the entirety of the gojs directory as gojs. And so in HTML, we can add the script tag referencing the gojs file generated by go4js build. And it's important actually that we expose the whole gojs directory rather than just a single gojs file because go4js build also spits out a .map file which is used by the browser when we try and debug our code instead of having to debug the compiled JavaScript code which is going to be difficult to read and it's simply just not the code we originally wrote in go. We want to see the go code when we debug while the map file allows us to do that. In the browser debugger, we can open up the actual go files and set break points on them and step through it like we're stepping through go code not through the underlying compiled JavaScript. But this only works if the browser can see our .map file and all the go files. It needs to actually be able to access them like it accesses any other resource through the server. So that's why we're statically serving everything under the whole gojs directory. Normally you would say it's a very bad idea to serve your actual code to your users but of course this is go code that's compiled into JavaScript anyway and so even through minification they still get your code in one form or another. So it's not like we're really hiding anything and you shouldn't put sensitive things in your client side code anyway. So maybe in production you make sure that you're serving just the single compiled JavaScript file instead of the map file and all the go files but I'd say it's hardly a real security concern. Your security probably shouldn't hinge upon the obfuscation and minification of your JavaScript code. Now I'll talk more about Gover.js in a later video but an important thing to note here is we're not using Gove modules which I think is now supported in Gover.js. I could be wrong about that. I'm sure it will be at some point in the future but we don't really need to use modules here because we don't need to put things in a vendor directory. We're gonna make sure that before we push up to Heroku that we first use Gover.js build to build the latest version of our JavaScript code and then make sure that's committed into our local repo and then push up to Heroku. Heroku is not gonna be building our client-side Go code. We're just gonna be doing that locally on our machine. It of course could be done to set up the build process on the Heroku side so that it actually does run the Gover.js tool and actually compile your code on the client side. Arguably that would be more convenient and less error prone rather than us having to remember to make sure to compile the JavaScript code before committing and pushing to Heroku but here we're just gonna keep things simple. We're just gonna do it manually. So now if you compile your client-side code and then recompile the server because we added that new route to the server, we can run the server locally and navigate to local host 5000 and you should see the content of your webpage plus also in the console it'll have that print line message from our Go code. Our client-side main function is executed when the page loads. If you go into the sources tab you can navigate to your client-side Go files and then you can actually set a break point. We can set this break point and if I were to reload the page then it would break on that first line of main. The last step here is we're gonna wanna set up a database. Do be clear about Heroku, the nature of the containers that it runs what they call dinos in their terminology. These dinos, they don't have any persistent storage. For one thing, every time we push up to Heroku when we push the latest version to Heroku it just flushes everything and starts again with a new container. So anything we store in the file system in our container is not gonna persist between new versions of our code. That's a problem. And then on top of that your Dino containers automatically are put to sleep after periods of inactivity and when they're inactive Heroku makes no guarantees about restoring the full state when it wakes up again. So after your initial successful build it will save that state but then anything that happens from there when your Dino falls asleep and then wakes up again it'll often roll back to that state. So you can't really preserve anything you can't store anything permanent directly in the Dino container itself. You need some kind of Heroku storage add-on and there are many different add-ons the one we'll be using here which is a Postgres add-on. And so the first thing we do within our project directory is we use the Heroku add-ons command with colon create and specifying the name of the add-on we want which is Heroku-Postgresql colon hobby dev hobby dev is the lowest tier plan the one that's free which is limited to I think like 10,000 rows in your database. So it's good for just like starting up a web project but as soon as you have actual real users and actual data storage needs you're gonna wanna upgrade to an actual paid plan. But for our free project just getting started that should be fine. Having created the add-on for our project in our server-side code we add imports for database slash SQL that's the standard SQL package but that's just the interface we need a so-called database driver behind that and that's why we also import libpq pq as in Postgres I don't know why they abbreviate as pq and the reason you put underscore in front of the import is because we're not actually gonna be referencing anything from the pq namespace in the pq package there's an init function which is run at the start of our program and that registers the Postgres database driver with the SQL package such that when we use the open function from the SQL package we can specify that we're using a Postgres database and it knows what we're talking about. You see that down at the bottom on the left where SQL.open Postgres without importing the pq driver it would have no idea what kind of database we're talking about and that called open would return an error. So you see there at the bottom that's how we open the database put that somewhere in your main towards the top. The second argument to open is the connection string which when running on Heroku is gonna be provided through the database URL environment variable and we have to get the connection string this way from the environment variable because Heroku makes no guarantees about that connection string being stable what the connection string is supposed to be changes dynamically so we need to make sure that Heroku when it starts up our server it is programmatically getting the latest version of what the proper URL is. So assuming this exceeds error will be nil and db will be assigned it's not a connection it's this thing that represents the SQL package connection pool but it's the thing we use to invoke SQL commands when we use this package. As a demonstration of using this thing on the right you see another route we might add to our code for slash tick so when we navigate to slash tick it'll run the code you see here which will create a ticks table if it doesn't already exist it'll insert a new row into the ticks table which is just the current time and then the third query there will get all the rows from the ticks table and that query returns a rows object which is a kind of iterator object and down at the bottom you see a loop where we're calling rows.next to go through all the elements of the rows the scan method there is used to actually extract the value from the row into a go variable the variable tick of type time and at the bottom c.string that is tacking on the tick to a string which is the response body for this HTTP request so in this route now once our server is running when we navigate to slash tick we'll see a list of timestamps and every time we refresh that list will have one more entry because every time we visit this route we're adding another timestamp to the ticks table that's a very brief introduction into the SQL interface which is quite complicated and the whole topic unto itself probably something will tackle in another later video but anyway now with all this code in place let's run go build again and because we've added a new non-standard dependency in this case the PQ library we're going to want to make sure that's in our vendor directory so we run go mod vendor and now we could deploy to Heroku and then run the application remotely but if you want to run the application locally we need to specify the values for the environment variables port 5000 like we saw before but also we need to specify a value for the database URL which as I mentioned is dynamic it's not fixed and so what the spash syntax does the dollar sign with parentheses is in those parentheses are another command in this case calling Heroku config which will echo out the config value for our database URL and we specify after the hyphen you specify the Heroku name of your application so that Heroku config sub-command it's going to spit out the URL and that's going to be inserted in place of the dollar sign parentheses and so that's going to be the values set to database URL when we run our server now be clear that in this setup the server running locally and the server running on Heroku both are using the same database and this might be a problem for your development you may prefer to have a development database a database that's just used for scratch for development purposes where you don't really care about losing the data that's generally a good idea so what you might want to do is set up Postgres on your local system and then use that database when running your server locally that is one solution to this problem that's probably the simplest thing to do regardless now that we have our server running we can open up localhost 5000 in our browser and navigate to slash tick and every time we reload the list of timestamps we see will grow by one each time so that's how to set up a go web app using Heroku with Jen and Go4JS and Postgres if you want to learn about Heroku I suggest you look at these links there's some basic concepts that are important to understand you should also learn more about Jen if you're going to use it pretty much everything you need to know is right there on the readme of the GitHub repo and next video I'm going to go into more detail about using Go4JS