Documentation
¶
Overview ¶
Package users is the canonical "owns its data, exposes typed REST" module: a minimal user catalog tagged DeployAs("users-svc") so it can be peeled out into its own binary later.
Layout demonstrates multi-file shadow support:
types.go — public types (User, *Args) service.go — Service struct, constructor, plain methods handlers.go — gin/graphql handler shims module.go — Module declaration
Each file contributes to the same `users` package; the shadow generator strips Service/handlers/Module-related declarations from each file and synthesizes one zz_shadow_gen.go containing the HTTP-stub Service. Public types in types.go are preserved verbatim in the shadow build (they're called by checkout's signatures).
Index ¶
- Variables
- func NewCounter(ctx context.Context, cache *Cache) error
- type Cache
- type CreateArgs
- type GetArgs
- type ListArgs
- type SearchArgs
- type Service
- func (s *Service) Create(ctx context.Context, args CreateArgs) (*User, error)
- func (s *Service) Get(ctx context.Context, args GetArgs) (*User, error)
- func (s *Service) List(ctx context.Context, args ListArgs) ([]*User, error)
- func (s *Service) Search(ctx context.Context, args SearchArgs) ([]*User, error)
- type User
- func NewBoom(svc *Service, p nexus.Params[struct{}]) (*User, error)
- func NewCreate(svc *Service, cache *Cache, p nexus.Params[CreateArgs]) (*User, error)
- func NewGet(svc *Service, cache *Cache, p nexus.Params[GetArgs]) (*User, error)
- func NewList(svc *Service, cache *Cache, p nexus.Params[ListArgs]) ([]*User, error)
- func NewSearch(svc *Service, cache *Cache, p nexus.Params[SearchArgs]) ([]*User, error)
Constants ¶
This section is empty.
Variables ¶
var Module = nexus.Module("users", nexus.DeployAs("users-svc"), nexus.Provide(NewService, NewCache), nexus.AsRest("GET", "/users/:id", NewGet), nexus.AsRest("GET", "/users", NewList, listRateLimit), nexus.AsRest("GET", "/boom", NewBoom), nexus.AsQuery(NewSearch), nexus.AsMutation(NewCreate), nexus.AsWorker("user-counter", NewCounter), nexus.Invoke(func(app *nexus.App) { app.Cron("cache-warmup", "@every 1m"). Describe("Top up the hottest user IDs into the cache."). Handler(func(ctx context.Context) error { return nil }) }), )
Module is the wired declaration. Demonstrates the breadth of the dashboard surface in one place:
- Provide(NewService, NewCache): the cache implements NexusResources(), so the framework auto-registers it as a resource node and attaches it to the service via constructor.
- REST + GraphQL query + GraphQL mutation: three transport flavours land in the same module card.
- Use(rate-limit) on the list endpoint: middleware chip + Rate limits tab entry.
- AsWorker: a long-lived background worker shows up as a Worker node connected to the cache.
- Invoke(app.Cron): a cron job appears in the Crons tab.
DeployAs is inferred from nexus.deploy.yaml's `users-svc.owns: [users]` entry. Add an explicit nexus.DeployAs("users-svc") to pin it in source.
Functions ¶
func NewCounter ¶ added in v0.21.28
NewCounter is a long-lived background worker. Its first param is context.Context (cancelled at fx.Stop), and it takes *Cache as a dep so the dashboard draws a Worker → users-cache edge alongside the service-level edge from User service. No-op heartbeat keeps the example trivial.
Types ¶
type Cache ¶ added in v0.21.28
type Cache struct {
// contains filtered or unexported fields
}
Cache is a tiny in-memory cache fronting the user store. It exists as its own type so the dashboard can render it as a Resource (cache kind) and draw an edge from the User service constructor — which takes *Cache as a dep — onto the cache node. Real apps would back this with Redis; the demo keeps it simple.
nexus.Provide(NewCache) is enough to register: the framework's auto-mount picks up the NexusResources() method below at boot.
func (*Cache) IsConnected ¶ added in v0.21.28
func (*Cache) NexusResources ¶ added in v0.21.28
NexusResources advertises this cache to the dashboard. The Service constructor takes *Cache as a parameter; the resource auto-attach pass walks that signature and draws the edge.
type CreateArgs ¶ added in v0.21.28
type CreateArgs struct {
Name string `graphql:"name,required" json:"name" validate:"required,len=2|80"`
}
CreateArgs is the typed input for the createUser GraphQL mutation. Validation tags surface as chips in the dashboard's args panel — gives the drawer a reason to show its Arguments section.
type GetArgs ¶
type GetArgs struct {
ID string `json:"id" uri:"id"`
}
GetArgs binds a path parameter named `id`. The framework's gin binding reads the `uri:"id"` tag; the shadow generator's path expansion reads the same tag — guaranteed to round-trip.
type ListArgs ¶
type ListArgs struct{}
ListArgs is empty — kept as a real type (rather than struct{}) so the generated method has a stable shape if filters are added.
type SearchArgs ¶ added in v0.13.0
type SearchArgs struct {
Prefix string `graphql:"prefix" json:"prefix"`
}
SearchArgs is the typed input for a GraphQL query.
type Service ¶
Service holds the in-memory store. Real implementations would back it with a DB; this stays simple to keep the example focused on the build-time transport switch. In binaries that don't own users, the shadow generator replaces this struct with an HTTP-stub variant whose methods route over PeerCaller — same public method set, same type identifier, different body.
func NewService ¶
NewService takes *Cache as a dep so the dashboard's auto-attach pass records "User service uses users-cache" — that draws an edge from the service card to the cache resource node.
func (*Service) Create ¶ added in v0.21.28
Create inserts a new user under a generated id and warms the cache. Backs the createUser GraphQL mutation registered in module.go.
func (*Service) Get ¶ added in v0.14.0
Get returns a typed user by id. Reads the hot cache first so the dashboard's edge from the service to the users-cache resource sees activity on every successful lookup.
type User ¶
User is the public shape returned over the wire. Generated client code lives in this package, so it sees this type without an import and consumers in other packages get it via `users.User`.
func NewBoom ¶ added in v0.21.28
NewBoom always panics with a nil-pointer dereference. Wired in module.go as GET /boom to demo the framework's stack-capture path — the recoveryMiddleware catches the runtime panic, attaches the captured debug.Stack() to a *trace.StackError, and the dashboard surfaces it on:
- the op-row's red error chip count (click to open drawer)
- the drawer's "Last error" panel with a ▸ stack disclosure
- the drawer's "Recent activity" rows (one per request) with the same ▸ stack toggle
- the bottom Activity rail rows (live feed)
Real handlers wouldn't ship this; it's purely a visibility demo. Hit it once from the drawer's tester and refresh — every panel that can show a stack will have it populated.