summaryrefslogtreecommitdiff
path: root/learn/golang/README.md
blob: 6561585db3df7b21a942c6fbcde2bf9c1edac87f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# Go lang (The Go Programming Language)

To get proficient with Golang you must read the docs.

* [How to Write Go Code](https://go.dev/doc/code)
* [Effective Go](https://go.dev/doc/effective_go)
* [Learn Go with Tests](https://quii.gitbook.io/learn-go-with-tests)

## Conventions

When structuring your directories use the `cmd` directory to place code for
building binaries.

In this example a binary named `server` can be installed or run. These types of
programs must be put into the `main` package.

```bash
モ tree
.
├── cmd
│   └── server
│       └── main.go
```

Code that can be shared like `lib` code is put into a folder called `pkg`. Each
of the sub directories in the `pkg` directory are different packages.

In the following example there is code placed in the `web` package. This package
can be imported from other packages in this project repo or from external repos
by importing the `module` name + the relative directory path that includes code in
that `package`.

```bash
モ tree
.
├── pkg
│   └── web
│       ├── authorize.go
│       ├── default.go
│       ├── routes.go
│       ├── token.go
│       └── well_known.go
```


Each repo should have a `module` name that is defined in the `go.mod` file.
The `module` name acts as a namespace for all the packages within it. A common
convention is to name the module the same thing as where the code can be found
in version control. E.g. if I have a repo with golang code available from
`https://github.com/xlgmokha/my-thing` then the module would be called
`github.com/xlgmokha/my-thing`. The `module` name is the prefix used to import
packages. This removes the need for a central registry or authority for
distribiting code (e.g. rubygems.org). So code can be hosted from anywhere.
However, if you change your username on GitHub you will need to also update the
module names to point to the new location.

```bash
モ cat go.mod
module github.com/xlgmokha/my-thing

go 1.18

require (
        github.com/golang-jwt/jwt v3.2.2+incompatible
        github.com/hashicorp/uuid v0.0.0-20160311170451-ebb0a03e909c
        github.com/lestrrat-go/jwx/v2 v2.0.0-beta1
)

require (
        github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect
        github.com/goccy/go-json v0.9.6 // indirect
        github.com/lestrrat-go/blackmagic v1.0.1 // indirect
        github.com/lestrrat-go/httpcc v1.0.1 // indirect
        github.com/lestrrat-go/httprc v1.0.1 // indirect
        github.com/lestrrat-go/iter v1.0.2 // indirect
        github.com/lestrrat-go/option v1.0.0 // indirect
        golang.org/x/crypto v0.0.0-20220214200702-86341886e292 // indirect
)
```

The `go.mod` file has 3 responsibilities:

1. Specifies the `module` name.
1. Specifies the desired version of golang.
1. Specifies other modules that this module depends on.
  * this is represented as both direct and indirect dependencies.