https://lets-go.alexedwards.net/
I was about to give up the idea of writing a web application in Go because I could not find an application framework like Spring or Django that helps with common stuff like
- App Configuration
- Authentication
- Session Cookies
- Form Validation
- Flash Messages.
- Optimistic Locking
- Internationalization
But then a perplexity research presented this book to me with an even better approach then an application framework
The author develops the necessary helpers and infra code on his own with the standard library in a very pragmatic and easy to follow way. Only very few 3rd party libraries are used.
So in the end you have your application framework living inside your project. You understand the code and you can easily modify it. this is so much better than a big and complex framework like Spring that is never modified in practice and becomes a real pain when the "magic" is not working as exspected.
Application Architecture
graph TB subgraph Infrastructure ["Infrastructure"] DB["<br/>Database Connection<br/>sql.DB"] EFS["<br/>Embedded FileSystem<br/>ui.Files"] LOG["<br/>Logger<br/>slog.Logger"] end subgraph DataAccessLayer ["Data Access Layer"] SM["<br/>SnippetModel<br/>models.SnippetModel"] --> DB UM["<br/>UserModel<br/>models.UserModel"] --> DB STORE["<br/>Session Store<br/>mysqlstore.Store"] --> DB end subgraph ApplicationLayer ["Application Layer"] CFG["<br/>Config<br/>main.config"] SESS["<br/>SessionManager<br/>scs.SessionManager"] --> STORE TC["<br/>Template Cache<br/>template.Template"] FD["<br/>Form Decoder<br/>form.Decoder"] VAL["<br/>Validator<br/>validator.Validator"] APP["<br/>Application with HTTP Handlers<br/>main.application"] APP --> SM APP --> UM APP --> SESS APP --> TC APP --> FD APP -.-> VAL APP --> CFG end subgraph TransportLayer ["Transport Layer"] SERVER["<br/>HTTP Server<br/>http.Server"] --> APP MW["<br/>Middleware Chain<br/>alice.Chain"] --> SESS MW --> APP end subgraph Legend ["Legend"] STDLIB["<br/>stdlib"] ~~~ CUSTOM["<br/>custom"] ~~~ THIRDPARTY["<br/>3rd party"] end %% Color Legend: %% Green: Internal Application Components %% Blue: Go Standard Library Components %% Gray: External Library Components (3rd party dependencies) %% Gray: Internal Domain/Data Components style APP fill:#2e7d32,stroke:#1b5e20,stroke-width:3px,color:#ffffff style DB fill:#1976d2,stroke:#0d47a1,stroke-width:2px,color:#ffffff style SERVER fill:#1976d2,stroke:#0d47a1,stroke-width:2px,color:#ffffff style LOG fill:#1976d2,stroke:#0d47a1,stroke-width:2px,color:#ffffff style EFS fill:#2e7d32,stroke:#1b5e20,stroke-width:2px,color:#ffffff style SESS fill:#4d4d4d,stroke:#666666,stroke-width:2px,color:#ffffff style TC fill:#2e7d32,stroke:#1b5e20,stroke-width:2px,color:#ffffff style SM fill:#2e7d32,stroke:#1b5e20,stroke-width:2px,color:#ffffff style UM fill:#2e7d32,stroke:#1b5e20,stroke-width:2px,color:#ffffff style STORE fill:#4d4d4d,stroke:#666666,stroke-width:2px,color:#ffffff style VAL fill:#2e7d32,stroke:#1b5e20,stroke-width:2px,color:#ffffff style FD fill:#4d4d4d,stroke:#666666,stroke-width:2px,color:#ffffff style CFG fill:#2e7d32,stroke:#1b5e20,stroke-width:2px,color:#ffffff style MW fill:#4d4d4d,stroke:#666666,stroke-width:2px,color:#ffffff style STDLIB fill:#1976d2,stroke:#0d47a1,stroke-width:2px,color:#ffffff style CUSTOM fill:#2e7d32,stroke:#1b5e20,stroke-width:2px,color:#ffffff style THIRDPARTY fill:#4d4d4d,stroke:#666666,stroke-width:2px,color:#ffffff %% Subgraph styling with light yellow background and black text style Infrastructure fill:#fff7d9,stroke:#333,stroke-width:2px,color:#000000 style DataAccessLayer fill:#fff7d9,stroke:#333,stroke-width:2px,color:#000000 style ApplicationLayer fill:#fff7d9,stroke:#333,stroke-width:2px,color:#000000 style TransportLayer fill:#fff7d9,stroke:#333,stroke-width:2px,color:#000000 style Legend fill:#fff7d9,stroke:#333,stroke-width:2px,color:#000000
Also I am very happy with the Approach of writing SQL instead of using an ORM that generates the queries which I have some sometimes seen to have unintended and very negative consequences.
Optimistic Locking is introduced in the successor book: https://lets-go-further.alexedwards.net/
Internationalization is discussed here: https://www.alexedwards.net/blog/i18n-managing-translations