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