refactor(api/v2): self-register resource routes via init() registry
Previously every new v2 resource appended an explicit RegisterXRoutes call (and the EnableAutoPatch line had to stay last) in registerAPIRoutesV2 in routes.go, causing recurring merge conflicts across in-flight PRs. Resources now self-register: each resource file calls AddRouteRegistrar from an init(), and registerAPIRoutesV2 just calls apiv2.RegisterAll, which runs every registrar and then EnableAutoPatch. New resources touch zero shared lines.
This commit is contained in:
parent
220af19a39
commit
b04d4d269c
|
|
@ -31,6 +31,8 @@ type adminProjectListBody struct {
|
|||
Body Paginated[*models.Project]
|
||||
}
|
||||
|
||||
func init() { AddRouteRegistrar(RegisterAdminProjectRoutes) }
|
||||
|
||||
// Permissions are enforced by the gateV2AdminRoutes path middleware, not per-handler.
|
||||
func RegisterAdminProjectRoutes(api huma.API) {
|
||||
tags := []string{"admin"}
|
||||
|
|
|
|||
|
|
@ -39,6 +39,8 @@ type avatarInput struct {
|
|||
Size int64 `query:"size" default:"250" minimum:"1" doc:"Desired avatar edge length in pixels. Clamped to the server's configured maximum if larger; providers that render fixed-size images may ignore it."`
|
||||
}
|
||||
|
||||
func init() { AddRouteRegistrar(RegisterAvatarRoutes) }
|
||||
|
||||
// RegisterAvatarRoutes wires the avatar binary endpoint onto the Huma API.
|
||||
func RegisterAvatarRoutes(api huma.API) {
|
||||
Register(api, huma.Operation{
|
||||
|
|
|
|||
|
|
@ -41,6 +41,8 @@ type avatarUploadBody struct {
|
|||
Body *models.Message
|
||||
}
|
||||
|
||||
func init() { AddRouteRegistrar(RegisterAvatarUploadRoutes) }
|
||||
|
||||
func RegisterAvatarUploadRoutes(api huma.API) {
|
||||
tags := []string{"user"}
|
||||
|
||||
|
|
|
|||
|
|
@ -35,6 +35,8 @@ type labelListBody struct {
|
|||
Body Paginated[*models.LabelWithTaskID]
|
||||
}
|
||||
|
||||
func init() { AddRouteRegistrar(RegisterLabelRoutes) }
|
||||
|
||||
// RegisterLabelRoutes wires Label CRUD onto the Huma API.
|
||||
func RegisterLabelRoutes(api huma.API) {
|
||||
tags := []string{"labels"}
|
||||
|
|
|
|||
|
|
@ -34,6 +34,8 @@ type projectViewListBody struct {
|
|||
Body Paginated[*models.ProjectView]
|
||||
}
|
||||
|
||||
func init() { AddRouteRegistrar(RegisterProjectViewRoutes) }
|
||||
|
||||
// RegisterProjectViewRoutes wires the nested ProjectView CRUD onto the Huma API.
|
||||
// Every operation binds two path params: {project} → ProjectID and {view} → ID.
|
||||
// This is the reference shape every nested sub-resource copies.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,39 @@
|
|||
// Vikunja is a to-do list application to facilitate your life.
|
||||
// Copyright 2018-present Vikunja and contributors. All rights reserved.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
package apiv2
|
||||
|
||||
import "github.com/danielgtaylor/huma/v2"
|
||||
|
||||
var routeRegistrars []func(huma.API)
|
||||
|
||||
// AddRouteRegistrar records a resource's route-registration function. Each
|
||||
// resource file calls this from an init() so new resources never touch the
|
||||
// central wiring.
|
||||
func AddRouteRegistrar(f func(huma.API)) {
|
||||
routeRegistrars = append(routeRegistrars, f)
|
||||
}
|
||||
|
||||
// RegisterAll runs every registrar collected via AddRouteRegistrar, then
|
||||
// enables AutoPatch. Registrars run in init() order (filename order across the
|
||||
// package); the order they register routes in is irrelevant. AutoPatch runs
|
||||
// last so it can synthesise PATCH counterparts for all GET + PUT pairs.
|
||||
func RegisterAll(api huma.API) {
|
||||
for _, r := range routeRegistrars {
|
||||
r(api)
|
||||
}
|
||||
EnableAutoPatch(api)
|
||||
}
|
||||
|
|
@ -27,6 +27,8 @@ import (
|
|||
)
|
||||
|
||||
// RegisterTaskDuplicateRoutes wires the task-duplicate action onto the Huma API.
|
||||
func init() { AddRouteRegistrar(RegisterTaskDuplicateRoutes) }
|
||||
|
||||
// TaskDuplicate is a CRUDable Create, so the handler reuses handler.DoCreate
|
||||
// (its CanCreate enforces read-source + write-project); the only custom part is
|
||||
// taking TaskID from the path rather than a request body.
|
||||
|
|
|
|||
|
|
@ -415,17 +415,8 @@ func registerAPIRoutesV2(e *echo.Echo, a *echo.Group) {
|
|||
a.GET("/docs", apiv2.ScalarUI)
|
||||
a.GET("/docs/scalar.standalone.js", apiv2.ScalarJS)
|
||||
|
||||
// Resource registrations.
|
||||
apiv2.RegisterLabelRoutes(api)
|
||||
apiv2.RegisterTaskDuplicateRoutes(api)
|
||||
apiv2.RegisterProjectViewRoutes(api)
|
||||
apiv2.RegisterAdminProjectRoutes(api)
|
||||
apiv2.RegisterAvatarRoutes(api)
|
||||
apiv2.RegisterAvatarUploadRoutes(api)
|
||||
|
||||
// AutoPatch must run AFTER all GET/PUT pairs are registered so it can
|
||||
// synthesize their PATCH counterparts.
|
||||
apiv2.EnableAutoPatch(api)
|
||||
// Resources self-register via init(); RegisterAll runs them all + AutoPatch.
|
||||
apiv2.RegisterAll(api)
|
||||
}
|
||||
|
||||
func registerAPIRoutes(a *echo.Group) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue