Dependency and Package Management in GoLang Microservices Apps
Reading Time: 7 Minutes
Introduction to GO
GO is a new language and thanks to GO community, it has grown rapidly since the release of GO 1.0. yet, keeping its most fundamental principle of simplicity intact.
Like other programming languages, GO has the approach for dependency management like npm in Node.js, the pip in Python.
GO user and developer have been using go get all the while. And there were many tools like godep, glide etc. available to compensate the little shortcomings of go get tool. One of the tool is glide and we will see how to use glide for package management.
But in future GO community might see a better dependency tool currently under development github.com/golang/dep.
Here I will walk through how we use different tools for managing packages in GO.
Setting up Workspace for GO
When we set up Golang, we have a single directory where $GOPATH is referencing to. This directory is our workspace, where all the thing about go begins. And the workspace structure looks like
-Work | -- bin/ | -- pkg/ | -- src/ | -- project1/ | -- project2/
bin - It contains executable commands.
pkg - It contains package objects.
src - It contains source files.
It is an environment variable which specifies the location of our workspace. Inside the directory $GOPATH/src we create a new directory for each project we start to work on.
This $GOPATH exists because:
All the import declaration in GO code references to a package through import path, and directories inside $GOPATH/src where go tool can compute all the imported packages.
To store the dependencies retrieved by go get.
Simplicity of GO GET
go get is the official GO tool to fetch GO code from a repository and store it in $GOPATH/src.
It provides isolation of packages with different import paths.
And in our source code, we just have to specify our compiler where it should go to get latest sources.
import (“fmt”“ github.com / gorilla / mux”)
Before running the code we have to import the library using go get:
go get github.com/gorilla/mux
And it will install the latest commit from the master branch of GitHub repository, these packages are not limited to GitHub.
For example golang.org/x/mobile - libraries and build tools for GO on Android.
go get always fetches the latest code for any package which is not already on the disk.
GO GET Flags
go get also uses flag instruction such as [-u, -insecure, -d, -f, -t, -fix, -v.]
The -u flag instructs get to use the network to update the named packages and their dependencies.
go get -u github.com/gorilla/mux
The -insecure flag permits fetching from repositories and resolving custom domains using insecure schemes such as HTTP.
go get -insecure github.com/name/repo
The -d flag instructs get to stop after downloading the packages; that is, it instructs get not to install the packages.
The -f flag, valid only when -u is set, forces get -u not to verify that each package has been checked out from the source control repository implied by its import path. This can be useful if the source is a local fork of the original.
The -fix flag instructs the get to run the fix tool on the downloaded packages before resolving dependencies or building the codes.
The -t flag instructs get to also download the packages required to build the tests for the specified packages.
Shortcomings in GO GET
We see that the way GO saves all its dependencies, there are some problems in this approach of dependency management like:
We won't be able to determine which version of package we need unless it is hosted in complete different repository as go get always fetches from the latest version of a package. This leads to problem when working as team we might end up fetching different version of a package.
And since go get installs package at $GOPATH/src directory so we will have to use the same version of a package for different projects as all our projects are under a single directory. So each of the projects will not have different versions of dependencies with them.
Package Management Using Glide
Now that we have seen how GO handles imports and manage packages and we also saw some of the difficulties a developer faces when handling dependencies. Let us tell you how to solve them.
There are many tools available to handle packages which have been used by GO developers like godep, glide etc. and we are going to explain the one we are using : GLIDE.
What is Glide Package?
Glide is a package management tool for GO language. It downloads dependencies from different sources and then locks the versions so that each team member gets an exact same version to download and updates the dependencies which do not break the project.
At first, we will install glide, using shell script curl https://glide.sh/get | sh
It will get the latest release of glide and the script puts it in GO binaries ($GOPATH/bin or $GOBIN).
You can also install the latest release on Mac OS X using:
$ brew install glide
And on Ubuntu Precise (12.04), Trusty (14.04), Wily (15.10) or Xenial (16.04) you can install using PPA:
$ sudo add-apt-repository ppa:masterminds/glide && sudo apt-get update
$ sudo apt-get install glide
Using Glide Initializing Dependency
Once we have installed Glide, we can go to our project folder and generate a glide.yaml file using:
package: nexdash - backend - go import: -package: github.com / gorilla / mux version: ^ 1.4 .0 - package: github.com / jinzhu / gorm version: ^ 1.0 .0 subpackages: -dialects / postgres
$ glide init
This scans the codebase in our project directory and creates a glide.yaml file containing the dependencies.
In each of the package, it reads the import in a GO file.
We can even edit glide.yaml and add information such as versions.
glide.yaml file contains two main things
It names the current package.
It declares external dependencies.
A glide.yaml file:
Here, it names the current package nexadash-backend-go and the imported libraries by it with their versions and the sub packages.
We can fetch dependency for our project and set them to specified versions in the glide.yaml file using:
$ glide up
This will install the latest dependency in the project directory matching the version information.
Glide will then create a lock file glide.lock, which contains all the dependency tree locked to specific commit ids.
Here, the dependency tree means all the dependency including sub-dependencies of dependencies.
A glide.lock file:
hash: e444b77a1ddd14f0737181e0f2dc1d4468f88db77b2e36cddde6c67547c39948 updated: 2017 - 06 - 14 T13: 56: 26.916785921 + 5: 30 imports: -name: github.com / gorilla / context version: 08 b5f424b9271eedf6f9f0ce86cb9396ed337a42 - name: github.com / gorilla / mux version: bcd8bc72b08df0f70df986b97f95590779502d31 - name: github.com / gorilla / gorm version: 5174 cc5c242a728b435ea2be8a2f7f998e15429b subpackages: -dialects / postgres - name: github.com / jinzhu / inflection version: 1 c35d901db3da928c72a72d8458480cc9ade058f - name: github.com / lib / pq version: 8837942 c3e09574accbc5f150e2c5e057189cace subpackages: -hstore - oid testImports: 
Installing Dependency in GO
Now we have a glide.lock file with all the specified dependency and versions, we use $ glide install to install versions specified in the lock file.
If we do not have glide.lock file then an update is performed before installing it.
Glide commands and their use:
$ glide init - It will initialize a new workspace and create a glide.yaml file
$ glide up - It will download or update all the libraries listed in glide.yaml file. A glide.lock file will be created with dependencies locked to specific versions.
$ glide install - It will install a specific version of dependencies listed in glide.lock file.
$ glide list - It will list all the packages that the project imports.
$ glide version - It will generate the glide version you are using.
Future of Package & Dependency Management
This is what we are more excited about the package-management and dependency-management in golang.
The go community is building dep which is an official tool for managing package and dependency and is currently in the Alpha stage of production. Find more about dep here.
XenonStack is a leading Software Company in Product Development and Solution Provider for DevOps, Big Data Integration, Real Time Analytics & Data Science.
NexaStack - Unified DevOps Platform
Product NexaStack - Unified DevOps Platform Provides monitoring of Kubernetes, Docker, OpenStack infrastructure, Big Data Infrastructure and uses advanced machine learning techniques for Log Mining and Log Analytics.
ElixirData - Modern Data Integration Platform
Product ElixirData - Modern Data Integration Platform Enables enterprises and Different agencies for Log Analytics and Log Mining.
Product Akira.AI is an Automated & Knowledge Drive Artificial Intelligence Platform that enables you to automate the Infrastructure to train and deploy Deep Learning Models on Public Cloud as well as On-Premises.