Help us shape the future of Go! Take the 2026 Go Developer Survey

servicecatalog

package
v1.0.14 Latest Latest
Warning

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

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

Documentation

Overview

Package servicecatalog defines Forge's browse-only, declared RPC/code inventory. It contains no endpoint values, credentials, invocation handles or runtime health.

Index

Constants

View Source
const (
	Schema        = "forge.dev/service-catalog/v1"
	GeneratedPath = "gen/forge_service_catalog.json"
	BundlePath    = "forge/service-catalog.json"
)
View Source
const DiagnosticBundleMethodSetsOmitted = "bundle_method_sets_omitted"

DiagnosticBundleMethodSetsOmitted marks a catalog whose code method sets (of components, implementation candidates and bindings) were left out: an empty Methods list there means "not recorded", never "has no methods". A bundle copy always carries it (ForBundle strips the sets from a catalog an earlier forge committed), and since v1.0.8 so does the committed gen/ catalog, which records none: a method set is a function of arbitrary Go in its package, so recording it made gen/ stale on Go changes no forge input saw.

Variables

This section is empty.

Functions

func ForBundle added in v1.0.6

func ForBundle(c *Catalog)

ForBundle reduces c to the copy a bundle carries: what a hosted reader serves to a browser, bounded by what its readers use rather than by the project's size.

  • Each service's Descriptor keeps only Schemas, the request/response shapes the RPC explorer renders. Methods, Messages, SchemaFiles, enums and Go package data are the generator's own view, and were most of a large project's catalog.
  • The code method sets of components, implementation candidates and bindings are dropped, and the DiagnosticBundleMethodSetsOmitted diagnostic says so (gen/ has carried none since v1.0.8; a catalog an earlier forge committed still does). The topology stays: every component, binding, candidate, provider and client. Method sets are one entry per Go method reachable through the composition graph (reliant: ~3,000 entries, 1.2 MB), and no hosted reader uses them.
  • Idempotency is the closed set Method documents (Idempotency).

The result is still schema v1 and decodes with Decode. Sources are left as they are; Locate runs before or after it.

func Idempotency added in v1.0.6

func Idempotency(level string) string

Idempotency maps a method's protobuf idempotency level (the MethodOptions.IdempotencyLevel name, or "" when unset) to the catalog's closed set: IDEMPOTENT, NO_SIDE_EFFECTS, else UNKNOWN.

func Locate added in v1.0.6

func Locate(c *Catalog, readFile func(path string) ([]byte, error))

Locate turns every committed Source in c into a located one: it resolves each Symbol to its line in the source being built, which is what a bundle carries. readFile reads a module-relative path (Decode has already refused absolute and escaping ones). Each file is parsed once, syntax only.

A source whose file cannot be read or parsed, or no longer declares its symbol, becomes the zero Source: the location is unknown, never guessed. Sources that are already located or unknown are left alone.

func MethodID

func MethodID(scope, owner, method string) string

MethodID is a stable low-cardinality symbol identity. Signature, source line, build, instance and arguments deliberately do not enter the identity.

func MethodIdentity

func MethodIdentity(scope, owner, namespace, method string) (id, legacyName string)

MethodIdentity is the join metadata shared by the catalog and generated decorators. Owner is the exposed interface/receiver whose method set is being decorated, NOT the receiver declaring an inherited/embedded method. Namespace is the actual instrumentation namespace (normally the Go package clause), not an import-path basename. Neither signature nor declaration location enters ID.

func NewClient

func NewClient[T any](binding ClientBinding, constructor func(connect.HTTPClient, string, ...connect.ClientOption) T, httpClient connect.HTTPClient, baseURL string, opts ...connect.ClientOption) T

NewClient calls the original generated Connect constructor without changing its HTTPClient, resolved baseURL or option order. T remains its generated client interface. Declare this call directly in a composition provider so forge generate can inventory it. Dynamic metadata is explicitly unresolved.

Types

type Binding

type Binding struct {
	Consumer   string       `json:"consumer"`
	Field      string       `json:"field"`
	Interface  string       `json:"interface"`
	Methods    []CodeMethod `json:"methods"`
	Candidates []string     `json:"candidates"` // assignable producers, NOT selected bindings
	Providers  []string     `json:"providers"`  // accessors in this field's composition expression
	Resolution string       `json:"resolution"` // composition_expression or unresolved
}

type Catalog

type Catalog struct {
	Schema      string       `json:"schema"`
	Module      string       `json:"module"`
	Processes   []Process    `json:"processes"`
	Services    []Service    `json:"services"`
	Components  []Component  `json:"components"`
	Bindings    []Binding    `json:"bindings"`
	Clients     []Client     `json:"clients"`
	Diagnostics []Diagnostic `json:"diagnostics"`
}

Catalog is generated from the same typed composition model and wire descriptor as the application. Missing evidence is explicit; none of these edges proves a call.

func Decode

func Decode(raw []byte) (Catalog, error)

Decode validates catalog bytes before a browser/hosted ingest consumes them. It has no size bound of its own: a catalog grows with the project it describes, and the bytes are already in memory, so the bound belongs to the reader that fetched them (a bundle layer's total, a registry blob read). It authenticates no provenance: callers must verify the containing OCI bundle digest and apply their existing project/environment authorization.

It accepts either Source form: the committed one (path + symbol) and the located one a bundle carries (path + line). DecodeLocated accepts only the latter.

func DecodeLocated added in v1.0.6

func DecodeLocated(raw []byte) (Catalog, error)

DecodeLocated is Decode for a bundle's copy: every source must be located (path + line) or unknown, never symbolic. A bundle's readers decode the v1 Source as {path, line} and refuse any other key, so a symbolic source that reached one would void the whole catalog.

type Client

type Client struct {
	ID          string `json:"id"`
	Provider    string `json:"provider"`
	Service     string `json:"service"`
	ConfigField string `json:"config_field"` // existing fully-qualified proto config field, NOT its value
	Constructor string `json:"constructor"`
	Source      Source `json:"source"`
	Resolution  string `json:"resolution"` // declared; no target URL inference
}

type ClientBinding

type ClientBinding struct {
	Service     string
	ConfigField string
}

ClientBinding describes the existing endpoint's config FIELD, not its value. Service is a fully-qualified protobuf service (use the generated service name constant); ConfigField is e.g. "shop.config.v1.API.orders_url". This metadata grants no authority and changes no HTTP, auth, tracing or retry behavior.

type CodeMethod

type CodeMethod struct {
	ID         string `json:"id"`
	Name       string `json:"name"`
	Signature  string `json:"signature"`   // Go types qualified by import path
	Scope      string `json:"scope"`       // legacy instrumentation scope
	LegacyName string `json:"legacy_name"` // legacy pkg.Method span name
	Source     Source `json:"source"`
}

type Component

type Component struct {
	ID      string       `json:"id"`
	Name    string       `json:"name"`
	Kind    string       `json:"kind"`
	Type    string       `json:"type"`
	Source  Source       `json:"source"`
	Methods []CodeMethod `json:"methods"`
	// ImplementationCandidates are assignable concrete types in the component's
	// package. They are not proof of which implementation a constructor returns.
	ImplementationCandidates []Implementation `json:"implementation_candidates"`
}

type Diagnostic

type Diagnostic struct {
	Code      string `json:"code"`
	Component string `json:"component,omitempty"`
	Source    Source `json:"source"`
}

type Implementation

type Implementation struct {
	Type    string       `json:"type"`
	Source  Source       `json:"source"`
	Methods []CodeMethod `json:"methods"`
}

type Method

type Method struct {
	ID              string `json:"id"` // full proto service + "/" + method
	Name            string `json:"name"`
	Input           string `json:"input"`
	Output          string `json:"output"`
	ClientStreaming bool   `json:"client_streaming"`
	ServerStreaming bool   `json:"server_streaming"`
	Idempotency     string `json:"idempotency"` // UNKNOWN, IDEMPOTENT, NO_SIDE_EFFECTS
	AuthRequired    bool   `json:"auth_required"`
}

type Process

type Process struct {
	ID         string   `json:"id"`
	Root       string   `json:"root"`
	Command    []string `json:"command"`
	Components []string `json:"components"`
	Serves     []Serve  `json:"serves"`
	Clients    []string `json:"clients"` // registrations reachable by this root: can-call only
	Source     Source   `json:"source"`
}

type Serve

type Serve struct {
	Component  string `json:"component"` // handler component; method names join to Component.Methods
	Service    string `json:"service"`   // fully-qualified protobuf service
	RouteSet   string `json:"route_set"`
	Audience   string `json:"audience"`
	Resolution string `json:"resolution"` // declared_route_set; not runtime observation
}

type Service

type Service struct {
	Name      string   `json:"name"`
	ProtoFile string   `json:"proto_file"`
	Methods   []Method `json:"methods"`
	// Descriptor is the existing forge descriptor (gen/forge_descriptor/) ServiceDef, unchanged:
	// Schemas, SchemaFiles, Enums and field validate/validate_options are the
	// authoritative schema graph. Do not invent a second validation dialect.
	Descriptor json.RawMessage `json:"descriptor"`
}

type Source

type Source struct {
	Path string `json:"path"` // module-relative, never absolute
	// Symbol is the declaration's name in Path: "NewOrders" (a func), "Orders"
	// (a type), or "Orders.Get" (a method, or a method of an interface type).
	// Only the committed form carries it.
	Symbol string `json:"symbol,omitempty"`
	Line   int    `json:"line"`
}

Source locates a declaration, in one of two forms.

The committed gen/ catalog names it: Path plus Symbol, and no line. A line number moves whenever unrelated code above it does, so a committed catalog that recorded one went stale on every merge that touched a handler file.

The bundle copy carries Path plus Line: Locate resolves each Symbol against the source being built, and the bundle's readers have always required a line with a path. The zero Source means the location is unknown.

func (Source) MarshalJSON added in v1.0.6

func (s Source) MarshalJSON() ([]byte, error)

MarshalJSON writes the committed form ({path, symbol}) when s is symbolic, and the located form ({path, line}) otherwise.

Jump to

Keyboard shortcuts

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