Documentation
¶
Overview ¶
Package shared holds the response-shape types common to every Go implementation under benchmarks/apps/ (currently gombit and gin-gorm) for the BENCH-1 canonical CRUD comparison (issue #141, benchmarks/docs/schema.md). Sharing these types between the two Go apps makes "same JSON shape" (one of the fairness checks issue #141 requires) true by construction instead of by two hand-maintained definitions staying in sync. Non-Go implementations (Django, Rails, Laravel, NestJS) can't share this package and must match benchmarks/docs/schema.md by hand instead.
Index ¶
- Constants
- func ProjectDescription(i int) string
- func ProjectName(i int) string
- func ProjectOwnerID(i, userCount int) uint
- func SeedCounts() (users, projects int, err error)
- func UserEmail(i int) string
- func UserName(i int) string
- type Data
- type DataMeta
- type ErrorBody
- type ErrorEnvelope
- type PageMeta
- type ProjectData
Constants ¶
const ( SeedUserCount = 1000 SeedProjectCount = 100000 )
SeedUserCount and SeedProjectCount are issue #141's recommended initial dataset (benchmarks/docs/schema.md "Seed dataset"), shared so every implementation seeds the same row counts without two copies of these numbers to keep in sync by hand.
const ( SeedUsersEnv = "BENCH_SEED_USERS" SeedProjectsEnv = "BENCH_SEED_PROJECTS" )
SeedUsersEnv and SeedProjectsEnv override the seeded row counts for a run. They exist for the CI smoke's small deterministic seed (issue #141 §11): a tiny row count over the SAME deterministic content formulas, so the containerized migrate → seed → serve → k6 path is exercised on every PR without a 100,000-row insert. Every implementation (Go, Python, Ruby, PHP, Node) reads these exact names with the same semantics — unset/empty means the canonical default; a non-empty value that is not a positive integer is a fatal error, never a silent fall back to 100k. Note the read workload asserts a full 20-row first page, so an override must keep at least 20 projects.
Variables ¶
This section is empty.
Functions ¶
func ProjectDescription ¶
func ProjectName ¶
func ProjectOwnerID ¶
ProjectOwnerID returns the 1-based owner id for project i, round-robin over 1..userCount, so every user owns projectCount/userCount projects and two implementations' seeded row N are content-identical.
func SeedCounts ¶
SeedCounts resolves the user and project counts to seed: the canonical constants, unless SeedUsersEnv / SeedProjectsEnv are set to a positive integer. A malformed override is returned as an error rather than silently falling back, so a typo in CI fails loudly instead of seeding 100k.
func UserEmail ¶
UserEmail, UserName, ProjectOwnerID, ProjectName, and ProjectDescription are the pure, deterministic-content formulas issue #141's seed dataset requires ("the same values for every implementation"). Shared across every Go implementation under benchmarks/apps/ so two of them can't silently seed different content for the same row N — the exact drift risk a hand-duplicated second copy would carry (this package already exists to avoid that for response shapes; seed content is the same problem).
Types ¶
type Data ¶
type Data[T any] struct { Data T `json:"data"` }
Data is the D10 success envelope without meta: {"data": ...}. Same JSON shape as contract.Data (github.com/gombit-dev/gombit/contract) — defined independently here, not imported from there. contract.ErrorEnvelope is a huma.StatusError, so importing the contract package pulls in Huma regardless of whether the importer ever calls Huma directly; a Go implementation under benchmarks/apps/ that's sold as "no Huma" (the gin-gorm control) needs to match Gombit's wire format without linking Gombit's framework packages to do it, or the claim is false in the dependency graph even when it's true in the handler code.
type ErrorBody ¶
type ErrorBody struct {
Code string `json:"code"`
Message string `json:"message"`
Fields map[string][]string `json:"fields,omitempty"`
RequestID string `json:"request_id,omitempty"`
}
ErrorBody is the D10 error object nested under "error".
type ErrorEnvelope ¶
ErrorEnvelope is the D10 error response body: {"error": {...}}.
func ConflictError ¶
func ConflictError(message string) *ErrorEnvelope
func InternalError ¶
func InternalError(message string) *ErrorEnvelope
func NotFoundError ¶
func NotFoundError(message string) *ErrorEnvelope
NotFoundError, ConflictError, ValidationError, and InternalError mirror the D10 §41 category -> status mapping (contract.Category / StatusFor in github.com/gombit-dev/gombit/contract) without importing that package — same codes and statuses, independently implemented.
func ValidationError ¶
func ValidationError(message string, fields map[string][]string) *ErrorEnvelope
func (*ErrorEnvelope) Error ¶
func (e *ErrorEnvelope) Error() string
type PageMeta ¶
PageMeta is the canonical /api/projects list-endpoint pagination meta shape: {"page","limit","total"}. Not contract.PageMeta (which uses per_page) — issue #141 explicitly specifies `limit` as both the query parameter and the meta field name for this benchmark's canonical API.
type ProjectData ¶
type ProjectData struct {
ID uint `json:"id"`
OwnerID uint `json:"owner_id"`
OwnerName string `json:"owner_name"`
Name string `json:"name"`
Description string `json:"description"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
ProjectData is the canonical /api/projects response shape (benchmarks/docs/schema.md "Canonical CRUD API"). OwnerName is the preloaded owner relationship flattened into the response — its presence is what the N+1 fairness check verifies: a handler that didn't preload the owner would have to make a second query per row to populate it.