zoobzio December 29, 2025 3 mins Edit this page

Scanning Guide

Inspect vs Scan

Sentinel provides two extraction modes:

Inspect

Extracts metadata for a single type only:

metadata := sentinel.Inspect[User]()
// Only User is cached
// Related types (Profile, Order) are NOT cached

Use Inspect when:

  • You need metadata for specific types
  • You want fine-grained control over caching
  • You're working with types that have external dependencies

Scan

Recursively extracts a type and all related types within your module:

metadata := sentinel.Scan[User]()
// User is cached
// Profile, Order, Address, and all transitively related types are cached

Use Scan when:

  • You want to discover your entire domain model
  • You're building schema exports or documentation
  • You need relationship graphs

Module Boundary Detection

Scan only processes types within your module to avoid pulling in external library types.

How It Works

Sentinel uses debug.ReadBuildInfo() to read your module path from go.mod:

go.mod: module github.com/you/myapp

Types are scanned if their package path starts with your module path:

// Your module: github.com/you/myapp

github.com/you/myapp/models.User      // ✓ Scanned
github.com/you/myapp/api/types.Request // ✓ Scanned
github.com/lib/pq.NullString           // ✗ Ignored
time.Time                               // ✗ Ignored (stdlib)

Vanity Imports

Module detection correctly handles vanity import paths:

go.mod: module go.yourcompany.com/service

This works regardless of where the code is actually hosted.

Relationship Kinds

When scanning, Sentinel tracks how types relate:

type User struct {
    Profile  *Profile          // reference
    Orders   []Order           // collection
    Settings                   // embedding (anonymous)
    Metadata map[string]Meta   // map
}

Inspecting Relationships

After scanning, explore relationships:

sentinel.Scan[User]()

// All types that User references
rels := sentinel.GetRelationships[User]()

// All types that reference Profile
refs := sentinel.GetReferencedBy[Profile]()

// List all cached types
types := sentinel.Browse()

// Export complete schema
schema := sentinel.Schema()

Best Practices

  1. Scan once at startup from your root domain type
  2. Use Inspect for targeted extraction of specific types
  3. Register custom tags before first Scan/Inspect call
  4. Export Schema for documentation or code generation

Next Steps