refactor: seperate concerns via handler, service, storage #2

Closed
opened 2026-03-21 21:23:13 +01:00 by lucas · 1 comment
Owner

ideally, all business logic should be in a service (file chat.go) and use purely our defined go structs.

a handler would be responsible from translating incoming HTTP API request containing json into the correct Go function calls + structs.

the storage part would be responsible for translating our Go structs + functions into SQL queries.

ideally, all business logic should be in a service (file chat.go) and use purely our defined go structs. a handler would be responsible from translating incoming HTTP API request containing json into the correct Go function calls + structs. the storage part would be responsible for translating our Go structs + functions into SQL queries.
Author
Owner

refactor done - pushed as 739e1fe

what changed:

  • main.go - startup + wiring only: open db, register routes, run server
  • handlers.go - handler layer: translates http/json <-> service calls
  • chat.go - service layer: business logic lives here. it's a thin pass-through right now, but the sse notification for postMessage (per pseudocode/backend.s) belongs here when it lands
  • storage.go - storage layer: all sql lives here
  • types.go - the shared structs (Room, Message, NewMessage)

the temporary global db is gone - the handle is passed as a plain function argument (same style as the sample in docs/dependency-explanations.md). requests now flow handler -> service -> storage. kept it as simple as possible: plain functions only, no interfaces, no generics.

small fixes that came with the move:

  • http.ListenAndServe error is no longer ignored (port already in use now logs a proper error instead of exiting silently - this bit me while setting the dev server up)
  • handlers answer 500 on db errors instead of log.Fatal-ing the whole server
  • POST /messages responds 201 with {"id": N} (the frontend ignores the response, so nothing breaks)

AGENTS.md was updated to match the new layout.

tested: go build + go vet clean, server restarted, verified GET /rooms, GET /messages, POST /messages (including 400 on invalid json and the Remote-User header). leaving this issue open for review.

refactor done - pushed as [739e1fe](https://forge.shiny.space/lucas/grugchat/commit/739e1fea55bf6e64309c061953b265118fd92210) what changed: - `main.go` - startup + wiring only: open db, register routes, run server - `handlers.go` - handler layer: translates http/json <-> service calls - `chat.go` - service layer: business logic lives here. it's a thin pass-through right now, but the sse notification for postMessage (per pseudocode/backend.s) belongs here when it lands - `storage.go` - storage layer: all sql lives here - `types.go` - the shared structs (Room, Message, NewMessage) the temporary global `db` is gone - the handle is passed as a plain function argument (same style as the sample in docs/dependency-explanations.md). requests now flow handler -> service -> storage. kept it as simple as possible: plain functions only, no interfaces, no generics. small fixes that came with the move: - `http.ListenAndServe` error is no longer ignored (port already in use now logs a proper error instead of exiting silently - this bit me while setting the dev server up) - handlers answer `500` on db errors instead of `log.Fatal`-ing the whole server - `POST /messages` responds `201` with `{"id": N}` (the frontend ignores the response, so nothing breaks) AGENTS.md was updated to match the new layout. tested: `go build` + `go vet` clean, server restarted, verified GET /rooms, GET /messages, POST /messages (including 400 on invalid json and the Remote-User header). leaving this issue open for review.
lucas closed this issue 2026-10-26 18:38:14 +01:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
lucas/grugchat#2
No description provided.