BowlerKitBowlerKit
Backend Architecture

API Backend (Go)

10/11/2026

Run the Go service that validates Laravel Sanctum tokens and serves the protected mobile resource contract.

What is implemented

The generated api-backend/ is a Chi-based Go service for Account projects. It currently provides:

  • GET /health liveness and GET /api/v1/health readiness endpoints.
  • Environment-driven config for HTTP, PostgreSQL, Redis, CORS, body limits, proxies, Sanctum expiry, and Laravel URL.
  • Recovery, request IDs, CORS, security headers, body limits, rate limits, and request logging.
  • Sanctum token lookup against Laravel's personal_access_tokens table with ability checks.
  • The protected /api/v1/app/* mobile resource handlers listed below.
  • Laravel-compatible success/error envelopes and resource serialization.

Go does not issue auth tokens, run migrations, own uploads or RevenueCat webhooks, revoke sessions/delete accounts, or send admin broadcasts. Keep those routes on Laravel.

Shared routes served by Go

MethodRouteGuard/behavior
GET/api/v1/app/meuser:read
POST/api/v1/app/device-tokensuser:update
PUT/api/v1/app/users/{uuid}user:update
GET/api/v1/app/security/authlogssecurity:read
GET/api/v1/app/security/sessionssecurity:read
GET/api/v1/app/help-center*Authenticated help-center reads
POST/GET/api/v1/app/help-center/feedbackhelp-center:create/read plus feedback quotas
GET/PUT/DELETE/api/v1/app/notifications*Notification abilities
GET/PUT/api/v1/app/preferencesPreference abilities
GET/api/v1/app/notifications/preferencespreferences:read
PUT/api/v1/app/notifications/preferencespreferences:update
GET/api/v1/app/billing/entitlementsbilling:read

The Go router intentionally returns 404 for unsupported empty sync routes and admin notification send/broadcast routes. Those operations remain Laravel-owned.

Local setup

Requirements: Go 1.26.5 or newer, and access to the shared Laravel PostgreSQL and Redis services.

cd api-backend
cp .env.example .env
# Match DB_*, REDIS_*, RATE_LIMIT_NAMESPACE, and LARAVEL_URL with Laravel.
go mod download
go run ./cmd/api

Health checks:

curl http://localhost:8080/health
curl http://localhost:8080/api/v1/health

Set DB_ENABLED=false when you only need a process/liveness check before the shared database exists. With DB enabled but unreachable, liveness stays healthy while readiness returns 503.

Docker modes

compose.dev.yaml is a standalone smoke-test stack for PostgreSQL, Redis, and Go. It is not the production shared stack:

docker compose -f compose.dev.yaml up --build

compose.yaml is the production-style single-service definition and expects external web and shared Docker networks plus .env.production. The generated project does not include or publish the repository-level docker/infra and docker/proxy directories. Provide those networks and any database, Redis, and reverse-proxy services through your own customer-managed infrastructure.

Schema and parity

Laravel migrations are the schema source of truth. When the schema changes:

  1. Migrate a local/temporary Laravel database.
  2. Refresh the checked-in Go schema snapshot.
  3. Update SQL queries and run sqlc generate.
  4. Run Go tests and compare response envelopes/fields with Laravel.

Do not edit generated sqlc files by hand or add Go migrations.

Verification

gofmt -l .
go vet ./...
go test ./...
go test -race ./...

Only route /api/v1/app/* to Go after verifying authentication abilities, request validation, response fields, timestamps, error envelopes, and side effects against the Laravel compatibility implementation.