Discovery & Inspection

GoNest provides runtime introspection tools for examining the application’s module graph, providers, controllers, and dependencies. Useful for debugging, admin dashboards, and tooling.

DiscoveryService

DiscoveryService discovers providers and controllers across all modules at runtime. Equivalent to NestJS DiscoveryService.

discovery := app.GetDiscoveryService()

List All Providers

providers := discovery.GetProviders()
for _, p := range providers {
    fmt.Printf("Type: %s, Module: %v\n", p.Type, p.Module)
    // p.Instance is the resolved instance
}

List All Controllers

controllers := discovery.GetControllers()
for _, c := range controllers {
    fmt.Printf("Controller: %T\n", c.Instance)
}

Find Providers by Interface

Use the generic helper to find all providers implementing a specific interface:

// Find all providers that implement HealthIndicator
indicators := gonest.GetProvidersWithInterface[health.HealthIndicator](discovery)
for _, indicator := range indicators {
    result := indicator.Check()
    fmt.Println(result.Status)
}

DiscoveredProvider

FieldTypeDescription
InstanceanyThe resolved provider instance
Typereflect.TypeThe provider’s Go type
Module*ModuleThe module that hosts this provider

DiscoveredController

FieldTypeDescription
InstanceControllerThe controller instance
Module*ModuleThe module that hosts this controller

GraphInspector

GraphInspector analyzes the dependency graph of the entire application. Equivalent to NestJS GraphInspector.

inspector := app.GetGraphInspector()

Module Graph

modules := inspector.GetModules()
for _, node := range modules {
    fmt.Printf("Module with %d imports\n", len(node.Imports))
}

Dependency Edges

// Dependencies for a specific module
edges := inspector.GetDependencies(myModule)
for _, edge := range edges {
    fmt.Printf("%s -> %s\n", edge.Source, edge.Target)
}

// All dependencies across the application
allEdges := inspector.GetAllDependencies()

Serialized Graph

Export the entire dependency graph as JSON for visualization or tooling:

graph := inspector.Serialize()

// Get JSON
jsonData, _ := graph.ToJSON()
jsonPretty, _ := graph.ToJSONIndent()

// Query the graph
node := graph.FindNode(nodeID)
outEdges := graph.FindEdgesFrom(nodeID)
inEdges := graph.FindEdgesTo(nodeID)

The serialized graph contains:

Nodes (GraphNode):

FieldTypeDescription
IDstringDeterministic unique identifier
LabelstringHuman-readable name
Typestring"module", "provider", or "controller"
Metadatamap[string]anyScope, resolved status, counts, etc.

Edges (GraphEdge):

FieldTypeDescription
IDstringUnique edge identifier
SourcestringSource node ID
TargetstringTarget node ID
Typestring"dependency", "import", "export", or "contains"

Reflector

Reflector stores and retrieves metadata attached to handlers. Guards and interceptors use this to read route-level configuration.

reflector := gonest.NewReflector()

// Store metadata
reflector.Set(handlerID, "roles", []string{"admin"})

// Retrieve metadata
roles, ok := reflector.Get(handlerID, "roles")

// Get all metadata for a handler
all := reflector.GetAll(handlerID)

Generic Typed Retrieval

In guards and interceptors, use GetMetadata with the ExecutionContext:

func (g *RolesGuard) CanActivate(ctx gonest.ExecutionContext) (bool, error) {
    roles, ok := gonest.GetMetadata[[]string](ctx, "roles")
    if !ok {
        return true, nil // no roles required
    }
    // check roles...
}

Accessing from ApplicationContext

Both services are also available on non-HTTP application contexts:

ctx, _ := gonest.CreateApplicationContext(AppModule)
discovery := ctx.GetDiscoveryService()
inspector := ctx.GetGraphInspector()