reference

package
v0.64.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 11, 2026 License: Apache-2.0 Imports: 2 Imported by: 0

Documentation

Overview

Package reference is the cross-service resource-reference seam (F041, WS-021 P1). It carries the machine-readable metadata protoc-gen-svc emits for a field annotated with the standard google.api.resource_reference (AIP-124) and the resolver seam a composition layer uses to batch-fetch referenced targets without an N+1 waterfall.

This package is deliberately stdlib-only so a server-only consumer's module graph stays dependency-light (the repo's check-graph-isolation gate). It defines mechanism, not policy: it does NOT dial services, own a catalog, or know transport — a static/in-process StaticResolver serves tests and the fixture; the catalog-backed resolver lands with WP-A/P2.

The invariant this package upholds is the anti-N+1 guarantee: given N parent resources each naming a target by a foreign key, Load resolves them in exactly ONE BatchGet call per distinct target-id set (DataLoader-style). The referenced field stays a scalar foreign key — this package never introduces a traversable Go edge or a cascade (metadata only; parity with the deliberately edge-less infoblox.ddd.v1.references).

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Load

func Load[T any, P any](
	ctx context.Context,
	resolver ReferenceResolver,
	ref Reference,
	parents []P,
	ids func(P) []string,
	keyOf func(T) string,
) (map[string]T, error)

Load resolves a reference for N parents in exactly ONE BatchGet call (DataLoader-style): it collects the distinct, non-empty target ids named by the parents (via ids), batch-fetches them once through the resolver's client for ref.TargetType, and returns the targets keyed by id.

It is the anti-N+1 primitive F041 AC-5 asserts: for N parents naming M distinct targets it issues one BatchGet of M ids, never M or N single Gets. A missing resolver for the target type is a fail-loud error (never a silent per-row fetch). BatchGet returns targets in id order, so the returned map is built by zipping the deduped id set with the result slice.

T is the target resource's Go type; the resolver's registered client for ref.TargetType must be a BatchGetter[T]. keyOf extracts a target's id so the result can be keyed (BatchGet returns id order, but keyOf keeps the mapping robust to an implementation that returns a different length/order).

Types

type BatchGetter

type BatchGetter[T any] interface {
	// BatchGet retrieves the targets named by ids, in id order. Implementations
	// front a single backend BatchGet call (they are NOT expected to loop).
	BatchGet(ctx context.Context, ids []string) ([]T, error)
}

BatchGetter is the batch-fetch capability a reference target must expose so a reference to it can be resolved without an N+1 waterfall (AIP-137 BatchGet). A generated reference-target service exposes exactly this over its BatchGet client. T is the target resource's Go type (e.g. *regionv1.Region).

type Cardinality

type Cardinality string

Cardinality is whether a reference field names a single target (a scalar FK) or many (a repeated FK).

const (
	// One is a single-target reference (a scalar foreign-key field).
	One Cardinality = "one"
	// Many is a multi-target reference (a repeated foreign-key field).
	Many Cardinality = "many"
)

type Reference

type Reference struct {
	// FieldName is the Go field name on the source resource holding the target's
	// foreign key (e.g. "RegionId").
	FieldName string
	// FKField is the proto field name of that foreign key (e.g. "region_id").
	FKField string
	// TargetType is the referenced resource's AIP-122 type (e.g.
	// "region.example.com/Region"). Globally unique; the target module/endpoint is
	// catalog-resolved from it.
	TargetType string
	// Cardinality is One for a scalar FK, Many for a repeated FK.
	Cardinality Cardinality
}

Reference is the generated metadata for one cross-service reference field: the source field on a resource message points at a target resource type served by (possibly) another microservice. protoc-gen-svc emits a <Svc>References table of these from google.api.resource_reference annotations.

It is metadata ONLY — a composition layer reads it to resolve references; it is not a Go edge and carries no mutation authority. The target module/endpoint is resolved elsewhere (the apx catalog index, WP-A) from TargetType, which is a globally unique AIP-122 resource type.

type ReferenceResolver

type ReferenceResolver interface {
	ResolverFor(targetType string) (client any, ok bool)
}

ReferenceResolver maps a target resource type to a BatchGet-capable client for it. It is the seam between the generated reference metadata and the concrete clients: a composition layer looks up the resolver for a Reference.TargetType and batch-fetches through it.

The returned client is untyped (any) because a resolver serves many target types with different Go types; a caller type-asserts it to a BatchGetter[T] for the target it is resolving (see Load). ok is false when no client is registered for targetType — which a fail-loud composition treats as an error (never a silent per-row fetch).

type StaticResolver

type StaticResolver struct {
	// contains filtered or unexported fields
}

StaticResolver is an in-process ReferenceResolver backed by a map from target type to client. It serves tests and the P1 two-service fixture; the catalog-backed resolver (dialing services from the apx type→endpoint index) lands with WP-A/P2. The zero value is not usable — construct with NewStaticResolver.

func NewStaticResolver

func NewStaticResolver() *StaticResolver

NewStaticResolver returns an empty in-process resolver. Register clients with StaticResolver.Register.

func (*StaticResolver) Register

func (r *StaticResolver) Register(targetType string, client any)

Register wires a BatchGet-capable client for targetType. A later Register for the same type replaces the earlier one.

func (*StaticResolver) ResolverFor

func (r *StaticResolver) ResolverFor(targetType string) (any, bool)

ResolverFor implements ReferenceResolver.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL