Working with Go Modules – Getting started
Development for Go Modules continues in Go 1.13 and the support GoLand has for them too. Today, we’ll have a look at how to transform our development model to use them without hassle.
This series of articles is broken down into the following sections:
- Starting with a new Go Module from scratch
- Dependencies and how to use them
- Versioning and migrating to a new major version
Let’s start by making sure that we are working with the latest version of Go. While Go 1.11 is the minimum Go version that uses Go Modules, the recent developments in Go 1.13 mean that is it better for this type of project.
The same is true for GoLand. Make sure that you have GoLand 2019.3.2 or newer installed, as this series relies on the features found in this newer version of the IDE.
Creating a new project
Once you have everything in place, start the IDE and click on the New Project option. Then, select Go Modules (vgo) and choose where to place the project. You can select any folder on the computer, as we are no longer limited to GOPATH. Then, make sure to use the latest Go SDK as mentioned above, and select whether you want to use the vendoring mode or not.
You’ll also see that there’s an option to configure the proxy. By default, GoLand uses “direct” as a value. This means that Go will connect directly to the dependency location, e.g. Github, to fetch it. However, you can also point it to your own proxy server if you work in a company that doesn’t allow direct internet connections or wants a clear record of what dependencies and versions are used. Go uses “https://proxy.golang.org,direct” as the default value, but this is overwritten by the value in the IDE proxy field.
After the project is created, the project will contain a new file called go.mod. This file is the equivalent to the package.json from Node.js or requirements.txt from Python’s pip command. It contains the name of the module, the minimum Go version the module is compatible with, and any required third-party packages.
By default, the IDE automatically sets the module name to be the name of the folder, but we can customize it to whatever we want. In this case, I’ll change it to point to the Github hosted repository, e.g., github.com/dlsniper/modulesdemo.
If we want to make this module backward compatible with previous versions of Go without using any new features, we can also change the “go” version from “go 1.13” to another version, such as “go 1.11” or “go 1.12”.
Now let’s create a new file and add some sample code. We’ll use the example below to make sure that we also get some dependencies in place.
package main import ( "log" "net/http" "time" "github.com/gorilla/mux" ) func main() { mtx := mux.NewRouter() mtx.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { _, _ = w.Write([]byte("Hello World!")) }) srv := &http.Server{ Handler: mtx, Addr: "127.0.0.1:8000", WriteTimeout: 10 * time.Second, ReadTimeout: 10 * time.Second, } log.Fatal(srv.ListenAndServe()) }
After pasting this code into the editor, the import line for “github.com/gorilla/mux” becomes red. This happens because the import is not yet included in the go.mod file, so the IDE does not have enough information about the version of the package that we are using or where to get it from the cache.
Add dependencies to the project
To download the missing dependency, move the cursor over using the F2 shortcut (Next Highlighted Error) and then press Alt+Enter to invoke the Sync packages of …. This will automatically download and install any of the missing dependencies and their related packages.
We’ll talk about how to manage dependencies later.
Running and debugging the application
When the operation finishes, everything will be green again and we can run the project as usual. To test this, let’s press Ctrl+Shift+F10 on Windows or Linux, or Cmd+Shift+R on macOS, to compile and run the application.
To test the debugging functionality, place a breakpoint on line 12, and run the debugger by pressing Alt+Shift+F9 on Windows/Linux, or Cmd+Option+D on macOS.
Given that Go modules simply offer another way to represent the dependencies of our code, the running or debugging part of our workflow remains unchanged.
This concludes the first part of our series. We’ve seen how to create a new project, add a dependency to it, and then run or debug it.
In the next article, we’ll look at how to manage our dependencies.
Thank you for reading. If you have any suggestions, questions, or would like to provide us with feedback, please use the comments section below, our issue tracker, or our Twitter account.