
An overview of what we will be covering in this course.
Just a bit of information about me and my background.
With the introduction of Vue.js version 3, we now have to application programming interfaces (APIs): the Options API, and the Composition API. We'll be covering both in this course.
Naturally, we'll need Go installed.
If you don't have an IDE already, VS Code will do the job. Install it if you need to.
We won't be using make for awhile, but it's incredibly useful, so let's install it now.
When you need to ask for help, make it easy for me to give that help to you. Here's how.
Let's build the standard "Hello, world!" application. It's tradition, after all.
Let's have a quick look at how Vue works on a web page.
With vue, it's easy to bind a form element to another part of the web page. Let's give that a try.
Let's add some additional interactivity to our application by listening for click events on a couple of buttons, and doing something when they are clicked.
Components are one of the most valuable and powerful parts of Vue. Let's get started with components.
Let's create a re-usable Vue component that can be used to create any type of text input for an HTML form.
Let's try out our Vue component by building a simple user registration form.
Vue applications have a certain lifecycle. It's important to know about it, and how to use it. Let's take advantage of Vue's lifecycle hooks and add some client-side JavaScript validation to our form.
Having a single component is fine, but it's incredibly useful to nest one or more Vue components within another Vue component. Let's try that by creating a (ficticious) user registration form.
Let's build a select component, and add it to our registration form.
Let's add one more component - a checkbox.
It's common to change what is displayed on a given web page depending on some condition. Vue makes it easy to do that with conditional rendering. Let's try it out.
One of the things we do a lot in web applications is to fetch data from a remote service. Let's get started doing that in our Vue application.
Now that we've pulled down some JSON from a remote source, let's work with it and display a list of books in our Vue application.
Let's get started adding some interactivity to our list of books.
Let's add an event listener to our list of books which allows us to remove a book from the list when the trash icon is clicked.
In order to work with Vue 3 in this section of the course, we need Node and npm installed. Let's take care of that now.
We also need vue-cli installed, so let's take care of that.
Let's remove most of the things that were auto-generated in our Vue app when we ran vue create vue-app, and get started from scratch.
Let's set up three simple Vue components for our application, register them, and add them to the main Vue component.
Let's add some more useful code to our header component.
Let's add some basic content to our Body Vue component.
Let's add some content and styling to our Footer component.
In order to make navigation actually work in our application, it is necessary to use some sort of router. Let's use the official Vue Router, which works really well.
Let's set up some simple routes.
Let's update main.js to tell our application that we are using a router, and then update App.vue to display the appropriate component.
Let's add a dummy Login Vue component, and update our Header component to use the router-link tag from the Vue Router.
Let's use the form Vue components we built in an earlier section and put together a Login component with the appropriate form.
Let's make creating a <form> tag simpler by creating a new Vue component.
Let's improve our login form by binding the form fields to the data associated with our component.
Let's update our FormTag and Login Vue components, and get them to the point where are ready to call the back end REST api. We won't be able to make that call until we actually write the api, but we'll get started on that in the next section.
Let's have a quick look at the way Go works with JSON files.
Let's get started writing the Go code for our REST api.
Let's simplify things by installing a third part routing package, and moving our handlers into their own file, with one function per handler.
Let's try connecting our front end Vue application to our back end API server.
Let's modify our routes.go file in the Go back end API to take care of CORS restrictions.
Let's try connecting from our Vue front end to our Go back end API one more time, just to make sure CORS is set up properly in our routes file.
Let's write two helper functions that make it easier to read & write JSON in our back end API.
Let's update our Login handler to use our helper functions for reading and writing JSON.
Let's write one more helper function that makes writing error responses back to the end user as JSON a simple one liner.
If you don't already have a Postgres client, Beekeeper Studio will do the trick.
Let's connect to our database with a Postgres client, and set up a simple users table.
Let's create a driver package that we'll use to connect our back end API to a Postgres database.
Let's clean up our driver package a bit, and then try connecting our API to the Postgres database.
Let's get our hard coded database connection information out of our source code, and move them into an environment variable. We'll do this using a Makefile, which makes our lives much easier.
We need some means of representing what is stored in the users table in Postgres in Go; let's set up a model to take care of that.
Let's go back to Beekeeper Studio and set up a tokens table in our Postgresql database.
Let's set up a Token model in our data package, which will map what is in Postgres with our Go code.
Let's simplify the way that we share database information to the various parts of our application, and set up a single function that connects to the database and gets a slice of all users stored in the users table.
Let's add one row to the users table in the Postgres database so that we can try out our GetAll() function.
Let's make sure everything works by creating a test route that calls the GetAll function on our User type, and write some JSON to the browser window.
We'll need a few methods on the User type to get users, so let's write a couple: one to get a user by ID, and another to get a user by email address.
Let's write the methods necessary to update a user, and to delete an existing user.
We're going to need to be able to insert users into the database, so let's write the Go code to insert a user into the Postgres database.
We are also going to need to be able to reset user passwords, and to validate a user supplied password to make sure it matches the hash that we have in the database. Let's take care of that.
Let's get started writing the necessary functions for the Token type.
Let's write two functions on the Token type: one to generate a token, and another to authenticate a token and make sure that it's valid.
We're going to have to be able to insert and delete tokens, so let's take care of that.
One useful function we can attach to the Token type is a means of ensuring that a given token is valid. In order to be considered valid, a token must exist, must be associated with a user that exists in the database, and it must not have expired. Let's create that function now.
Let's get started trying out the functions that interact with Postgres.
Let's try out our GenerateToken function and make sure it works.
Let's see if we got the function that inserts a token into the database right.
Let's make sure that the ValidToken function works as expected by creating a test route and handler.
Let's add a constraint to the users table which will only allow unique email addresses.
Let's make the JSON that we send back a bit more readable by implementing and using an envelope type.
In order to connect from our Vue front end to our Go back end and actually authenticate a user, we need to finish up our Login handler. Let's do that now.
We already call the back end from our Vue application, but now we need to make some changes to our front end so that we actually pass the necessary data. Let's get started.
Let's try authenticating and see if we get an error when we should, and that we get a token when we authenticate successfully.
Right now, our login process is not very intuitive, since we don't give any kind of feedback to the user when they log in. Let's improve that.
Let's get started making the logout process functional.
In order to log a user out completely, we need to delete the token saved in the database. Let's take care of that.
Let's finish up the logout process by updating our Vue Header component to make a fetch request to the back end API in order to delete the user's token from the database.
It's useful to save information like our token in a secure cookie so that users don't have to log in every time they visit the site. Let's take care of that now.
Let's make some final changes to both the front and back end in order to compete our improved login process.
While we're in development, it's useful to have nicely formatted JSON, but in production, that's a waste of resources. Let's make things more efficient by updating our Makefile to set an environment variable, and then use that in the API back end.
Let's set up some middleware to protect routes so that only users with a valid token can access them.
Let's try out our protected route from the front end to make sure that it works as expected.
Let's set up some stub components for displaying and managing both users and books.
Let's add some menu items to the Header.vue component which link to the URLs we added to the Vue Router file.
Right now, we have hard coded the URL to the back end API in all of our JavaScript fetch statements, and that's going to be a problem when we make this site live. Let's fix that by setting up an environment variable in a .env file.
Code duplication is rarely a good thing. Let's extract some functionality we'll be using a lot into a JavaScript module. This means we'll write less code, and have less code to maintain.
Let's try out our security.js JavaScript module and make sure it works as expected.
Every one of the Vue components that appear under the Admin menu item need to be protected; that is, they should only be available to logged in users. Let's take care of that using our Security JavaScript module.
Let's get started with the logic needed to get a list of all users from the back end API.
Let's take the data we received from the Go back end API and use it to display a list of all users in the Users Vue component.
Let's get started implementing the UserEdit Vue component, which will display a form for adding and editing users.
Let's finish up the necessary logic to submit data from the form in the UserEdit Vue component to the back end API.
Let's take care of the route and handler to insert a new user into the database, or to update an existing user.
Let's try out our changes and see if we can add a user.
Let's finish up the code on the back and front ends to handle updating an existing user's information.
Let's try out the changes we made and see if they work.
Let's take care of writing the front end and back end code to delete existing users.
Let's simplify our code by having a parent component listen for events in order to display notie alerts.
Let's modify our UserEdit component to emit events in order to display notie alerts.
Sometimes accessing a remote API is slower than we would like, and we should give some visual feedback to users while the data is loading. Let's take care of that now.
Since we have a list of users in the system, we can improve things a bit by showing which users are currently logged in. Let's get started.
We need to make some changes to the back end in order to make logging a user out useful. First, we'll add a "user_active" field to the users table, and second, we'll update the user type and associated methods in order to populate the user_active field with the appropriate value: one when the user is active, and zero when the user is not. Let's take care of that now.
Let's add a route and handler to take care of logging a user out and setting that user to inactive.
We need to make some modifications to the front end in order to log a user out and set them to inactive. Let's take care of that.
Let's make the necessary fetch request to access the functionality on the back end which deletes a user's tokens, and sets that user to inactive.
After a user is logged out and set to inactive, the table displaying the list of users should update automatically. In effect, we want to re-render the Users component, without doing a full page refresh. Let's take care of that now.
Even after a user is logged out and set to inactive, if that user has a token stored locally, they still appear to be logged in. Let's take care of that by checking the user's token on every request.
Let's try out our ValidateToken handler and make sure that it does what we think it should.
We need to set up some additional tables to store books and authors, so let's take care of that right now.
Let's insert some data into our new tables so that we have something to work with, and let's go over the contents of the books.go file.
Let's set up our back end so that it can serve images, since we can't just randomly add files to our assets folder in the front end, and get started writing a handler to send back a list of all books to the front end.
Let's update the Books Vue component to load the books from the back end API and display them using Boostrap's Card functionality.
Let's display a book's genres on the Bootstrap Card, and also implement a "filter by genre" function by adding some buttons at the top, and having those buttons call a method.
Let's update our code so that the "state" of the list of books remembers our current filter choice by using Vue's built in KeepAlive component.
Let's take care of the protected route, /admin/books, which lists all the books in our catalogue so that we can choose which one we want to edit.
Having to add an activated/deactivated method to all of our components can be irritating. Let's simplify thing by naming our components and taking advantage of the KeepAlive component's "include" attribute, and only cache the component that we want to cache.
Let's get started creating the form that we'll use to add and edit books.
Let's finish up the add/edit book form.
In order to populate the <select> on our form that displays the authors, we need to get some JSON from the back end API. Let's take care of that now.
Let's update our front end code, including the SelectInput Vue component, so that we can call the back end, get a list of authors as JSON, and populate the Authors <select> form field in our BookEdit.vue component.
Let's take care of creating the route and associated handler to allow for inserting and updating the database when adding or editing a book.
We have the handler and route in place on the back end API, so let's try adding a book on the front end.
We appear to be able to insert a book without a problem, but we can't yet edit an existing book. Let's take care of that.
The final step in managing our catalogue is to delete a book. Let's take care of that now.
Before we can write any tests, we need to duplicate enough of the production environment in order to give handlers, routes, and so forth enough information to run. Let's take care of that by writing a setup_test.go file.
Let's write a unit test that makes sure all of the routes we need are actually registered.
Let's go through how we write a unit test for a handler, while using a mocked database.
Let's write some unit tests for the readJSON and writeJSON helper functions in helpers.go.
Let's write a unit test for the errorJSON helper function.
Right now, we are just testing that the errorJSON function executes, and we're not paying any attention to what that function sends back. Let's fix that.
In order to test our data package, it would be useful to have an actual database to test. Let's automate this sort of thing by using Docker to spin up a test database server, and populate it with known data. That way, we can ensure that our various database functions work the way that we think they should.
Vue.js is, as they say on their website, an "approachable, performant and versatile framework for building web user interfaces." That sentence really does not give Vue its full due. It is arguably the best solution currently available for building highly interactive, easy to maintain, and feature-rich web applications currently available. Many developers find it easier to learn than React or Angular, and once you learn the basics, it is easy to move on to building more complex applications.
Go, commonly referred to as Golang, is an easy to learn, type safe, compiled programming language that has quickly become a favourite among people writing API back ends, network software, and similar products. The ease with which Go works with JSON, for example, makes it an ideal solution to develop a back end for a Single Page Application written in something like Vue.
This course will cover all of the things you need to know to start writing feature-rich, highly interactive applications using Vue.js version 3 for the front end, and Go for the back end API.
We will cover:
Working with Vue 3 using a CDN
Working with Vue 3 using the vue-cli, node.js and npm
Learn both the Options API and the Composition API for Vue 3
How to work with props
How to build reusable Vue components
How to build and use a data store with Vue 3
Creating, validating, and posting forms using fetch and JSON
Emitting and processing events in Vue
Conditional rendering in Vue
Animations and transitions in Vue
Working with the Vue Router
Protecting routes in Vue (requiring user authentication)
Caching components using Vue's KeepAlive functionality
Implementing a REST API using Go
Routing with Go
Connecting to a Postgresql database with Go
Reading and writing JSON with Go
Complete user authentication with Go using stateful tokens
Testing our Go back end with unit and integration tests
And much more.
Vue is one of the most popular front end JavaScript frameworks out there, and Go is quickly becoming the must-know language for developers, so learning them is definitely a benefit for any developer.
Please note that this course requires you to download Docker Desktop from Docker. If you are a Udemy Business user, please check with your employer before downloading software.