feat(handler): implement default sort configuration for models

* Add SetDefaultSort method to configure default sort order
* Implement getDefaultSort method to retrieve configured defaults
* Update handleRead to apply default sort when none specified
* Add tests for default sort functionality
This commit is contained in:
Hein
2026-07-29 10:05:24 +02:00
parent a70e3e02d0
commit 7c737afc5a
6 changed files with 203 additions and 0 deletions
+33
View File
@@ -32,6 +32,7 @@ type Handler struct {
nestedProcessor *common.NestedCUDProcessor
fallbackHandler FallbackHandler
openAPIGenerator func() (string, error)
defaultSort map[string][]common.SortOption
}
// NewHandler creates a new API handler with database and registry abstractions
@@ -64,6 +65,33 @@ func (h *Handler) SetFallbackHandler(fallback FallbackHandler) {
h.fallbackHandler = fallback
}
// SetDefaultSort sets the sort order applied to list ("read") results when a
// request does not specify its own sort (no x-sort header / sort query param).
// Pass an empty schema and name to set a global default used by any model
// without a more specific default.
func (h *Handler) SetDefaultSort(schema, name string, sort ...common.SortOption) {
if h.defaultSort == nil {
h.defaultSort = make(map[string][]common.SortOption)
}
h.defaultSort[defaultSortKey(schema, name)] = sort
}
// getDefaultSort returns the configured default sort for a model, falling
// back to the global default (registered with an empty schema and name).
func (h *Handler) getDefaultSort(schema, name string) []common.SortOption {
if h.defaultSort == nil {
return nil
}
if sort, ok := h.defaultSort[defaultSortKey(schema, name)]; ok {
return sort
}
return h.defaultSort[defaultSortKey("", "")]
}
func defaultSortKey(schema, name string) string {
return fmt.Sprintf("%s.%s", schema, name)
}
// handlePanic is a helper function to handle panics with stack traces
func (h *Handler) handlePanic(w common.ResponseWriter, method string, err interface{}) {
stack := debug.Stack()
@@ -645,6 +673,11 @@ func (h *Handler) handleRead(ctx context.Context, w common.ResponseWriter, id st
query = query.Where(fmt.Sprintf("%s.%s = ?", common.QuoteIdent(tableAlias), common.QuoteIdent(pkName)), id)
}
// Fall back to the configured default sort when the request didn't specify one
if len(options.Sort) == 0 {
options.Sort = common.ResolveSortColumns(h.getDefaultSort(schema, entity), reflection.GetPrimaryKeyName(model))
}
// Apply sorting
tableAlias := reflection.ExtractTableNameOnly(tableName)
for _, sort := range options.Sort {