Skip to content

About

A sphere layout template with bun as ORM.

Topics

Resources

Contributing

Stars

0 stars

Watchers

1 watching

Forks

Repository files navigation

Sphere Bun Layout

sphere-bun-layout is the Sphere project template for applications that use Bun instead of Ent. It keeps the same Proto-first HTTP, Wire, Swagger, Docker, and Makefile contracts as the other official layouts while limiting the example domain to a small authenticated admin API.

Capabilities

  • Protobuf and Buf API contracts with generated HTTP handlers on the stdx (net/http) engine.
  • Bun models and SQLite through sqliteshim.
  • JWT-protected admin CRUD example.
  • Wire dependency injection and Swagger/OpenAPI generation.
  • Docker and multi-architecture build targets.

Workflow

make init
make run

During development use make gen/all, make check, and make build. Run make help for the exact targets supported by this layout. Deployment is not a layout capability; connect the generated image to the project's own delivery system.

Structure and Ownership

  • proto/** contains handwritten API and Bun model contracts; the Bun models live in proto/bunpb/bunpb.proto (generated as api/bunpb).
  • api/** and swagger/** are generated.
  • internal/service/** contains handler implementations.
  • internal/biz/** contains initialization and business tasks.
  • internal/pkg/database owns Bun connection setup.
  • cmd/app composes the application through Wire.

Read .sphere/layout.json and AGENTS.md before extending or synchronizing the layout. Unclassified paths are project-owned by default.

Generator Versions and Codegen Baseline

codegen.versions pins every tool make install installs: the go-sphere protoc plugins, Buf, protoc-gen-go, Swag, Wire, golangci-lint, and sphere-cli. Change versions only there; the Makefile and the codegen scripts both read it.

Generated api/** is not committed, so codegen.sha256 records the SHA-256 of every generated api/** file as the tracked regression baseline:

  • make codegen-check compares the current api/** with the baseline. The CI workflow runs it right after make gen/all.
  • make codegen-verify regenerates api/** with the pinned plugins in a temporary tool directory and checks that the generated packages build, that generation is idempotent, and that the output matches the baseline. The Codegen workflow runs it on every push.
  • make codegen-baseline rewrites the baseline from the current api/**.

After changing Proto files or bumping a generator, run make install && make gen/all && make codegen-baseline and commit codegen.sha256 with the change, so reviewers see which generated files moved. A failing check without such a change means the installed tools do not match codegen.versions.

The baseline's first line, # module <path>, names the Go module it was recorded for: generated code embeds the module path, so a baseline only matches its own module. make init records the baseline last, which gives a project scaffolded under another module its own; make codegen-check asks for make codegen-baseline when go.mod and the baseline disagree. make init uses the committed buf.lock as is; refresh it deliberately with make gen/deps.

HTTP Server Limits

httpsrv.NewServer takes httpsrv.Options, which is embedded in each server's HTTP config, so these keys sit next to address and cors in api.http of config.json. 0 selects the default and a negative value disables the limit.

  • read_timeout_seconds (default 30) bounds reading a whole request, body included; idle_timeout_seconds (default 120) bounds an idle keep-alive connection.
  • max_body_bytes (default 4 MiB) caps a request body: a request declaring a larger Content-Length is answered 413 before its route runs, and reading past the cap is answered 413 too.
  • trusted_proxies lists the reverse proxies (IPs or CIDRs) whose X-Forwarded-For header is honoured. Set it when the service runs behind a proxy: otherwise every client, and every per-IP rate limit, shares the proxy's address. An invalid entry fails configuration loading.

Upgrade Notes

Changes in the sphere v0.0.7 sync:

  • Pinned to sphere v0.0.7, httpx / httpx/stdx v0.0.6 and errors v0.0.3, and generated api/** comes from protoc-gen-sphere v0.0.6, -binding v0.0.6 and -errors v0.0.4 (codegen.versions; codegen.sha256 was refreshed). protoc-gen-sphere now fails generation for the constructs it used to drop: a real oneof in a JSON body, a Timestamp/Duration/wrapper as a query/uri/header parameter, a FORM field on a body-less method, and nested or missing body/response_body paths.
  • The process-wide error parser falls back to httpz.ParseError instead of httpx.ParseError, so the storage sentinels (ErrNotFound, ErrDestExists, ErrFileNameInvalid) render 404/400 instead of 500. A project with its own parser must change the fallback the same way.
  • The request body cap is the engine's stdx.WithMaxBodySize now, not a wrapper around the server's handler: a request declaring a larger Content-Length is refused with 413 before its route runs, in-process requests are capped too, and the 413 is rendered by the error parser.

Template changes after the stdx migration:

  • internal/pkg/httpsrv sets read and idle timeouts, a request body cap and trusted proxies from httpsrv.Options (see HTTP Server Limits), and NewServer(name, addr, opts) takes it as a third argument.
  • GetAdmin answers 404 (ADMIN_ERROR_NOT_FOUND) for a missing admin instead of 500.
  • The unused environments config field is removed; it had no effect, and an existing config.json that still carries it keeps loading.
  • .dockerignore excludes go.work and go.work.sum, so a local workspace no longer breaks docker build.

This revision is a breaking template change: generated handlers are served by the stdx (net/http) engine from httpx / httpx/stdx v0.0.5, pinned together with github.com/go-sphere/sphere v0.0.6. The Gin adapter is gone.

  • Generated api/** code and its error envelopes use the httpz.* types instead of the former ginx.* names.
  • internal/pkg/httpsrv exports NewServer(name, addr) httpx.Engine, backed by stdx over net/http, and UseCORS registers CORS on that engine.
  • Middleware is registered on the engine rather than a Gin router, so CORS and panic recovery also cover paths no route matched.

A project generated from an earlier revision should merge internal/pkg/httpsrv/**, internal/server/*/web.go, and the regenerated api/** outputs at its next layout sync, then run make gen/all and make check.

The process timezone is now set explicitly: cmd/app/main.go calls boot.InitTimezone(boot.DefaultTimezone) (Asia/Shanghai) before startup and exits if the zone cannot be loaded. Newer sphere releases no longer set it from a package init(), so a project that keeps an older main.go runs in the host timezone after upgrading sphere. Merge cmd/app/main.go (it is mixed), then pass another IANA zone or delete the call to keep the host default.

The handwritten Bun model contract was renamed from proto/entpb/entpb.proto (package entpb) to proto/bunpb/bunpb.proto (package bunpb); the old name suggested Ent-generated output. This is a breaking template change: generated Go moves from api/entpb to api/bunpb. A project synchronizing this revision should move its model messages into proto/bunpb, change proto imports to "bunpb/bunpb.proto" and entpb.X references to bunpb.X, update Go imports of .../api/entpb to .../api/bunpb, delete the stale api/entpb, then run make gen/all and make codegen-baseline.

About

A sphere layout template with bun as ORM.

Topics

Resources

Contributing

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages