Web Development with Go v2 (Current Version)
Learn to build real, production-grade web applications from scratch. No trivial TODO apps that barely touch the complexity of a real app. No frameworks that hide all the details. In this course we build and deploy a photo sharing application complete with users, authentication, image uploads, a database, and more. We even deploy to a production server and set up automatic HTTPS.
More
Web Development with Go is the course I wish I had
This course takes everything I have learned over years of building web applications and distills it into easy to consume lessons. By the end of the course you will build a complete web application, deploy it to a production server, and understand why you took every step along the way. You will also...
- Know exactly how to initialize your database connection and share it without resorting to global variables or other hard to test anti-patterns.
- Feel confident saying, "Yes, my authentication system is safe and secure!"
- Understand how to organize your code, and how to weigh the trade-offs of various code structures.
- Have clear examples of how to email users and build a complete "Forgot your password?" workflow.
- And so much more!
This is possible because this is not your run of the mill course. It is a comprehensive breakdown of every little detail you need to know when building and deploying a real web application.
Watch Online Web Development with Go v2 (Current Version)
# | Title | Duration |
---|---|---|
1 | A Basic Web Application | 06:06 |
2 | Troubleshooting and Slack | 12:04 |
3 | Packages and Imports | 04:59 |
4 | Editors and Automatic Imports | 04:53 |
5 | The "Hello, world" Part of our Code | 04:10 |
6 | Web Requests | 09:15 |
7 | HTTP Methods | 04:52 |
8 | Our Handler Function | 10:05 |
9 | Registering our Handler Function and Starting the Web Server | 08:28 |
10 | Go Modules | 13:45 |
11 | Dynamic Reloading | 11:37 |
12 | Setting Header Values | 08:24 |
13 | Creating a Contact Page | 08:12 |
14 | Examining the http.Request Type | 05:48 |
15 | Custom Routing | 04:20 |
16 | URL Path vs RawPath | 06:54 |
17 | Not Found Page | 08:50 |
18 | The http.Handler Type | 10:09 |
19 | The http.HandlerFunc Type | 12:09 |
20 | Exploring Handler Conversions | 08:19 |
21 | FAQ Exercise | 06:07 |
22 | Router Requirements | 09:11 |
23 | Using Git | 06:41 |
24 | Installing Chi | 03:55 |
25 | Using Chi | 08:56 |
26 | Chi Exercises | 02:01 |
27 | What are Templates? | 05:55 |
28 | Why Do We Use Server Side Rendering? | 16:02 |
29 | Creating Our First Template | 16:23 |
30 | Cross Site Scripting (XSS) | 10:27 |
31 | Alternative Template Libraries | 03:39 |
32 | Contextual Encoding | 06:13 |
33 | Home Page via Template | 16:53 |
34 | Contact Page via Template | 10:53 |
35 | FAQ Page via Template | 03:29 |
36 | Template Exercises | 07:28 |
37 | Code Organization | 16:36 |
38 | MVC Overview | 09:25 |
39 | Walking Through a Web Request with MVC | 07:52 |
40 | MVC Exercises | 04:58 |
41 | Creating the Views Package | 10:59 |
42 | fmt.Errorf | 08:48 |
43 | Validating Templates at Startup | 13:08 |
44 | Must Functions | 10:45 |
45 | Exercises | 04:48 |
46 | Embedding Template Files | 14:09 |
47 | Variadic Parameters | 08:02 |
48 | Named Templates | 06:52 |
49 | Dynamic FAQ Page | 12:34 |
50 | Reusable Layouts | 13:20 |
51 | Tailwind CSS | 09:16 |
52 | Utility-first CSS | 16:22 |
53 | Adding a Navigation Bar | 14:30 |
54 | Exercises | 03:48 |
55 | Creating the Signup Page | 13:15 |
56 | Styling the Signup Page | 14:19 |
57 | Intro to REST | 16:20 |
58 | Users Controller | 08:22 |
59 | Decouple with Interfaces | 06:22 |
60 | Parsing the Signup Form | 14:00 |
61 | URL Query Parameters | 11:34 |
62 | Exercises | 04:02 |
63 | Intro to Databases | 15:11 |
64 | Installing Postgres | 15:44 |
65 | Connecting to Postgres | 10:43 |
66 | Update: Docker Container Names | 02:52 |
67 | Creating SQL Tables | 08:44 |
68 | Postgres Data Types | 05:52 |
69 | Postgres Constraints | 07:20 |
70 | Creating a Users Table | 03:11 |
71 | Inserting Records | 08:00 |
72 | Querying Records | 03:07 |
73 | Filtering Queries | 03:51 |
74 | Updating Records | 03:50 |
75 | Deleting Records | 02:38 |
76 | Additional SQL Resources | 03:43 |
77 | Connecting to Postgres with Go | 14:15 |
78 | Imports with Side Effects | 09:05 |
79 | Postgres Config Type | 05:47 |
80 | Executing SQL with Go | 08:53 |
81 | Inserting Records with Go | 04:41 |
82 | SQL Injection | 09:15 |
83 | Acquire a new Record's ID | 08:26 |
84 | Querying a Single Record | 06:20 |
85 | Creating Sample Orders | 04:12 |
86 | Querying Multiple Records | 09:10 |
87 | ORMs vs SQL | 12:56 |
88 | Exercises | 02:36 |
89 | Syncing the Book and Screencasts Source Code | 03:28 |
90 | Steps for Securing Passwords | 08:41 |
91 | Third Party Authentication Options | 05:30 |
92 | What is a Hash Function? | 14:29 |
93 | Store Password Hashes, Not Encrypted or Plaintext Values | 07:30 |
94 | Salt Passwords | 10:42 |
95 | Learning bcrypt with a CLI | 10:15 |
96 | Hashing Passwords with bcrypt | 10:36 |
97 | Comparing a Password with a bcrypt Hash | 05:59 |
98 | Defining the User Model | 08:06 |
99 | Creating the UserService | 06:37 |
100 | Create User Method | 16:29 |
101 | Postgres Config for the Models Package | 07:46 |
102 | UserService in the Users Controller | 04:22 |
103 | Create Users on Signup | 06:56 |
104 | Sign In View | 05:30 |
105 | Authenticate Users | 06:39 |
106 | Process Sign In Attempts | 04:31 |
107 | Stateless Servers | 13:08 |
108 | Creating Cookies | 09:57 |
109 | Viewing Cookies with Chrome | 05:13 |
110 | Viewing Cookies with Go | 09:32 |
111 | Securing Cookies from XSS | 06:57 |
112 | Cookie Theft | 10:06 |
113 | CSRF Attacks | 12:32 |
114 | CSRF Middleware | 16:54 |
115 | Providing CSRF to Templates via Data | 05:57 |
116 | Custom Template Functions | 08:19 |
117 | Adding the HTTP Request to Execute | 10:15 |
118 | Request Specific CSRF Template Function | 10:23 |
119 | Template Function Errors | 09:05 |
120 | Securing Cookies from Tampering | 11:46 |
121 | Random Strings with crypto/rand | 11:03 |
122 | Exploring math/rand | 05:52 |
123 | Wrapping the crypto/rand Package | 08:40 |
124 | Why Do We Use 32 Bytes for Session Tokens? | 09:14 |
125 | Defining the Sessions Table | 07:36 |
126 | Stubbing the SessionService | 10:23 |
127 | Sessions in the Users Controller | 15:57 |
128 | Cookie Helper Functions | 08:07 |
129 | Create Session Tokens | 07:19 |
130 | Refactor the rand Package | 07:01 |
131 | Hash Session Tokens | 11:55 |
132 | Insert Sessions into the Database | 05:44 |
133 | Updating Existing Sessions | 08:54 |
134 | Querying Users via Session Token | 07:26 |
135 | Deleting Sessions | 03:50 |
136 | Sign Out Handler | 07:58 |
137 | Sign Out Link | 05:28 |
138 | SQL Relationships | 10:40 |
139 | Foreign Keys | 07:52 |
140 | On Delete Cascade | 02:41 |
141 | Inner Join | 06:06 |
142 | Left, Right, and Full Outer Join | 06:52 |
143 | Using Join in the SessionService | 10:05 |
144 | SQL Indexes | 10:45 |
145 | Creating PostgreSQL Indexes | 03:58 |
146 | On Conflict | 05:53 |
147 | What Are Schema Migrations? | 09:56 |
148 | How Schema Migration Tools Work | 09:17 |
149 | Installing pressly/goose | 09:22 |
150 | Converting to Schema Migrations | 04:32 |
151 | Schema Versioning Problem | 12:19 |
152 | Running Goose with Go | 10:59 |
153 | Embedding Migrations | 06:57 |
154 | Go Migration Files | 09:12 |
155 | Removing Old SQL Files | 01:35 |
156 | Using Context to Store Values | 09:06 |
157 | Improved Context Keys | 08:13 |
158 | Context Values with Types | 07:44 |
159 | Storing Users as Context Values | 09:36 |
160 | Reading Request Context Values | 08:32 |
161 | Set the User via Middleware | 14:33 |
162 | Requiring a User via Middleware | 16:17 |
163 | Accessing the Current User in Templates | 07:48 |
164 | Request-Scoped Values | 06:10 |
165 | Password Reset Overview | 07:35 |
166 | SMTP Services | 10:48 |
167 | Building Emails with SMTP | 10:43 |
168 | Sending Emails with SMTP | 06:01 |
169 | Building an Email Service | 06:49 |
170 | EmailService.Send | 11:15 |
171 | Forgot Password Email | 05:05 |
172 | ENV Variables | 15:48 |
173 | Password Reset DB Migration | 05:07 |
174 | Password Reset Service Stubs | 11:28 |
175 | Forgot Password HTTP Handler | 12:50 |
176 | Asynchronous Emails | 05:59 |
177 | Forgot Password HTML Template | 07:53 |
178 | Initializing Services with ENV Vars | 14:21 |
179 | Check Your Email HTML Template | 05:18 |
180 | Reset Password HTTP Handlers | 08:06 |
181 | Reset Password HTML Template | 06:41 |
182 | Update Password Function | 04:24 |
183 | PasswordReset Creation | 13:10 |
184 | Implementing Consume | 13:20 |
185 | Inspecting Errors | 13:06 |
186 | Inspecting Wrapped Errors | 09:25 |
187 | Designing the Alert Banner | 06:37 |
188 | Dynamic Alerts | 03:54 |
189 | Removing Alerts with JavaScript | 04:13 |
190 | Detecting Existing Emails | 12:19 |
191 | Accepting Errors in Templates | 10:25 |
192 | Public vs Internal Errors | 09:39 |
193 | Creating Public Errors | 09:57 |
194 | Using Public Errors | 07:37 |
195 | Galleries Overview | 12:01 |
196 | Gallery Model and Migration | 06:19 |
197 | Creating Gallery Records | 05:01 |
198 | Querying for Galleries by ID | 05:27 |
199 | Querying Galleries by UserID | 06:09 |
200 | Updating Gallery Records | 01:59 |
201 | Deleting Gallery Records | 01:55 |
202 | New Gallery Handler | 06:27 |
203 | views.Template Name Bug | 13:07 |
204 | New Gallery Template | 08:34 |
205 | Gallery Routing and CSRF Bug Fixes | 09:29 |
206 | Create Gallery Handler | 06:46 |
207 | Edit Gallery Handler | 08:20 |
208 | Edit Gallery Template` | 07:54 |
209 | Update Gallery Handler | 05:34 |
210 | Gallery Index Handler | 10:48 |
211 | Discovering and Fixing a Gallery Index Bug | 04:36 |
212 | Gallery Index Template Continued | 14:57 |
213 | Show Gallery Handler | 08:34 |
214 | Show Gallery Template and a Tailwind Update | 07:09 |
215 | Extracting Common Gallery Code | 13:02 |
216 | Extra Gallery Checks with Functional Options | 10:39 |
217 | Delete Gallery Handler | 06:24 |
218 | Images Overview | 14:56 |
219 | Setting Up Test Images | 04:34 |
220 | Adding the ImagesDir to the GalleryService | 05:04 |
221 | Globbing Image Files | 12:45 |
222 | Adding Filename and GalleryID to the Image Type | 03:22 |
223 | Adding Images to the Show Gallery Page | 06:22 |
224 | Show Image Handler | 08:44 |
225 | Querying for a Single Image | 06:39 |
226 | URL Path Escaping Image Filenames | 06:40 |
227 | Adding Images to the Edit Gallery Page | 05:43 |
228 | Delete Image Form | 06:09 |
229 | Delete Image Service Func | 03:16 |
230 | Delete Image Handler | 06:54 |
231 | Checking for Filename Vulnerabilities | 09:17 |
232 | Upload Image Form | 11:06 |
233 | Image Upload Handler | 12:49 |
234 | Creating Images in the GalleryService | 12:47 |
235 | Detecting Content Type | 13:13 |
236 | Rendering Content Type Errors | 10:12 |
237 | Deleting Images on Gallery Deletion | 05:05 |
238 | Redirect to Galleries After Auth | 01:43 |
239 | Loading All Config via ENV | 14:19 |
240 | Docker Compose Overrides | 14:02 |
241 | Building Tailwind Locally | 12:39 |
242 | Tailwind Via Docker | 13:16 |
243 | Serving Static Assets | 08:16 |
244 | Making main Easier to Test | 04:16 |
245 | Running our Go Server via Docker | 12:10 |
246 | Multi-Stage Docker Builds | 07:32 |
247 | Tailwind Production Build | 04:35 |
248 | Caddy Server via Docker | 08:00 |
249 | Creating a Digital Ocean Droplet | 09:24 |
250 | Setting up DNS | 06:35 |
251 | Installing Git on the Server | 04:19 |
252 | Setting Up a Bare Git Repo | 06:37 |
253 | Setting Up a Local Git Repo | 05:33 |
254 | Checking Out Our Code on the Server | 03:21 |
255 | Email Sending Server Setup | 02:59 |
256 | Production .env File | 04:54 |
257 | Install Docker in Prod | 04:36 |
258 | Production Caddyfile | 02:23 |
259 | Production Data Directories | 05:17 |
260 | Running Our App in Prod | 07:57 |
261 | Post-receive Deploy Updates | 06:56 |
262 | Deploy via Git | 07:39 |
263 | Logging Services | 10:51 |
264 | Intro to OAuth | 13:39 |
265 | OAuth Example Code | 14:41 |
266 | Dropbox App Setup | 10:30 |
267 | Offline OAuth Demo | 21:28 |
268 | OAuth Tokens | 07:07 |
269 | Online vs Offline Access Types | 06:50 |
270 | Redirect URIs | 06:50 |
271 | OAuth Connect HTTP Handler | 09:02 |
272 | Determine Redirect URI Host | 04:04 |
273 | OAuth Routes and Config Setup | 07:47 |
274 | OAuth Callback Handler | 10:20 |
275 | Testing OAuth with API Calls | 06:56 |
276 | Dropbox Chooser Overview | 07:26 |
277 | Embedding the Dropbox Chooser | 10:09 |
278 | Images via Dropbox Form | 07:21 |
279 | Chooser Success Function | 06:30 |
280 | Images Via URL Handler | 08:11 |
281 | Downloading Images | 11:36 |
282 | Creating Images Without Seek | 07:50 |
283 | Concurrent Downloads | 12:31 |
284 | Using errgroup | 06:04 |
285 | Page Specific JS | 08:57 |
Read Book Web Development with Go v2 (Current Version)
# | Title |
---|---|
1 | Book 1 |