Matt Butcher Matt Farina FOREWORD BY Brian Ketelsen M A N N I N G Includes 70 Techniques
(This page has no text content)
Go in Practice MATT BUTCHER MATT FARINA M A N N I N G SHELTER ISLAND
For online information and ordering of this and other Manning books, please visit www.manning.com. The publisher offers discounts on this book when ordered in quantity. For more information, please contact Special Sales Department Manning Publications Co. 20 Baldwin Road PO Box 761 Shelter Island, NY 11964 Email: orders@manning.com ©2016 by Manning Publications Co. All rights reserved. No part of this publication may be reproduced, stored in a retrieval system, or transmitted, in any form or by means electronic, mechanical, photocopying, or otherwise, without prior written permission of the publisher. Many of the designations used by manufacturers and sellers to distinguish their products are claimed as trademarks. Where those designations appear in the book, and Manning Publications was aware of a trademark claim, the designations have been printed in initial caps or all caps. Recognizing the importance of preserving what has been written, it is Manning’s policy to have the books we publish printed on acid-free paper, and we exert our best efforts to that end. Recognizing also our responsibility to conserve the resources of our planet, Manning books are printed on paper that is at least 15 percent recycled and processed without the use of elemental chlorine. Manning Publications Co. Development editor: Susanna Kline 20 Baldwin Road Technical development editors: Ivan Kirkpatrick, Kim Shrier, PO Box 761 Glenn Burnside, Alain Couniot Shelter Island, NY 11964 Review editor: Aleksandar Dragosavljevic Project editor: Karen Gulliver Copy editor: Sharon Wilkey Proofreader: Melody Dolab Technical Proofreader: James Frasché Typesetter: Dottie Marsico Cover designer: Marija Tudor ISBN 9781633430075 Printed in the United States of America 1 2 3 4 5 6 7 8 9 10 – EBM – 21 20 19 18 17 16
brief contents PART 1 BACKGROUND AND FUNDAMENTALS ...............................1 1 ■ Getting into Go 3 2 ■ A solid foundation 27 3 ■ Concurrency in Go 59 PART 2 WELL-ROUNDED APPLICATIONS ....................................85 4 ■ Handling errors and panic 87 5 ■ Debugging and testing 113 PART 3 AN INTERFACE FOR YOUR APPLICATIONS ....................145 6 ■ HTML and email template patterns 147 7 ■ Serving and receiving assets and forms 168 8 ■ Working with web services 194 PART 4 TAKING YOUR APPLICATIONS TO THE CLOUD .............215 9 ■ Using the cloud 217 10 ■ Communication between cloud services 235 11 ■ Reflection and code generation 253v
(This page has no text content)
vii contents foreword xiii preface xv acknowledgments xvi about this book xviii about the authors xx about the cover illustration xxi PART 1 BACKGROUND AND FUNDAMENTALS....................1 1 Getting into Go 3 1.1 What is Go? 4 1.2 Noteworthy aspects of Go 6 Multiple return values 6 ■ A modern standard library 7 Concurrency with goroutines and channels 9 ■ Go the toolchain— more than a language 13 1.3 Go in the vast language landscape 17 C and Go 17 ■ Java and Go 18 ■ Python, PHP, and Go 19 JavaScript, Node.js, and Go 21 1.4 Getting up and running in Go 22 Installing Go 22 ■ Working with Git, Mercurial, and version control 22 ■ Exploring the workspace 23 ■ Working with environment variables 23 1.5 Hello, Go 24 1.6 Summary 25
CONTENTSviii2 A solid foundation 27 2.1 Working with CLI applications, the Go way 28 Command-line flags 28 TECHNIQUE 1 GNU/UNIX-style command-line arguments 31 Command-line frameworks 33 TECHNIQUE 2 Avoiding CLI boilerplate code 33 2.2 Handling configuration 38 TECHNIQUE 3 Using configuration files 39 TECHNIQUE 4 Configuration via environment variables 43 2.3 Working with real-world web servers 44 Starting up and shutting down a server 45 TECHNIQUE 5 Graceful shutdowns using manners 46 Routing web requests 49 TECHNIQUE 6 Matching paths to content 49 TECHNIQUE 7 Handling complex paths with wildcards 52 TECHNIQUE 8 URL pattern matching 54 TECHNIQUE 9 Faster routing (without the work) 57 2.4 Summary 58 3 Concurrency in Go 59 3.1 Understanding Go’s concurrency model 59 3.2 Working with goroutines 60 TECHNIQUE 10 Using goroutine closures 61 TECHNIQUE 11 Waiting for goroutines 63 TECHNIQUE 12 Locking with a mutex 67 3.3 Working with channels 72 TECHNIQUE 13 Using multiple channels 73 TECHNIQUE 14 Closing channels 76 TECHNIQUE 15 Locking with buffered channels 80 3.4 Summary 82 PART 2 WELL-ROUNDED APPLICATIONS ........................85 4 Handling errors and panics 87 4.1 Error handling 88 TECHNIQUE 16 Minimize the nils 90 TECHNIQUE 17 Custom error types 92 TECHNIQUE 18 Error variables 93
CONTENTS ix4.2 The panic system 95 Differentiating panics from errors 96 ■ Working with panics 97 TECHNIQUE 19 Issuing panics 97 Recovering from panics 99 TECHNIQUE 20 Recovering from panics 100 Panics and goroutines 104 TECHNIQUE 21 Trapping panics on goroutines 105 4.3 Summary 111 5 Debugging and testing 113 5.1 Locating bugs 114 Wait, where is my debugger? 114 5.2 Logging 114 Using Go’s logger 115 TECHNIQUE 22 Logging to an arbitrary writer 116 TECHNIQUE 23 Logging to a network resource 118 TECHNIQUE 24 Handling back pressure in network logging 120 Working with system loggers 123 TECHNIQUE 25 Logging to the syslog 123 5.3 Accessing stack traces 126 TECHNIQUE 26 Capturing stack traces 126 5.4 Testing 129 Unit testing 129 TECHNIQUE 27 Using interfaces for mocking or stubbing 130 TECHNIQUE 28 Verifying interfaces with canary tests 132 Generative testing 134 5.5 Using performance tests and benchmarks 136 TECHNIQUE 29 Benchmarking Go code 137 TECHNIQUE 30 Parallel benchmarks 139 TECHNIQUE 31 Detecting race conditions 141 5.6 Summary 142 PART 3 AN INTERFACE FOR YOUR APPLICATIONS.........145 6 HTML and email template patterns 147 6.1 Working with HTML templates 148 Standard library HTML package overview 148 ■ Adding functionality inside templates 150
CONTENTSxTECHNIQUE 32 Extending templates with functions 150 Limiting template parsing 152 TECHNIQUE 33 Caching parsed templates 153 When template execution breaks 154 TECHNIQUE 34 Handling template execution failures 154 Mixing templates 155 TECHNIQUE 35 Nested templates 156 TECHNIQUE 36 Template inheritance 158 TECHNIQUE 37 Mapping data types to templates 161 6.2 Using templates for email 164 TECHNIQUE 38 Generating email from templates 164 6.3 Summary 166 7 Serving and receiving assets and forms 168 7.1 Serving static content 169 TECHNIQUE 39 Serving subdirectories 171 TECHNIQUE 40 File server with custom error pages 172 TECHNIQUE 41 Caching file server 174 TECHNIQUE 42 Embedding files in a binary 176 TECHNIQUE 43 Serving from an alternative location 178 7.2 Handling form posts 180 Introduction to form requests 180 TECHNIQUE 44 Accessing multiple values for a form field 182 Working with files and multipart submissions 183 TECHNIQUE 45 Uploading a single file 183 TECHNIQUE 46 Uploading multiple files 185 TECHNIQUE 47 Verify uploaded file is allowed type 187 Working with raw multipart data 189 TECHNIQUE 48 Incrementally saving a file 189 7.3 Summary 193 8 Working with web services 194 8.1 Using REST APIs 195 Using the HTTP client 195 ■ When faults happen 196 TECHNIQUE 49 Detecting timeouts 197 TECHNIQUE 50 Timing out and resuming with HTTP 198 8.2 Passing and handling errors over HTTP 200 Generating custom errors 201
CONTENTS xiTECHNIQUE 51 Custom HTTP error passing 201 Reading and using custom errors 203 TECHNIQUE 52 Reading custom errors 204 8.3 Parsing and mapping JSON 206 TECHNIQUE 53 Parsing JSON without knowing the schema 206 8.4 Versioning REST APIs 209 TECHNIQUE 54 API version in the URL 209 TECHNIQUE 55 API version in content type 211 8.5 Summary 213 PART 4 TAKING YOUR APPLICATIONS TO THE CLOUD..............................................215 9 Using the cloud 217 9.1 What is cloud computing? 218 The types of cloud computing 218 ■ Containers and cloud-native applications 220 9.2 Managing cloud services 222 Avoiding cloud provider lock-in 222 TECHNIQUE 56 Working with multiple cloud providers 222 Dealing with divergent errors 225 TECHNIQUE 57 Cleanly handling cloud provider errors 225 9.3 Running on cloud servers 227 Performing runtime detection 227 TECHNIQUE 58 Gathering information on the host 227 TECHNIQUE 59 Detecting dependencies 229 Building for the cloud 230 TECHNIQUE 60 Cross-compiling 230 Performing runtime monitoring 232 TECHNIQUE 61 Monitoring the Go runtime 233 9.4 Summary 234 10 Communication between cloud services 235 10.1 Microservices and high availability 236 10.2 Communicating between services 237 Making REST faster 237
CONTENTSxiiTECHNIQUE 62 Reusing connections 238 TECHNIQUE 63 Faster JSON marshal and unmarshal 241 Moving beyond REST 244 TECHNIQUE 64 Using protocol buffers 244 TECHNIQUE 65 Communicating over RPC with protocol buffers 247 10.3 Summary 252 11 Reflection and code generation 253 11.1 Three features of reflection 254 TECHNIQUE 66 Switching based on type and kind 254 TECHNIQUE 67 Discovering whether a value implements an interface 258 TECHNIQUE 68 Accessing fields on a struct 262 11.2 Structs, tags, and annotations 266 Annotating structs 266 ■ Using tag annotations 267 TECHNIQUE 69 Processing tags on a struct 268 11.3 Generating Go code with Go code 274 TECHNIQUE 70 Generating code with go generate 275 11.4 Summary 280 index 281
foreword When I heard that Matt Farina and Matt Butcher were starting a new book on Go, I was excited. Both have been key contributors in the Go ecosystem for years, and have extensive work experience and backgrounds that flavor the prose in this book with the spice of past learnings. The book is intended as a spiritual successor to Go in Action, taking you beyond the basics that we introduced there and into more practical learning. The book is broken into four easily digestible parts, each with a different focus. Part 1 is a refresher on key Go concepts. If you’re in a hurry and comfortable with your Go skills, you can safely skip this section, but I discourage that. In reviewing the final manuscript, I found nuggets of such value that I think everyone would benefit from these chapters. Part 2 dives into the mechanics of managing a Go application in the real world. The chapter on errors is one of the best treatises on Go errors I’ve ever read, and the chapter on debugging and testing provides useful information on that crucial middle step of application development that takes your application from proof of concept to reliable production system. In part 3, you’ll learn about ways to create user interfaces for your application. The chapter on templates is an excellent guide to what many find to be a complicated part of Go’s ecosystem. You’ll see practical ways to reuse your templates and make your web interfaces more dry. The examples alone are worth the price of the book, as it’s difficult to find examples of template usage that can be easily mapped to a real-world application. Later, you’ll see how to create and consume a standards-compliant REST API and learn the tricks to properly versioning that API.xiii
FOREWORDxiv The final section of the book moves into the interoperability layer that’s required in nearly every application today. You’ll dive deep into cloud infrastructure and see where Go fits in the cloud-computing model. You’ll finish with great coverage of microservices and service-to-service communication patterns. Whether you’re just coming to Go or you’ve been writing Go applications for years, this book has vital knowledge that will help you take your application develop- ment to the next level. The authors do a great job of presenting complex information with a unified voice and in a manner that’s easy to digest. I’m excited for the publica- tion of this book and the value that it brings to the Go community. I hope that you’ll enjoy reading it as much as I have. —BRIAN KETELSEN CO-AUTHOR OF GO IN ACTION CO-FOUNDER OF GOPHER ACADEMY
preface When we first started using Go, we saw a language with a lot of potential. We wanted to build applications with it. But it was a new language, and many companies are wary of introducing a new programming language. This is especially true in the enterprise, where Go has the potential to have a huge impact. New languages are challenged to be trusted, accepted, and adopted. There are hundreds of thousands of developers in businesses where leaders need to be swayed to try a new language and developers need to learn it well enough to build applications and see a benefit. Open source projects, conferences, training, and books all help to make a pro- gramming language more palatable. We wanted to write a book that teaches Go in order to help the Go community, help those trying to learn Go or to convince their organizations’ leadership, and help us in the companies that we work for and with. When we first started the book, it was targeted squarely at cloud development with Go. Go is a language built for the cloud, and we’ve spent years working in cloud com- puting. Once we started working with Manning Publications, we saw an opportunity to expand beyond the cloud, into more useful and helpful patterns. And so the book shifted from being cloud-focused to pattern-focused. Yet it still retains its cloud roots. Go in Practice is our attempt to help developers move from being familiar with the language to being productive with it. To help the community of developers grow, while helping organizations write better software.xv
acknowledgments We’ve spent about two years writing this book, but none of the effort would have been possible without the commitment of our families. They’ve supported us through the early mornings, late nights, and weekends when we were focused on writing. They were there as we were fixated on solving problems, even when we weren’t sitting down to write. Good code is never created in a vacuum. We’re also grateful to the women and men of the Go community who have so generously given their time to create a great language, great libraries, and a thriving ecosystem. It has been exciting to be a part of such a diverse, burgeoning community of developers. In particular, Rob Pike, Brian Ketelsen, and Dave Cheney all reached out to us early in our Go learning process. They’re admirable ambassadors of the language. Special thanks to Brian for contrib- uting the foreword to the book and for endorsing our work. We appreciate the many individuals who gave time and effort to the creation of this book. It has been an arduous process, and thanks to many careful readers, includ- ing our MEAP readers, we found and corrected numerous mistakes. We’d like to thank everyone at Manning, especially our development editor, Susanna Kline; our technical development editors, Ivan Kirkpatrick, Kim Shrier, Glenn Burnside, and Alain Couniot; and our technical proofreader, James Frasché; as well as everyone who worked on our book behind the scenes. Thanks also to the many reviewers who took the time to read our manuscript at various stages of its develop- ment and who provided invaluable feedback: Anthony Cramp, Austin Riendeau, Brandon Titus, Doug Sparling, Ferdinando Santacroce, Gary A. Stafford, Jim Amrhein, Kevin Martin, Nathan Davies, Quintin Smith, Sam Zaydel, and Wes Shaddix. Finally, we owe a debt of gratitude to the Glide community, which has grown with us as we worked to build a top-tier package manager for Go. Thank you for your support.xvi
ACKNOWLEDGMENTS xviiMatt Butcher I began writing this book at Revolv, continued when Google/Nest acquired us, and finished at Deis. Thanks to all three for supporting the writing of this book. Thanks to Brian Hardock, Cristian Cavalli, Lann Martin, and Chris Ching, all of whom served as early sounding boards. Matt Boersma provided helpful feedback for several chapters. Kent Rancourt and Aaron Schlesinger each inspired particular code examples in this book. Matt Fisher, Sivaram Mothiki, Keerthan Mala, Helgi Þorbjörnsson (yes, Helgi, I copied and pasted that), Gabe Monroy, Chris Armstrong, Sam Boyer, Jeff Bleiel, Joshua Anderson, Rimas Mocevicius, Jack Francis, and Josh Lane all (wittingly or unwittingly) influenced specific portions of this book. The impact of Michelle Noorali and Adam Reese cannot be understated; I’ve learned a lot watching a couple of Ruby developers master Go. And thanks to Angie, Annabelle, Claire, and Katherine for their unflagging support and understanding. Matt Farina I would like to thank Kristin, my beautiful and amazing wife, along with our wonderful daughters, Isabella and Aubrey, for their love and support. I wrote this book while working at Hewlett Packard Enterprise, formerly Hewlett- Packard. Working at HPE has taught me invaluable lessons while providing me with the opportunity to work alongside and learn from those far wiser than myself. Specifi- cally, I need to thank Rajeev Pandey, Brian Aker, Steve McLellan, Erin Handgen, Eric Gustafson, Mike Hagedorn, Susan Balle, David Graves, and many others. They have affected the way I write and operate applications, and that has shown up in these chapters in subtle ways. There have been many others who influenced portions of this book, sometimes without realizing it. Thanks to Tim Pletcher, Jason Buberel, Sam Boyer, Larry Gar- field, and all those I may have forgotten who had a positive influence. Finally, I want to thank Matt Butcher. I never imagined authoring books until you suckered me into it. Thanks!
about this book Go in Practice is a book about practical development using the Go programming lan- guage. Developers already familiar with the basics of Go will find patterns and tech- niques for creating Go applications. Chapters are organized around central themes (for example, chapter 10, “Communicating between cloud services”), but then explore a variety of techniques related to that theme. How the book is organized The 11 chapters are divided into four parts. Part 1, “Background and fundamentals,” provides a foundation for building appli- cations. Chapter 1 provides the background of Go for those not already familiar with it or those with a passing understanding who would like to learn more. Building con- sole applications and servers is the topic of chapter 2, and concurrency in Go is the topic of chapter 3. Part 2, “Well-rounded applications,” contains chapters 4 and 5. These chapters cover errors, panics, debugging, and testing. The goal of this section is to build appli- cations you trust that handle problems well. Part 3, “An interface for your applications,” contains three chapters with topics ranging from generating HTML and to serving assets to providing and working with APIs. Many Go applications provide web applications and REST APIs for interaction. These chapters cover patterns to aid in their construction. Part 4, “Taking your applications to the cloud,” contains the remaining chapters, which focus on cloud computing and generating code. Go is a language built with cloud needs in mind. This section showcases patterns that enable working with those services and operating applications, sometimes as microservices, in them. It also cov- ers generating code and metaprogramming.xviii
ABOUT THIS BOOK xix There are 70 techniques explored in the book, each with its own Problem, Solu- tion, and Discussion sections. Code conventions and downloads All source code in the book is presented in a mono-spaced typeface like this, which sets it off from the surrounding text. In many listings, the code is annotated to point out key concepts, and numbered bullets are sometimes used in the text to provide additional information about the code. Source code for the examples in the book is available for download from the pub- lisher’s website at www.manning.com/books/go-in-practice and from GitHub at github.com/Masterminds/go-in-practice. Author Online Forum The purchase of Go in Practice includes free access to a private web forum run by Man- ning Publications, where you can make comments about the book, ask technical ques- tions, and receive help from the authors and from other users. To access the forum and subscribe to it, point your web browser to www.manning.com/books/go-in-practice. This page provides information on how to get on the forum after you’re registered, what kind of help is available, and the rules of conduct on the forum. Manning’s commitment to our readers is to provide a venue where a meaningful dialogue between individual readers and between readers and the authors can take place. It’s not a commitment to any specific amount of participation on the part of the authors, whose contribution to the forum remains voluntary (and unpaid). We sug- gest you try asking the authors some challenging questions lest their interest stray! The Author Online forum and the archives of previous discussions will be accessi- ble from the publisher’s website as long as the book is in print.
Comments 0
Loading comments...
Reply to Comment
Edit Comment