appview/web#
package structure#
web/
|- routes.go
|- handler/
| |- xrpc/
|- middleware/
|- request/
web/routes.go: all possible routes defined in single fileweb/handler: general http handlersweb/handler/xrpc: xrpc handlersweb/middleware: all middlwaresweb/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.goanduser_repo_pulls_rounds.go(withuser_repo_pulls_prefix)
- e.g. using both
handler-generators instead of raw handler function#
instead of:
type Handler struct {
is isvc.Service
rs rsvc.Service
}
func (h *Handler) RepoIssues(w http.ResponseWriter, r *http.Request) {
// ...
}
prefer:
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.
Function name can be anything as long as it is clear.