First App with Go

We will begin our first app using the Go language, which we will name example

Create Project Directory

To begin the project, we need to create a new directory and initialize a Go project:

mkdir example
cd $_
go mod init $_
In shell console the symbol $_ refers to the last argument from the previous command

In the project directory, will be created file go.mod it contains the specific versions of the dependencies used in the project. This files generated automatically.

Entry Point

Entry point in most programming languages is a main function. Make directory to store an application main function:

mkdir -p cmd/example

In any text editor create file cmd/example/main.go:

package main

import (
    "fmt"
)

func main() {
    fmt.Println("Hello, world!")
}

Save file and run your project:

go run ./cmd/example

Components

Component is a collection of functions and object that implement the application's logic. Let's modify our code and move application logic into component.

Create new directory:

mkdir -p internal/app

In text editor create file internal/app/app.go:

package app

import (
    "fmt"
)

func Start() error {
    fmt.Println("Hello, world!")
    return nil
}

All source files in the component directory should start with the component name on the first line.

Modify main file to use component:

package main

import (
    "log"
    "os"

    "example/internal/app"
)

func main() {
    arg := ""
    if len(os.Args) > 1 {
        arg = os.Args[1]
    }

    switch arg {
    case "-v", "--version":
        log.Println("Example App v0.0.1")
    default:
        log.Println("Starting Example App")
        if err := app.Start(); err != nil {
            log.Fatal(err)
        }
    }
}

New version checks command line arguments and print version number if requested. Otherwise it starts our application. In case of error prints error description into console.

Install Dependencies

For example we append SQLite3 to our project:

go get github.com/mattn/go-sqlite3

Link to dependency will be added into go.mod file with the indirect mark, it means that dependency is not used in code. Also will be created file go.sum with dependencies checksums to ensures the integrity and authenticity of the module's dependencies.

For database we create additional component:

mkdir -p internal/base

The base component will be used to provide shared objects across other modules.

Now we can use SQLite3 in the application code, open internal/base/db.go in text editor and write code to initialize database on the application start:

package base

import (
    "database/sql"
    _ "github.com/mattn/go-sqlite3"
)

var (
    DB *sql.DB
)

func OpenDB() error {
    db, err := sql.Open("sqlite3", ":memory:")
    if err != nil {
        return err
    }

    DB = db
    return nil
}

func CloseDB() {
    _ = DB.Close()
    DB = nil
}

Done. Now we used dependencies in code and can run:

go mod tidy

This command clean up go.mod file. If some dependency is not used in code it will be removed from file.

And finally we can open our database on application start. Modify file internal/app/app.go:

package app

import (
    "hello/internal/base"
)

func Start() error {
    if err := base.OpenDB(); err != nil {
        return err
    }

    // here, we can use base.DB global variable

    return nil
}

Update Dependencies

Check available dependencies with command:

go list -u -m all

In row will be dependency name, current version, and in square brackets new version if exist. To update all dependencies at once you may launch command:

go get -u ./...

Read more