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 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 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 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. |

