# Go Beginner Guide for This Backend This is not a full Go course. It explains only the Go ideas you need to read this project. ## 1. How a Go project starts This repo has a `go.mod` file: ```go module github.com/arkie/ark-database ``` That module name is used in imports: ```go import "github.com/arkie/ark-database/internal/config" ``` The executable starts at: ```text cmd/server/main.go ``` In Go, a runnable program has: ```go package main func main() { // program starts here } ``` ## 2. Packages Every `.go` file begins with a package name: ```go package handlers ``` Files in the same folder usually share the same package and can call each other directly. Example: files in `internal/handlers/` all say `package handlers`, so `public.go` can call `writeJSON` from `util.go`. ## 3. Imports Go imports are explicit: ```go import ( "net/http" "github.com/go-chi/chi/v5" ) ``` If an import is unused, Go compilation fails. Run `gofmt -w .` after edits. ## 4. Structs A struct is an object/data shape. Example from `internal/config/config.go`: ```go type Config struct { Addr string DatabaseURL string JWTSecret string } ``` JSON field names are controlled by tags: ```go type ResourceDTO struct { CategoryID int `json:"categoryId"` } ``` The Go field is `CategoryID`, but JSON output is `categoryId`. ## 5. Functions with errors Go commonly returns `(value, error)`: ```go pool, err := db.Connect(ctx, cfg.DatabaseURL) if err != nil { log.Fatal(err) } ``` Read this as: 1. Try connecting to DB. 2. If `err` is not nil, stop. 3. Otherwise use `pool`. ## 6. Short variable declaration `:=` This creates a new variable: ```go cfg := config.Load() ``` This assigns to an existing variable: ```go cfg = config.Load() ``` Most code here uses `:=` inside functions. ## 7. HTTP handlers A Go HTTP handler usually looks like: ```go func ListCategories(w http.ResponseWriter, r *http.Request) { // w writes response // r reads request } ``` - `w` = response writer. - `r` = request. Route registration in `main.go`: ```go r.Get("/categories", handlers.ListCategories) ``` Because this is inside `r.Route("/api", ...)`, the full URL is: ```text GET /api/categories ``` ## 8. Middleware Middleware wraps a request before it reaches the final handler. Example in `main.go`: ```go r.Use(middleware.Logger) ``` This logs requests. Admin auth is also middleware: ```go r.Use(handlers.AdminAuth(cfg.JWTSecret)) ``` If token is bad, it returns `401 unauthorized` before reaching the admin handler. ## 9. Context Context carries request-scoped values and cancellation. This project stores the DB pool in request context: ```go r.Use(func(next http.Handler) http.Handler { return handlers.WithPool(next, pool) }) ``` Handlers retrieve it: ```go pool := poolFrom(r) ``` So most handlers do not receive the DB pool as a direct function parameter. ## 10. Database queries This project uses pgx. One row: ```go err := pool.QueryRow(ctx, `SELECT id FROM admins WHERE email = $1`, email).Scan(&id) ``` Many rows: ```go rows, err := pool.Query(ctx, `SELECT id, title FROM resources`) defer rows.Close() for rows.Next() { rows.Scan(&id, &title) } ``` PostgreSQL parameters use `$1`, `$2`, etc. This protects from SQL injection when used correctly. ## 11. Pointers and nil You will see `*string` and `*time.Time`: ```go var pubAt *time.Time ``` This allows SQL `NULL` to become Go `nil`. Code checks before using it: ```go if pubAt != nil { s := pubAt.UTC().Format(time.RFC3339) dto.PublishedAt = &s } ``` ## 12. `defer` `defer` runs later when the current function returns. Examples: ```go defer pool.Close() defer rows.Close() defer r.Body.Close() ``` Use it for cleanup. ## 13. JSON helpers in this project Write JSON response: ```go writeJSON(w, map[string]any{"ok": true}) ``` Read JSON request body: ```go var req loginReq if err := jsonDecode(r, &req); err != nil { http.Error(w, "bad json", http.StatusBadRequest) return } ``` ## 14. Common edit workflow After changing `.go` files: ```bash gofmt -w . go test ./... ``` `go test ./...` also compiles all packages, even if there are no test files. ## 15. Recommended reading order 1. `README.md` 2. `cmd/server/main.go` 3. `internal/config/config.go` 4. `internal/handlers/public.go` 5. `internal/handlers/admin.go` 6. `internal/handlers/wallet_auth.go` 7. `migrations/001_init.sql` When you see a function you do not understand, search for its definition: ```bash rg "func FunctionName" . ```