# appview/web ## package structure ``` web/ |- routes.go |- handler/ | |- xrpc/ |- middleware/ |- request/ ``` - `web/routes.go` : all possible routes defined in single file - `web/handler` : general http handlers - `web/handler/xrpc` : xrpc handlers - `web/middleware` : all middlwares - `web/request` : define methods to insert/fetch values from request context. shared between middlewares and handlers. ### file name convention on `web/handler` - Follow the absolute uri path of the handlers (replace `/` to `_`.) - Trailing path segments can be omitted. - Avoid conflicts between prefix and names. - e.g. using both `user_repo_pulls.go` and `user_repo_pulls_rounds.go` (with `user_repo_pulls_` prefix) ### handler-generators instead of raw handler function instead of: ```go type Handler struct { is isvc.Service rs rsvc.Service } func (h *Handler) RepoIssues(w http.ResponseWriter, r *http.Request) { // ... } ``` prefer: ```go func RepoIssues(is isvc.Service, rs rsvc.Service, p *pages.Pages, d *db.DB) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { // ... } } ``` Pass dependencies to each handler-generators and avoid creating structs with shared dependencies unless it serves somedomain-specific roles like `service/issue.Service`. Same rule applies to middlewares too. This pattern is inspired by [the grafana blog post](https://grafana.com/blog/how-i-write-http-services-in-go-after-13-years/#maker-funcs-return-the-handler). Function name can be anything as long as it is clear.