Files

42 lines
1.1 KiB
Go

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
}