(This page has no text content)
Let’s Go teaches you step-by-step how to create fast, secure and maintainable web applications using the fantastic programming language Go. The idea behind this book is to help you learn by doing. Together we’ll walk through the start-to-finish build of a web application — from structuring your workspace, through to session management, authenticating users, securing your server and testing your application. Building a complete web application in this way has several benefits. It helps put the things you’re learning into context, it demonstrates how different parts of your codebase link together, and it forces us to work through the edge-cases and difficulties that come up when writing software in real-life. In essence, you’ll learn more that you would by just reading Go’s (great) documentation or standalone blog posts. By the end of the book you’ll have the understanding — and confidence — to build your own production-ready web applications with Go. Although you can read this book cover-to-cover, it’s designed specifically so you can follow along with the project build yourself. Break out your text editor, and happy coding! — Alex
Contents 1. Introduction 2. Foundations 2.1. Installing Go 2.2. Project Setup and Enabling Modules 2.3. Web Application Basics 2.4. Routing Requests 2.5. Customizing HTTP Headers 2.6. URL Query Strings 2.7. Project Structure and Organization 2.8. HTML Templating and Inheritance 2.9. Serving Static Files 2.10. The http.Handler Interface 3. Configuration and Error Handling 3.1. Managing Configuration Settings 3.2. Leveled Logging 3.3. Dependency Injection 3.4. Centralized Error Handling 3.5. Isolating the Application Routes 4. Database-Driven Responses 4.1. Setting Up MySQL
4.2. Installing a Database Driver 4.3. Creating a Database Connection Pool 4.4. Designing a Database Model 4.5. Executing SQL Statements 4.6. Single-record SQL Queries 4.7. Multiple-record SQL Queries 4.8. Transactions and Other Details 5. Dynamic HTML Templates 5.1. Displaying Dynamic Data 5.2. Template Actions and Functions 5.3. Caching Templates 5.4. Catching Runtime Errors 5.5. Common Dynamic Data 5.6. Custom Template Functions 6. Middleware 6.1. How Middleware Works 6.2. Setting Security Headers 6.3. Request Logging 6.4. Panic Recovery 6.5. Composable Middleware Chains 7. RESTful Routing 7.1. Installing a Router 7.2. Implementing RESTful Routes 8. Processing Forms
8.1. Setting Up a Form 8.2. Parsing Form Data 8.3. Data Validation 8.4. Scaling Data Validation 9. Stateful HTTP 9.1. Installing a Session Manager 9.2. Setting Up the Session Manager 9.3. Working with Session Data 10. Security Improvements 10.1. Generating a Self-Signed TLS Certificate 10.2. Running a HTTPS Server 10.3. Configuring HTTPS Settings 10.4. Connection Timeouts 11. User Authentication 11.1. Routes Setup 11.2. Creating a Users Model 11.3. User Signup and Password Encryption 11.4. User Login 11.5. User Logout 11.6. User Authorization 11.7. CSRF Protection 12. Using Request Context 12.1. How Request Context Works 12.2. Request Context for Authentication/Authorization
13. Testing 13.1. Unit Testing and Sub-Tests 13.2. Testing HTTP Handlers 13.3. End-To-End Testing 13.4. Mocking Dependencies 13.5. Testing HTML Forms 13.6. Integration Testing 13.7. Profiling Test Coverage 14. Conclusion 15. Appendices 15.1. How HTTPS Works 15.2. Further Reading and Useful Links
Chapter 1. Introduction In this book we’ll be building a web application called Snippetbox, which lets people paste and share snippets of text — a bit like Pastebin or GitHub’s Gists. Towards the end of the build it will look a bit like this: Our application will start off super simple, with just one web page. Then with each chapter we’ll build it up step-by-step until a user is able save and view snippets via the app. This will take us through topics like how to
structure a project, routing requests, working with a database, processing forms and displaying dynamic data safely. Then later in the book we’ll add user accounts, and restrict the application so that only registered users can create snippets. This will take us through more advanced topics like configuring a HTTPS server, session management, user authentication and middleware. Prerequisites This book is designed for people who are new to Go, but you’ll probably find it more enjoyable if you have a general understanding of Go’s syntax first. If you find yourself struggling with the syntax, the Little Book of Go by Karl Seguin is a fantastic tutorial, or if you want something more interactive I recommend running through the Tour of Go. I’ve also assumed that you’ve got a (very) basic understanding of HTML/CSS and SQL, and some familiarity with using your terminal (or command line for Windows users). If you’ve built a web application in any other language before — whether it’s Ruby, Python, PHP or C# — then this book should be a good fit for you. In terms of software, you’ll need a working installation of Go (version 1.11 or newer). We’ll also use Curl in a few places throughout the book to inspect the responses that our application sends. This should be pre-installed on most Macs, and Linux/Unix users should find in their package repositories as curl. Windows users can download it from here.
Conventions Throughout this book code blocks are shown with a silver background like below. If the code is particularly long, parts that aren’t relevant may be replaced with an ellipsis. To make it easy to follow along, most code blocks also have a title bar at the top indicating the name of the file that we’re working on. File: hello.go package main ... // Indicates that some existing code has been omitted. func sayHello() { fmt.Println("Hello world!") } Terminal (command line) instructions are show with a black background and start with a dollar symbol. These commands should work on any Unix-based operating system, including Mac OSX and Linux. Sample output is shown in silver beneath the command. $ echo "Hello world!" Hello world! If you’re using Windows, you should replace the command with the DOS equivalent or carry out the action via the normal Windows GUI.
Some chapters in this book end with an additional information section. These sections contain information that isn’t relevant to our application build, but is still important (or sometimes, just interesting) to know about. If you’re very new to Go, you might want to skip these parts and circle back to them later. About the Author Hey, I’m Alex Edwards, a full-stack web developer. I began working with Go 6 years ago in 2013, and have been teaching people and writing about the language for nearly as long. I’ve used Go to build a variety of production applications, from simple websites to high-frequency trading systems. I also maintain several open- source Go packages, including the popular session management system SCS. I live near Innsbruck, Austria. You can follow me on GitHub, Instagram, Twitter and on my blog. Copyright and Disclaimer Let’s Go: Learn to build professional web applications with Go. Copyright © 2019 Alex Edwards. Published by Brandberg Ltd. Last updated 2019-02-10 17:52:56 UTC. Version 1.2.11. The Go gopher was designed by Renee French and is used under the Creative Commons 3.0 Attributions license.
The information provided within this book is for general informational purposes only. While the author and publisher have made every effort to ensure the accuracy of the information within this book was correct at time of publication there are no representations or warranties, express or implied, about the completeness, accuracy, reliability, suitability or availability with respect to the information, products, services, or related graphics contained in this book for any purpose. Any use of this information is at your own risk.
Chapter 2. Foundations Alright, let’s get started! In this first section of the book we’re going to lay the groundwork for our project and explain the main principles that you need to know for the rest of the application build. You’ll learn how to: Setup a project repository which follows the Go conventions. Start a web server and listen for incoming HTTP requests. Route requests to different handlers based on the request path. Send different HTTP responses, headers and status codes to users. Fetch and validate untrusted user input from URL query string parameters. Structure your project in a sensible and scalable way. Render HTML pages and use template inheritance to keep your markup DRY and free of boilerplate. Serve static files like images, CSS and JavaScript from your application.
Chapter 2.1. Installing Go If you’d like to code along with this book, you’ll need Go version 1.11 installed on your computer. As well as generally being the latest and greatest version of Go, the 1.11 release ships with support for modules — which are Go’s new way to manage and version control any external packages used by your project. If you’ve already got Go installed, you can check which version you have from your terminal by using the go version command. The output should look similar to this: $ go version go version go1.11 linux/amd64 If you need to upgrade your version of Go — or install Go from scratch — then please go ahead and do that now. Detailed instructions for different operating systems can be found here: Removing an old version of Go Installing Go on Mac OS X Installing Go on Windows Installing Go on Linux
Chapter 2.2. Project Setup and Enabling Modules Before we write any code, you’ll need to first set up a project directory (also known as a repository) on your computer which follows the Go conventions. This directory will act as the top-level ‘home’ for our Snippetbox project throughout this book — all the Go code we write will live in there, along with other project-specific assets like HTML templates and CSS files. So where should this project directory live, and what should we call it? Open a terminal window and run the go env command to get the information about your current Go installation and environment. The output should look something like this: $ go env GOARCH="amd64" GOBIN="" GOCACHE="/home/alex/.cache/go-build" GOEXE="" GOFLAGS="" GOHOSTARCH="amd64" GOHOSTOS="linux" GOOS="linux" GOPATH="/home/alex/go"
The important thing to look at here is the GOPATH value — which in my case is the directory /home/alex/go. For older versions of Go (pre-1.11) it was best practice to locate your project repositories within a src folder under your GOPATH directory. But if you’re running Go 1.11 and using modules to manage your dependencies — like we will be in this book — then this rule no longer applies. You can create your project repository anywhere on your computer, and it’s actually simplest if you locate it outside of your GOPATH directory. So, if you’re following along, open your terminal and run the following commands to create a new project directory called snippetbox. I’m GOPROXY="" GORACE="" GOROOT="/usr/local/go" GOTMPDIR="" GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64" GCCGO="gccgo" CC="gcc" CXX="g++" CGO_ENABLED="1" GOMOD="" CGO_CFLAGS="-g -O2" CGO_CPPFLAGS="" CGO_CXXFLAGS="-g -O2" CGO_FFLAGS="-g -O2" CGO_LDFLAGS="-g -O2" PKG_CONFIG="pkg-config" GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-bu
going to locate this under $HOME/code, but you can choose a different location if you wish. $ mkdir -p $HOME/code/snippetbox While we’re at it, let’s also add an empty main.go file to the project directory: $ cd $HOME/code/snippetbox $ touch main.go Enabling Modules The next thing we need to do is let Go know that we want to use the new modules functionality to help manage (and version control) any third- party packages that our project imports. To do this we first need to decide what the module path for our project should be. The important thing here is uniqueness. To avoid potential import conflicts with other people’s packages or the standard library in the future, you want to choose a module path that is globally unique and unlikely to be used by anything else. In the Go community, a common convention is to namespace your module paths by basing them on a URL that you own.
In my case a clear, succinct and unlikely-to-be-used-by-anything-else module path for this project would be alexedwards.net/snippetbox, and we’ll use this throughout the rest of the book. If possible, you should swap this for something that’s unique to you instead. Now that we’ve decided a unique module path let’s enable modules for the project. To do this make sure that you’re in the root of your project directory, and then run the go mod init command — passing in your module path as a parameter like so: $ cd $HOME/code/snippetbox $ go mod init alexedwards.net/snippetbox go: creating new go.mod: module alexedwards.net/snippetbox At this point your project directory should look a bit like the screenshot below. Notice the go.mod file which has been created?
At the moment there’s not much going on in this file, and if you open it up in your text editor it should look like this (but preferably with your own unique module path instead): File: mod.go module alexedwards.net/snippetbox Later in our build we’ll see how this file is used to define the third-party packages (and their versions) which are required by our project. Additional Information
Module Paths for Downloadable Packages If you’re creating a package or application which can be downloaded and used by other people and programs, then it’s good practice for your module path to equal the location that the code can be downloaded from. For instance, if your package is hosted at https://github.com/foo/bar then the module path for the project should be github.com/foo/bar.
Chapter 2.3. Web Application Basics Now that everything is set up correctly let’s make the first iteration of our web application. We’ll begin with the three absolute essentials: The first thing we need is a handler. If you’re coming from an MVC- background, you can think of handlers as being a bit like controllers. They’re responsible for executing your application logic and for writing HTTP response headers and bodies. The second component is a router (or servemux in Go terminology). This stores a mapping between the URL patterns for your application and the corresponding handlers. Usually you have one servemux for your application containing all your routes. The last thing we need is a web server. One of the great things about Go is that you can establish a web server and listen for incoming requests as part of your application itself. You don’t need an external third-party server like Nginx or Apache. Let’s put these components together in the main.go file to make a working application. File: main.go
Comments 0
Loading comments...
Reply to Comment
Edit Comment