Documentation
¶
Overview ¶
Package nexus is a thin framework over Gin that registers every endpoint (REST, GraphQL, WebSocket) into a central registry, traces every request into an in-memory event bus, and exposes both under /__nexus for tooling — notably the Vue dashboard.
nexus does NOT replace the caller's GraphQL layer: hand it a *graphql.Schema (typically built with github.com/paulmanoni/nexus/graph) and it mounts + introspects.
Index ¶
- Constants
- func ClientIPFromCtx(ctx context.Context) string
- func Run(cfg Config, opts ...Option)
- func WithClientIP(ctx context.Context, ip string) context.Context
- type App
- func (a *App) Bus() *trace.Bus
- func (a *App) Cache() *cache.Manager
- func (a *App) Cron(name, schedule string) *CronBuilder
- func (a *App) Engine() *gin.Engine
- func (a *App) Metrics() metrics.Store
- func (a *App) OnResourceUse(target UseReporter)
- func (a *App) RateLimiter() ratelimit.Store
- func (a *App) Register(r resource.Resource)
- func (a *App) Registry() *registry.Registry
- func (a *App) Run(addr string) error
- func (a *App) Scheduler() *cron.Scheduler
- func (a *App) ServeHTTP(w http.ResponseWriter, r *http.Request)
- func (a *App) Service(name string) *Service
- type AppOption
- func WithCache(m *cache.Manager) AppOption
- func WithDashboard() AppOption
- func WithDashboardMiddleware(bundles ...middleware.Middleware) AppOption
- func WithDashboardName(name string) AppOption
- func WithEngine(e *gin.Engine) AppOption
- func WithMetricsStore(s metrics.Store) AppOption
- func WithRateLimitStore(s ratelimit.Store) AppOption
- func WithTracing(capacity int) AppOption
- type Config
- type CronBuilder
- type GqlField
- type GqlOption
- func Deprecated(reason string) GqlOption
- func Desc(s string) GqlOption
- func GraphMiddleware(name, description string, mw graph.FieldMiddleware) GqlOption
- func Middleware(name, description string, mw graph.FieldMiddleware) GqlOptiondeprecated
- func OnService[S any]() GqlOption
- func Op(name string) GqlOption
- func RateLimit(l ratelimit.Limit) GqlOption
- func WithArgValidator(arg string, vs ...graph.Validator) GqlOption
- type MiddlewareOption
- type NexusResourceProvider
- type Option
- func AsMutation(fn any, opts ...GqlOption) Option
- func AsQuery(fn any, opts ...GqlOption) Option
- func AsRest(method, path string, fn any, opts ...RestOption) Option
- func AsSubscription(fn any, opts ...GqlOption) Option
- func AsWebSocket(path string, fn any, opts ...WsOption) Option
- func Invoke(fns ...any) Option
- func Module(name string, opts ...Option) Option
- func Provide(fns ...any) Option
- func ProvideResources(fns ...any) Option
- func ProvideService(fn any) Option
- func Raw(opt fx.Option) Option
- func Supply(values ...any) Option
- type Params
- type RestOption
- type Service
- func (s *Service) AtGraphQL(path string) *Service
- func (s *Service) Attach(r resource.Resource) *Service
- func (s *Service) Auth(fn UserDetailsFn) *Service
- func (s *Service) Describe(desc string) *Service
- func (s *Service) GraphQLPath() string
- func (s *Service) MountGraphQL(path string, schema *graphql.Schema, opts ...gql.Option)
- func (s *Service) Name() string
- func (s *Service) REST(method, path string) *rest.Builder
- func (s *Service) Using(names ...string) *Service
- func (s *Service) UsingDefaults() *Service
- func (s *Service) WebSocket(path string) *ws.Builder
- type UseReporter
- type UserDetailsFn
- type WsOption
Constants ¶
const DefaultGraphQLPath = "/graphql"
DefaultGraphQLPath is the mount path nexus.AsQuery / AsMutation use when a service hasn't called AtGraphQL.
const GqlFieldGroup = "nexus.graph.fields"
GqlFieldGroup is the single fx value-group name every reflective GraphQL registration feeds. fxmod's auto-mount Invoke reads this group, partitions entries by ServiceType, and mounts one schema per service.
Variables ¶
This section is empty.
Functions ¶
func ClientIPFromCtx ¶ added in v0.3.0
ClientIPFromCtx pulls the IP stashed via WithClientIP (or ratelimit.WithClientIP). Empty when absent.
func Run ¶ added in v0.3.0
Run builds and runs the app. Blocks until SIGINT/SIGTERM, then gracefully shuts the HTTP server + cron scheduler. Returns nothing — identical to fx.App.Run(). For tests where you need explicit Start/Stop control, build the app via a test helper that calls fxBootOptions.
func main() {
nexus.Run(
nexus.Config{Addr: ":8080", EnableDashboard: true},
nexus.Provide(NewDBManager),
advertsModule,
)
}
func WithClientIP ¶ added in v0.3.0
WithClientIP is a thin pass-through to ratelimit.WithClientIP so nexus callers can thread IP into context without importing the lower-level ratelimit package. Kept here for API consistency with other nexus helpers.
Types ¶
type App ¶
type App struct {
// contains filtered or unexported fields
}
func (*App) Cron ¶ added in v0.3.0
func (a *App) Cron(name, schedule string) *CronBuilder
Cron starts building a scheduled job. Finalize with .Handler(fn). Jobs run bare — middleware chains do not apply — but the scheduler still emits request.start / request.end trace events so they appear on the dashboard Traces tab.
app.Cron("refresh-pets", "*/5 * * * *").
Describe("Warm the pet cache").
Handler(func(ctx context.Context) error { return nil })
func (*App) OnResourceUse ¶
func (a *App) OnResourceUse(target UseReporter)
OnResourceUse installs an auto-attach hook onto any UseReporter (typically a *multi.Registry or a user wrapper around one). Whenever code calls target.UsingCtx(ctx, "resource-name") during a request, the hook:
- reads the current trace.Span from ctx so we know which service made the call
- AttachResource(service, resource) on the registry — edge appears live
- emits a "downstream" trace event so the Traces tab shows the lookup
Calls with no span in context (e.g. UsingCtx fired from main or a cron job outside the trace middleware) are silently ignored — there's no service to attribute the usage to.
func (*App) RateLimiter ¶ added in v0.3.0
type AppOption ¶ added in v0.3.0
type AppOption func(*App)
AppOption is the functional-option type for nexus.New. Named AppOption (not Option) so nexus.Option can be reserved for the top-level fx-wrapping builder type used by nexus.Provide / Module / Invoke / Run.
func WithCache ¶ added in v0.3.0
WithCache installs a user-provided cache.Manager instead of the default one nexus creates. Pass the same Manager users' app code receives from fx (e.g. via cache.Module) so every cache consumer — user code, metrics, rate-limit overrides — hits one store.
func WithDashboard ¶
func WithDashboard() AppOption
WithDashboard mounts /__nexus/endpoints (always) and /__nexus/events (if tracing is on).
func WithDashboardMiddleware ¶ added in v0.3.1
func WithDashboardMiddleware(bundles ...middleware.Middleware) AppOption
WithDashboardMiddleware gates the /__nexus surface behind one or more middleware bundles. Each bundle's Gin realization runs in registration order before any dashboard handler. Typical use:
nexus.WithDashboardMiddleware(
middleware.Middleware{Name: "auth", Gin: bearerAuth},
middleware.Middleware{Name: "admin", Gin: requireAdminRole},
)
Bundles without a Gin realization are skipped silently — the dashboard is an HTTP surface, so graph-only bundles don't apply.
func WithDashboardName ¶
WithDashboardName sets the brand shown in the dashboard header and the browser tab title. Defaults to "Nexus". The name is served over /__nexus/config so the client picks it up without a rebuild.
func WithEngine ¶
WithEngine supplies a pre-configured Gin engine. Without it, nexus builds a bare engine with just Recovery so the caller can bring their own logger.
func WithMetricsStore ¶ added in v0.3.0
WithMetricsStore swaps the default cache-backed metrics store. Useful when you want a Prometheus- or StatsD-backed implementation; the built-in dashboard /__nexus/stats endpoint reads from whichever Store is installed.
func WithRateLimitStore ¶ added in v0.3.0
WithRateLimitStore swaps the default in-memory rate-limit store for a custom implementation — typically ratelimit.NewRedisStore(...) in a multi-replica deploy. Pass this to nexus.New / via nexus.Config when you want limit state (counters, overrides) to survive restarts or be shared across processes.
func WithTracing ¶
WithTracing enables per-request trace events, buffered in a ring of the given capacity. Required for the dashboard's event stream to show anything.
type Config ¶ added in v0.3.0
type Config struct {
// Addr is the HTTP listen address (default ":8080").
Addr string
// DashboardName is the brand shown in the dashboard header and tab title
// (default "Nexus"). Served over /__nexus/config so you can change it
// per-environment without rebuilding the UI.
DashboardName string
// TraceCapacity is the ring-buffer size for request traces. 0 disables
// tracing — the Traces tab will stay empty.
TraceCapacity int
// EnableDashboard mounts /__nexus/* if true.
EnableDashboard bool
// DisablePlayground turns OFF the GraphQL Playground served on GET
// <service>/<path>. Default is enabled. Flip in prod wiring to hide
// the interactive console.
DisablePlayground bool
// GraphQLDebug skips query validation + response sanitization in
// go-graph. Dev-only. Default false.
GraphQLDebug bool
// GraphQLPretty pretty-prints JSON responses. Convenient while
// exploring; ship off in prod.
GraphQLPretty bool
// GlobalRateLimit applies across every endpoint — the whole app
// consumes from one bucket. Combine with per-op nexus.RateLimit()
// declarations for layered protection: the request must pass both
// the global bucket and the op's bucket. Zero disables.
//
// Set PerIP to scope the global bucket per caller IP.
GlobalRateLimit ratelimit.Limit
// GlobalMiddleware stacks on the Gin engine root, so every REST
// endpoint, GraphQL POST, WebSocket upgrade, and dashboard request
// flows through it in registration order. Use for cross-cutting
// concerns (request-id, logger, CORS, global rate limit, auth pre-
// gate, etc.). Each bundle's Gin field runs; nil Gin realizations
// are skipped silently. Per-op middleware (via nexus.Use on a
// registration) layers on top.
GlobalMiddleware []middleware.Middleware
// RateLimitStore replaces the default in-memory rate-limit store.
// Set when you want to share the store between the app and externally-
// built middleware bundles (ratelimit.NewMiddleware consumes a Store),
// or for persistence / multi-replica via a Redis-backed implementation.
// Nil → app builds its own MemoryStore at boot (or cache-backed when
// Cache is set — see below).
RateLimitStore ratelimit.Store
// MetricsStore replaces the default metrics store. Parallel to
// RateLimitStore — explicit wins over Cache-driven defaults.
MetricsStore metrics.Store
// DashboardMiddleware gates the /__nexus surface behind user-supplied
// middleware — typically auth + permission checks. Each bundle's
// Gin realization runs in registration order on the /__nexus route
// group BEFORE any dashboard handler, covering the JSON API,
// WebSocket events, and the embedded Vue UI in one pass.
//
// nexus.Config{
// EnableDashboard: true,
// DashboardMiddleware: []middleware.Middleware{
// {Name: "auth", Gin: bearerAuth},
// {Name: "admin", Gin: requireAdminRole},
// },
// }
//
// Bundles whose Gin field is nil are ignored for the dashboard (no
// graph-only protection makes sense here — the dashboard itself
// isn't GraphQL).
DashboardMiddleware []middleware.Middleware
// Cache is an optional nexus cache.Manager. When set, nexus uses it
// as the default backing for metrics + rate-limit stores so counters
// and overrides benefit from the app's cache tier (Redis when
// configured via env, go-cache otherwise) without extra wiring.
//
// Explicit RateLimitStore / MetricsStore settings still win — this
// is just the default when those are nil.
Cache *cache.Manager
}
Config drives how nexus.Run builds the app. Supply it as the first argument to nexus.Run; users never construct a *App directly when using the top-level builder.
type CronBuilder ¶ added in v0.3.0
type CronBuilder struct {
// contains filtered or unexported fields
}
CronBuilder accumulates optional metadata before Handler registers the job with the scheduler.
func (*CronBuilder) Describe ¶ added in v0.3.0
func (c *CronBuilder) Describe(desc string) *CronBuilder
Describe sets a human-readable description shown on the dashboard.
func (*CronBuilder) Handler ¶ added in v0.3.0
func (c *CronBuilder) Handler(fn func(ctx context.Context) error)
Handler finalizes the registration. A bad schedule is logged and the job is dropped; the app keeps running.
func (*CronBuilder) Service ¶ added in v0.3.0
func (c *CronBuilder) Service(name string) *CronBuilder
Service groups the cron under a service on the dashboard. Optional.
type GqlField ¶ added in v0.3.0
type GqlField struct {
Kind graph.FieldKind
ServiceType reflect.Type
Service *Service // nil if dep[0] didn't unwrap (misuse)
Module string // nexus.Module name this field was declared under; "" if unscoped
Field any // graph.QueryField or graph.MutationField
DepTypes []reflect.Type // for resource auto-attach
Deps []reflect.Value // for resource auto-attach (NexusResourceProvider)
// RateLimit is the baseline rate limit this op declared. Auto-mount
// publishes it to the registry so the dashboard can render it and
// — once operator overrides land — show the effective limit beside
// the declared one.
RateLimit *ratelimit.Limit
}
GqlField is the shared-group payload that AsQuery / AsMutation produce and fxmod's auto-mount Invoke consumes. Exported so consumers building their own mount logic can see what's in the graph, but most users never touch it.
type GqlOption ¶ added in v0.3.0
type GqlOption interface {
// contains filtered or unexported methods
}
GqlOption tunes a GraphQL registration. An interface (not a func type) so a single value — notably the nexus.Use cross-transport bundle — can satisfy both GqlOption and RestOption by implementing each's applyToX.
func Deprecated ¶ added in v0.3.0
Deprecated marks the field deprecated. The reason shows up in SDL and the dashboard "deprecated" badge.
func Desc ¶ added in v0.3.0
Desc sets the resolver's description (shown on the dashboard and in SDL documentation).
func GraphMiddleware ¶ added in v0.3.0
func GraphMiddleware(name, description string, mw graph.FieldMiddleware) GqlOption
GraphMiddleware attaches a named graph-only middleware to the resolver. Equivalent to go-graph's WithNamedMiddleware — the name appears in FieldInfo.Middlewares for dashboard rendering (and "auth", "cors", etc. get labelled "builtin" via nexus/middleware.Builtins).
For cross-transport middleware, prefer nexus.Use(middleware.Middleware{...}) — it accepts the same bundle on REST and GraphQL alike.
func Middleware
deprecated
added in
v0.3.0
func Middleware(name, description string, mw graph.FieldMiddleware) GqlOption
Middleware is a deprecated alias for GraphMiddleware. Exists so existing call sites keep compiling while codebases migrate to nexus.Use for cross-transport middleware.
Deprecated: use GraphMiddleware for graph-only middleware, or nexus.Use with a middleware.Middleware bundle for cross-transport.
func OnService ¶ added in v0.3.0
OnService routes this registration onto the given service wrapper type without requiring the handler to take it as a dep. Use when the handler is minimal (`func NewListQuestions(q *QuestionsDB) (...)`) but still belongs to a particular service on the dashboard.
nexus.AsQuery(NewListQuestions, nexus.OnService[*AdvertsService]())
The resolver still needs the owning service to have been provided into the fx graph elsewhere so MountGraphQL can pick up the field.
func RateLimit ¶ added in v0.3.0
RateLimit declares a baseline rate limit for this op. The auto-mount registers it with the app's rate-limit store and wires an enforcement middleware that consults the store on every request. Operators can override the effective limit live from the dashboard — the declared baseline stays in source-of-truth, the override survives in the store.
nexus.AsMutation(NewCreateAdvert,
nexus.RateLimit(ratelimit.Limit{RPM: 30, PerIP: true}),
)
Burst defaults to RPM/6 when zero (10-second burst window). Set PerIP to true to scope the bucket to the caller's IP; leave false for a shared global bucket.
type MiddlewareOption ¶ added in v0.3.0
type MiddlewareOption struct {
// contains filtered or unexported fields
}
MiddlewareOption carries a Middleware across the AsRest/AsQuery/... call sites. Each transport's option type embeds / converts this, so a single nexus.Use(...) expression can appear wherever the transport accepts it.
func Use ¶ added in v0.3.0
func Use(m middleware.Middleware) MiddlewareOption
Use attaches a transport-agnostic middleware bundle to a registration. Works on AsRest, AsQuery, AsMutation, (future AsSubscription / AsWebSocket) — each transport picks the realization it understands from the bundle (Gin for REST/WS upgrade, Graph for GraphQL). Missing fields are silently ignored so a single bundle can degrade gracefully across transports.
rl := ratelimit.NewMiddleware(store, key, ratelimit.Limit{RPM: 30})
fx.Provide(
nexus.AsMutation(NewCreateAdvert, nexus.Use(rl)),
nexus.AsRest("POST", "/quick", NewQuick, nexus.Use(rl)),
)
For app-wide coverage (every REST endpoint + GraphQL POST + WS upgrade + the dashboard itself) put the middleware in Config.GlobalMiddleware instead of naming it on each registration.
type NexusResourceProvider ¶ added in v0.3.0
NexusResourceProvider is implemented by managers that know the external resources they front. A manager's NexusResources slice is used in two places:
- Boot-time registration via nexus.ProvideResources — each returned resource.Resource is added to the app registry so it appears on the dashboard with its health, description, and details.
- Service attachment via the GraphQL auto-mount — whenever a resolver names this manager as a dep, every resource in the slice gets linked to the owning service by name, drawing the architecture edge.
A manager may list more resources than any one handler uses; the edge is drawn per named resource on every service that mentions the manager.
func (m *DBManager) NexusResources() []resource.Resource {
var out []resource.Resource
m.Each(func(name string, db *DB) {
out = append(out, resource.NewDatabase(name, ...))
})
return out
}
type Option ¶
type Option interface {
// contains filtered or unexported methods
}
Option composes a nexus app. Everything returned by Provide, Supply, Invoke, Module, AsRest, AsQuery, AsMutation, AsWebSocket, AsSubscription is an Option, ready to pass to Run. fx is an implementation detail — user code imports only nexus.
func AsMutation ¶ added in v0.3.0
AsMutation is the mutation analogue of AsQuery.
func AsQuery ¶ added in v0.3.0
AsQuery registers a GraphQL query from a plain Go handler. The handler's signature is inspected reflectively:
- First param should be the service wrapper (e.g. *AdvertsService). Its type is used as the fx value-group key so MountGraphQL[*AdvertsService] picks up this query.
- Subsequent params are fx-injected deps.
- Optional last param is an args struct. Field tags drive arg config: graphql:"name" — arg name (defaults to lowercased field name) graphql:"name,required" — NonNull validate:"required" — graph.Required() validate:"len=3|120" — graph.StringLength(3, 120) validate:"int=1|100" — graph.Int(1, 100) validate:"oneof=a|b|c" — graph.OneOf("a","b","c") Chain multiple rules with commas.
- Return type must be (T, error). T is the resolver's return; pointer and slice wrappers are honored.
Op name defaults to the handler's func name, stripping a leading "New" and lowercasing the first rune ("NewGetAllAdverts" → "getAllAdverts"). Override with nexus.Op("explicit").
fx.Provide(
nexus.AsQuery(NewGetAllAdverts),
nexus.AsMutation(NewCreateAdvert,
nexus.Middleware("auth", "Bearer token", AuthMw)),
)
func AsRest ¶ added in v0.3.0
func AsRest(method, path string, fn any, opts ...RestOption) Option
AsRest registers a REST endpoint from a plain Go handler. The handler's signature is inspected via reflection:
- Leading params are fx-injected deps. The first such param should be your service wrapper (see docs on Service) — its type grounds the endpoint in a service node on the dashboard.
- The optional last param is an "args" struct whose tags direct gin on how to bind from the request: uri:"id" → ShouldBindUri query:"x" → ShouldBindQuery header:"x" → ShouldBindHeader form:"x" → ShouldBind (multipart/url-encoded) json:"x" → ShouldBindJSON (for non-GET; default when other binders are absent)
- The return may be (T, error), (T), (error), or nothing. T gets JSON-marshalled with status 200 (201 for POST) on success; errors become status 500 with {"error": "..."}.
Returns an fx.Option; drop it into fx.Provide.
fx.Provide(
nexus.AsRest("GET", "/pets", NewListPets),
nexus.AsRest("POST", "/pets", NewCreatePet),
nexus.AsRest("GET", "/pets/:id", NewGetPet),
)
func AsSubscription ¶ added in v0.3.0
AsSubscription is reserved for a follow-up: subscriptions use a separate builder (SubscriptionResolver[T] with PubSub + channel plumbing) that we haven't taught the reflective path yet. Use graph.NewSubscriptionResolver directly for now; once the reflective SubscriptionResolverFromType exists this helper will mirror AsQuery/AsMutation.
func AsWebSocket ¶ added in v0.3.0
AsWebSocket is reserved. WebSocket endpoints have a multi-callback shape (OnConnect / OnMessage / OnClose) or use Hub-managed messaging — neither collapses into the single-function reflective signature that AsRest and AsQuery/AsMutation share. For now, continue declaring WS endpoints via (*nexus.Service).WebSocket(path).OnMessage(...).Mount().
A follow-up will introduce a handler shape like:
func NewPetsStream(svc *PetsService, hub *ws.Hub, conn *websocket.Conn) error { ... }
with AsWebSocket reflecting on it, registering the ws.Builder, and returning an fx.Invoke.
func Invoke ¶ added in v0.3.0
Invoke runs a function at startup, resolving its parameters from the graph. Use for side-effects on boot — attaching resources, registering hooks, seeding state. Multiple Invoke options run in registration order.
nexus.Invoke(func(app *nexus.App, dbs *DBManager) {
app.OnResourceUse(dbs)
})
func Module ¶ added in v0.3.0
Module groups options under a name. Mirrors fx.Module's logging — the group name appears in startup/shutdown logs and in error messages, which helps when several modules touch the same service or resource. The name is also stamped onto every AsQuery/AsMutation/AsRest registration inside the module so the dashboard's architecture view can group endpoints by module container.
var advertsModule = nexus.Module("adverts",
nexus.Provide(NewAdvertsService),
nexus.AsQuery(NewGetAllAdverts),
nexus.AsMutation(NewCreateAdvert, …),
)
func Provide ¶ added in v0.3.0
Provide registers one or more constructor functions with the dep graph. Return types are entered into the graph; parameter types are resolved from it. Same semantics as fx.Provide.
nexus.Provide(NewDBManager, NewCacheManager)
func ProvideResources ¶ added in v0.3.0
ProvideResources is like Provide but also auto-registers each constructed instance's resources at boot. For any fn whose returned value implements NexusResourceProvider, every resource.Resource it reports is passed to app.Register; if it also satisfies UseReporter (e.g. *multi.Registry), app.OnResourceUse is wired automatically so resolver→resource edges appear on first UsingCtx call.
This replaces the old pattern of a "resources" module full of resource.NewDatabase / NewCache calls — managers now describe their resources themselves via NexusResources() []resource.Resource, and a single ProvideResources does all the wiring.
nexus.ProvideResources(ProvideDBs, NewCacheManager)
Types that don't implement either interface fall through to a plain Provide — so it's safe to pass mixed providers.
func ProvideService ¶ added in v0.6.0
ProvideService is like Provide but inspects the constructor's parameters for resources (NexusResourceProvider) and other services (service-wrapper types — pointer to a struct that anonymously embeds *nexus.Service) and records them onto the service's registry entry. The dashboard uses those records to draw architecture edges at the SERVICE layer:
func NewAdvertsService(app *nexus.App, users *UsersService, db *DBManager) *AdvertsService {
return &AdvertsService{Service: app.Service("adverts")}
}
nexus.ProvideService(NewAdvertsService)
// → registry sees: adverts.ServiceDeps = ["users"]
// adverts.ResourceDeps = [<whatever db.NexusResources() returns>]
The constructed service still flows into fx's dep graph the same way fx.Provide would wire it, so downstream consumers (other services, resolvers) get it injected normally. The ONLY side effect is the registry metadata that feeds the architecture view — nothing observable happens at runtime.
Only the first return value is inspected; trailing (T, error) returns are supported. Constructors that don't return a service wrapper are still Provide'd (same as plain Provide), but no service deps are recorded — the option gracefully no-ops in that case.
func Raw ¶ added in v0.3.0
Raw is an escape hatch: accept any fx.Option and route it through nexus. For features nexus hasn't mirrored yet (fx.Decorate, fx.Replace, named values via fx.Annotate with ParamTags, etc.) or one-off integrations. Normal apps never need it.
nexus.Raw(fx.Decorate(wrapLogger))
type Params ¶ added in v0.3.0
Params is the bundle a reflective resolver receives when it wants more than just typed args — namely the resolve context, parent source, or schema info. Use it as the last parameter of an AsQuery / AsMutation handler (or AsRest, where only Context is filled).
func NewCreateAdvert(
svc *AdvertsService,
dbs *DBManager,
cache *CacheManager,
p nexus.Params[CreateAdvertArgs],
) (*AdvertResponse, error) {
advert := Advert{Title: p.Args.Title, EmployerName: p.Args.EmployerName}
return create(p.Context, advert)
}
The type parameter T is the args struct — its fields carry the same `graphql:"..."` and `validate:"..."` tags as the legacy flat-args form. Use Params[struct{}] for resolvers that need Context/Source/Info but have no user-supplied args.
For simple handlers that only need a context.Context, you can still take that as a plain parameter; Params[T] is additive, not required.
type RestOption ¶ added in v0.3.0
type RestOption interface {
// contains filtered or unexported methods
}
RestOption tunes an AsRest registration. Interface (not a func) so nexus.Use can satisfy both GqlOption and RestOption from a single value. The one-off func-shaped helpers below adapt via restOptionFn.
func Description ¶ added in v0.3.0
func Description(s string) RestOption
Description sets the human-readable description shown on the dashboard.
type Service ¶
type Service struct {
// contains filtered or unexported fields
}
Service is a named group of endpoints. Services are the nodes the dashboard draws in the architecture view.
A Service also carries the GraphQL mount path for reflective controllers registered via nexus.AsQuery / AsMutation. The auto-mount step inside fxmod.Module reads this path at fx.Start and wires the schema onto the engine. Default is "/graphql"; override via (*Service).AtGraphQL.
func (*Service) AtGraphQL ¶ added in v0.3.0
AtGraphQL overrides the GraphQL mount path for this service. Most apps keep the default ("/graphql") — override only when you need a per-service path (e.g. "/admin/graphql") or want to unify multiple nexus apps behind the same reverse proxy.
app.Service("admin").AtGraphQL("/admin/graphql").Describe("Admin ops")
func (*Service) Attach ¶
Attach links a resource to this service so the dashboard draws an edge. If the resource isn't already registered, Attach registers it too — that's convenient for ad-hoc services but means typos silently create orphan nodes. For centrally-declared resources, prefer .Using("name") instead.
func (*Service) Auth ¶ added in v0.3.0
func (s *Service) Auth(fn UserDetailsFn) *Service
Auth wires a Bearer-token → user hook. Resolvers read the user via graph.GetRootInfo(p, "details", &user) after successful authentication. Per-service because different services often use different auth mechanisms (admin vs public).
func (*Service) GraphQLPath ¶ added in v0.3.0
GraphQLPath returns the mount path set via AtGraphQL (or the default). Read by the auto-mount Invoke; users rarely need this.
func (*Service) MountGraphQL ¶
MountGraphQL attaches schema (assembled by go-graph or graphql-go) and auto-registers every operation into the nexus registry. Pass gql.With* options for auth (UserDetailsFn), Playground, Pretty, and DEBUG.
func (*Service) Name ¶ added in v0.3.0
Name returns the service's identifier (same string used on the dashboard and passed to *App.Service). Exposed so framework internals (the auto- mount Invoke, service wrappers) can identify a service without reaching into the private field.
func (*Service) Using ¶
Using attaches already-registered resources by name so the dashboard draws edges. An empty string resolves to the default database (the resource of kind Database marked resource.AsDefault(), or the lexically-first if none is marked). Unknown names are attached anyway so the registry shows a disconnected edge — surfacing the typo rather than hiding it.
app.Service("adverts").Using("").MountGraphQL(...) // default DB
app.Service("qb").Using("questions", "session").MountGraphQL(...) // explicit
func (*Service) UsingDefaults ¶
UsingDefaults attaches the default resource of every kind that has at least one registered (database, cache, queue). Useful for services that touch the common "main DB + session cache" pair without naming either.
type UseReporter ¶
UseReporter is satisfied by any type that exposes an OnUse hook with this exact signature. multi.Registry and anything embedding it fit — including the project's own DBManager wrapper. This is a structural interface so nexus doesn't need to import nexus/multi directly.
type UserDetailsFn ¶ added in v0.3.0
UserDetailsFn, when set on a service, routes GraphQL requests through graph.NewHTTP so resolvers can read the authenticated user via graph.GetRootInfo(p, "details", &user). Returning an error aborts the request with the framework's standard unauthenticated shape.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package auth is nexus's built-in authentication surface.
|
Package auth is nexus's built-in authentication surface. |
|
Package cache provides a Redis + in-memory hybrid cache for nexus apps, ported from the oats_applicant implementation.
|
Package cache provides a Redis + in-memory hybrid cache for nexus apps, ported from the oats_applicant implementation. |
|
Package cron registers and runs scheduled jobs alongside the app's HTTP surface.
|
Package cron registers and runs scheduled jobs alongside the app's HTTP surface. |
|
Package dashboard mounts the nexus introspection surface under /__nexus.
|
Package dashboard mounts the nexus introspection surface under /__nexus. |
|
Package db is nexus's driver-agnostic GORM manager.
|
Package db is nexus's driver-agnostic GORM manager. |
|
examples
|
|
|
fxapp
command
An example showing nexus's top-level builder: nexus.Run composes modules, nexus.Provide / Invoke / Module replace fx.Provide / Invoke / Module — no go.uber.org/fx import in user code.
|
An example showing nexus's top-level builder: nexus.Run composes modules, nexus.Provide / Invoke / Module replace fx.Provide / Invoke / Module — no go.uber.org/fx import in user code. |
|
graphapp
command
Example: a complete GraphQL service wired with nexus's reflective controller API.
|
Example: a complete GraphQL service wired with nexus's reflective controller API. |
|
petstore
command
|
|
|
wstest
command
|
|
|
Package graph provides a modern, secure GraphQL handler for Go with built-in authentication, validation, and an intuitive builder API.
|
Package graph provides a modern, secure GraphQL handler for Go with built-in authentication, validation, and an intuitive builder API. |
|
Package metrics records per-endpoint request counts + errors so the dashboard can show at-a-glance health next to each op: how busy it is, whether it's failing, and if so, what the last error was.
|
Package metrics records per-endpoint request counts + errors so the dashboard can show at-a-glance health next to each op: how busy it is, whether it's failing, and if so, what the last error was. |
|
Package middleware defines nexus's cross-transport middleware model.
|
Package middleware defines nexus's cross-transport middleware model. |
|
Package multi routes N named instances of the same type behind a single .Using(name) dispatcher.
|
Package multi routes N named instances of the same type behind a single .Using(name) dispatcher. |
|
Package ratelimit provides the rate-limit primitives nexus uses to throttle endpoints: a Limit shape, a Store interface (pluggable to memory, Redis, or any backend), and a token-bucket MemoryStore.
|
Package ratelimit provides the rate-limit primitives nexus uses to throttle endpoints: a Limit shape, a Store interface (pluggable to memory, Redis, or any backend), and a token-bucket MemoryStore. |
|
Package registry stores metadata about every endpoint a nexus app exposes.
|
Package registry stores metadata about every endpoint a nexus app exposes. |
|
Package resource defines the abstractions nexus uses to know about databases, caches, message queues, and other external dependencies so they show up in the dashboard's Architecture view with health status.
|
Package resource defines the abstractions nexus uses to know about databases, caches, message queues, and other external dependencies so they show up in the dashboard's Architecture view with health status. |
|
Package trace captures request-lifecycle events (start, end, downstream calls, logs) into an in-memory ring buffer and fans them out to subscribers such as the dashboard.
|
Package trace captures request-lifecycle events (start, end, downstream calls, logs) into an in-memory ring buffer and fans them out to subscribers such as the dashboard. |
|
transport
|
|
|
gql
Package gql mounts a GraphQL schema (typically assembled by github.com/paulmanoni/nexus/graph) onto Gin and introspects its operations into the nexus registry.
|
Package gql mounts a GraphQL schema (typically assembled by github.com/paulmanoni/nexus/graph) onto Gin and introspects its operations into the nexus registry. |
|
rest
Package rest wires REST endpoints onto a Gin engine and records metadata about them in the nexus registry.
|
Package rest wires REST endpoints onto a Gin engine and records metadata about them in the nexus registry. |
|
ws
Package ws wires WebSocket endpoints onto a Gin engine using gorilla/websocket and records metadata about them in the nexus registry.
|
Package ws wires WebSocket endpoints onto a Gin engine using gorilla/websocket and records metadata about them in the nexus registry. |

