Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add documentation about learning Go #12

Merged
merged 1 commit into from
Oct 10, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 97 additions & 0 deletions docs/learning-go.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# Are You New to the Go Programming Language?

Learning a new programming language can be quite daunting.
Existing Python programmers might feel overwhelmed when starting to contribute in a new language.
Some of the early contributors to this project were also new to Go. This document offers some pointers on how to learn the language effectively in relation to this project.

## Learning Go

### Picking Up the Language

As your first point of contact, you can experiment with Go in the browser via the ["A Tour of Go"](https://go.dev/tour/welcome/1) interactive application. This tour is translated into several languages beyond English and covers some basics.

The Tour of Go focuses on syntax but lacks real-world experience. Learning a new language involves not just the syntax but also understanding the toolchain and ecosystem. Therefore, we recommend [Learn Go with Tests](https://quii.gitbook.io/learn-go-with-tests). This guide teaches you Go in a way that closely resembles how coding in Go will look in this project.

Lastly, if you prefer to learn through video materials, we recommend [Learn Go Fast: Full Tutorial](https://www.youtube.com/watch?v=8uiZC0l4Ajw&t=185s). This is a straightforward walkthrough of all the concepts in Go.

### Unlearn Your Previous Experience

Depending on the languages you've used in the past, Go might be a bit different for you.
**Don't try to fight this!** Before I worked on this project, I was doing functional programming. While Go allows you to pass functions as arguments, many concepts operate in an imperative way. The advice here is to avoid merely translating syntax from languages with other paradigms. Instead, try to solve problems "the Go way" and let go (pun intended) of your past experiences.

## Use the Dev Container

It's perfectly fine if you've never installed Go before! To make things easier, we've provided a [dev container](https://containers.dev/) for everyone to use.

Using the dev container ensures you have the correct version of Go, along with the linters, editor plugins, and various other tools you might need for this project. It keeps your operating system clean and provides a consistent contributor experience.

## Linters

We make heavy use of [golangci-lint](https://golangci-lint.run/) in this project. This ensures code quality and consistency among various contributors. It’s a blessing for newcomers, as it can highlight honest mistakes you may be unaware of.

We use multiple linters for different languages via [pre-commit](https://pre-commit.com/). Before you commit your code, you can run

```shell
pre-commit
```

to ensure everything is in good shape.

⚠️ You may encounter Go lint errors for files you didn't touch. ⚠️
If this happens, please run

```shell
golangci-lint cache clean
```

<small>We expect this issue to be resolved in future Go lint releases.</small>

## Unit Tests

Unit tests can be a great way to quickly test something in Go. If you want to explore some temporary code, you can add a temporary unit test to one of the existing `_test.go` files.

```go
func TestSomethingNew(t *testing.T) {
t.Error("Failing test!")
}
```

```shell
go test -run ^TestSomethingNew$ ./pkg/tracking/service/query/lexer/tokenizer_test.go
```

## Used Frameworks

In addition to learning Go, it can be beneficial to familiarize yourself with some of the Go libraries used in this project.

### Fiber

While vanilla Go includes a basic web routing framework, it proved to be too limiting for our needs. We utilize [Fiber](https://gofiber.io/) to serve static files and API routes for the tracking server.

Most of our Fiber code is generated (e.g., [pkg/server/routes/tracking.g.go](../pkg/server/routes/tracking.g.go)), but it may still be worthwhile to understand the generated code.

### Code Generation

As mentioned earlier, we generate a considerable amount of code from the `*.proto` files of `mlflow`. (See [magefiles/generate.go](../magefiles/generate.go)). We use the standard [go/parser](https://pkg.go.dev/go/parser) and [go/ast](https://pkg.go.dev/go/ast) packages to parse Go source code generated by `protoc` and modify the abstract syntax tree (AST) to suit our requirements.

A helpful tool for inspecting the Go AST is [https://astexplorer.net/](https://astexplorer.net/).

### Go Validate

We validate all incoming request structs using the [Go validator](https://github.com/go-playground/validator) package.

As explained in [our guide for porting a new endpoint](./porting-a-new-endpoint.md#validate-input), we don't add tags to the struct directly; instead, we configure them in [magefiles/generate/validations.go](../magefiles/generate/validations.go).

Run

```shell
mage generate
```

after making any changes.

### Gorm

We use [Gorm](https://gorm.io/index.html) as our Object Relational Mapper (ORM) to communicate with any SQL instance.

Please note that we do not have any migrations in Go and cannot construct a new database; this process still occurs in Python.
Loading