refactor(server/api): resolveByID helper for parseUUID->fetch->404 (T4)
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"net/http"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
"github.com/jackc/pgx/v5"
|
||||
"github.com/jackc/pgx/v5/pgtype"
|
||||
|
||||
"git.fabledsword.com/bvandeusen/minstrel/internal/apierror"
|
||||
)
|
||||
|
||||
// resolveByID parses paramKey as a UUID, fetches the row via fetch, and
|
||||
// returns the row. On invalid UUID, returns BadRequest. On pgx.ErrNoRows,
|
||||
// returns NotFound with code "<notFoundCode>_not_found". On other fetch
|
||||
// errors, returns Internal (caller is responsible for logging if needed).
|
||||
//
|
||||
// Generic over T because dbq getters return concrete dbq row types.
|
||||
func resolveByID[T any](
|
||||
r *http.Request,
|
||||
paramKey string,
|
||||
fetch func(context.Context, pgtype.UUID) (T, error),
|
||||
notFoundCode string,
|
||||
) (T, *apierror.Error) {
|
||||
var zero T
|
||||
raw := chi.URLParam(r, paramKey)
|
||||
id, ok := parseUUID(raw)
|
||||
if !ok {
|
||||
return zero, apierror.BadRequest("bad_request", "invalid "+paramKey+" id")
|
||||
}
|
||||
row, err := fetch(r.Context(), id)
|
||||
if err != nil {
|
||||
if errors.Is(err, pgx.ErrNoRows) {
|
||||
return zero, apierror.NotFound(notFoundCode)
|
||||
}
|
||||
return zero, apierror.Internal(err)
|
||||
}
|
||||
return row, nil
|
||||
}
|
||||
Reference in New Issue
Block a user