# 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. ## HTTP Go makes it very easy to create an http(s) server and provides a default mechanism for routing requests to specific `handler` functions. The default router is called a `Mux` which is short for multiplexer. The `ServeMux` struct is described as a `HTTP request multiplexer`. ```golang // ServeMux is an HTTP request multiplexer. // It matches the URL of each incoming request against a list of registered // patterns and calls the handler for the pattern that // most closely matches the URL. ``` The interface used by the `mux` is `Handler` which is defined as: ```golang // A Handler responds to an HTTP request. // // ServeHTTP should write reply headers and data to the ResponseWriter // and then return. Returning signals that the request is finished; it // is not valid to use the ResponseWriter or read from the // Request.Body after or concurrently with the completion of the // ServeHTTP call. // // Depending on the HTTP client software, HTTP protocol version, and // any intermediaries between the client and the Go server, it may not // be possible to read from the Request.Body after writing to the // ResponseWriter. Cautious handlers should read the Request.Body // first, and then reply. // // Except for reading the body, handlers should not modify the // provided Request. // // If ServeHTTP panics, the server (the caller of ServeHTTP) assumes // that the effect of the panic was isolated to the active request. // It recovers the panic, logs a stack trace to the server error log, // and either closes the network connection or sends an HTTP/2 // RST_STREAM, depending on the HTTP protocol. To abort a handler so // the client sees an interrupted response but the server doesn't log // an error, panic with the value ErrAbortHandler. type Handler interface { ServeHTTP(ResponseWriter, *Request) } ``` This means that any `type` that implements the function `ServeHTTP(w, *r)` can be used as a `Handler` for the HTTP Mux.