diff options
| author | mo khan <mo@mokhan.ca> | 2022-05-06 14:27:23 -0600 |
|---|---|---|
| committer | mo khan <mo@mokhan.ca> | 2022-05-06 14:27:23 -0600 |
| commit | b3e52da170fb12f19855b4fcd04dd0c29aec4795 (patch) | |
| tree | 82092ad4351d9511228e0d2321cbb43def974d59 | |
| parent | 18343bdef59fe898741185f6e2861b373f47a8e3 (diff) | |
docs: copy over notes on golang
| -rw-r--r-- | learn/golang/README.md | 138 |
1 files changed, 137 insertions, 1 deletions
diff --git a/learn/golang/README.md b/learn/golang/README.md index 14087b1..2062a3c 100644 --- a/learn/golang/README.md +++ b/learn/golang/README.md @@ -1,6 +1,142 @@ -# Golang +# 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) + +To get better with Golang you _should_ read: * [benchmarks](https://dave.cheney.net/2013/06/30/how-to-write-benchmarks-in-go) * [generate](https://go.dev/blog/generate) * [project-layout](https://github.com/golang-standards/project-layout) * [strings](https://go.dev/blog/strings) + +## 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. |
