Documentation
¶
Overview ¶
Package protoregistry provides a multi-namespace protobuf schema registry with versioning, staging, and hot-swap capabilities.
It uses protocompile to compile .proto source files at runtime, stores versioned schemas in Postgres with content-addressable deduplication, and serves compiled descriptors for dynamic message creation and validation.
Each namespace is an isolated scope — proto imports resolve only within the same namespace, similar to a chroot. Schemas within a namespace are versioned independently, with a staging mechanism for coordinated multi-schema promotions.
Index ¶
- Constants
- type CreateNamespaceRequest
- type Option
- type ParentPinStatus
- type PromoteResult
- type PublishRequest
- type PublishResult
- type RebaseRequest
- type RebaseStatus
- type Registry
- func (r *Registry) CreateNamespace(ctx context.Context, req *CreateNamespaceRequest) error
- func (r *Registry) Current(namespaceID, schemaID string) *snapshot.Snapshot
- func (r *Registry) DiscardStaging(ctx context.Context, namespaceID string) error
- func (r *Registry) GetNamespaceChain(_ context.Context, namespaceID string) ([]string, error)
- func (r *Registry) GetRebaseStatus(ctx context.Context, namespaceID, schemaID string) (*RebaseStatus, error)
- func (r *Registry) Namespaces() *namespace.Registry
- func (r *Registry) Promote(ctx context.Context, namespaceID string) (*PromoteResult, error)
- func (r *Registry) Publish(ctx context.Context, req *PublishRequest) (*PublishResult, error)
- func (r *Registry) Rebase(ctx context.Context, req *RebaseRequest) (*PublishResult, error)
- func (r *Registry) Restore(ctx context.Context) error
- func (r *Registry) Rollback(ctx context.Context, namespaceID, schemaID string, version uint64, ...) error
- func (r *Registry) SetNamespaceParent(ctx context.Context, req *SetNamespaceParentRequest) error
- func (r *Registry) Staged(namespaceID, schemaID string) *snapshot.Snapshot
- type RollbackOptions
- type SetNamespaceParentRequest
Constants ¶
const BuiltinsNamespace = "__builtins__"
BuiltinsNamespace is the reserved namespace for built-in proto files. Schemas published here are available to all namespaces during compilation.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type CreateNamespaceRequest ¶ added in v0.71.0
type CreateNamespaceRequest struct {
NamespaceID string
ParentID *string
Metadata map[string]string
ActorID string
}
CreateNamespaceRequest contains the parameters for creating a namespace. Compared to the implicit creation that happens during Publish, this lets callers establish a namespace explicitly — typically because they want to specify a parent up front. ActorID is recorded in the re-parenting audit log when ParentID is non-nil; tests and admin scripts that don't have a real principal may pass a sentinel like "system".
type Option ¶
type Option func(*Registry)
Option configures a Registry.
func WithAuthorizer ¶ added in v0.71.0
func WithAuthorizer(a authz.Authorizer) Option
WithAuthorizer wires a policy-decision layer for privileged operations (Publish, Promote, CreateNamespace, SetNamespaceParent, Rebase). The default is authz.AllowAll, which permits everything and is suitable only for tests and single-tenant local deployments — when in effect, the registry logs a warning at startup.
func WithCompiler ¶
WithCompiler sets a custom compiler for the registry.
type ParentPinStatus ¶ added in v0.71.0
type ParentPinStatus struct {
ParentNamespaceID string
DepSchemaID string
DepFilename string
PinnedVersion uint64
// CurrentVersion is the parent's current version of (DepSchemaID,
// DepFilename). Zero when the schema or file no longer exists in
// the parent — in that case rebase will fail because the pinned
// file vanished. (Future work: report that case more explicitly.)
CurrentVersion uint64
}
ParentPinStatus describes one pinned cross-namespace dependency and the parent's current version of the same file, so callers can decide whether a rebase is needed and what's likely to change.
type PromoteResult ¶
type PromoteResult struct {
Promoted []store.PromotedSchema
}
PromoteResult contains the outcome of a promote operation.
type PublishRequest ¶
type PublishRequest struct {
NamespaceID string
SchemaID string
Sources map[string][]byte // filename → proto source content
CreatedBy string
Metadata map[string]string
Force bool // when true, allows publishing files that shadow well-known types
}
PublishRequest contains the parameters for publishing a new schema version.
type PublishResult ¶
type PublishResult struct {
Version uint64
Fingerprint string
Snapshot *snapshot.Snapshot
NoChange bool // true if the content is identical to the current staged/current version
}
PublishResult contains the outcome of a publish operation.
type RebaseRequest ¶ added in v0.71.0
type RebaseRequest struct {
NamespaceID string
SchemaID string
// ActorID is recorded in the resulting version's metadata as the
// principal that triggered the rebase.
ActorID string
}
RebaseRequest contains the parameters for rebasing a schema against its parent chain's current state.
type RebaseStatus ¶ added in v0.71.0
type RebaseStatus struct {
// PinStatuses has one entry per cross-namespace dependency the schema
// has pinned. Same-namespace deps are not included.
PinStatuses []ParentPinStatus
// RebaseAvailable is true when at least one cross-namespace pin is
// behind the parent's current state.
RebaseAvailable bool
}
RebaseStatus describes how far the current version of a schema is from the parent state that would result from a fresh rebase. With per-import pinning (decision D3), the diff is reported per pinned parent file, not per "namespace snapshot" — each pinned file may have moved independently in the parent.
type Registry ¶
type Registry struct {
// contains filtered or unexported fields
}
Registry is the top-level orchestrator that ties together compilation, storage, namespace management, and compatibility checking.
func (*Registry) CreateNamespace ¶ added in v0.71.0
func (r *Registry) CreateNamespace(ctx context.Context, req *CreateNamespaceRequest) error
CreateNamespace creates a namespace explicitly, optionally with a parent in the resolution chain. Gated by authz.CanCreateNamespace.
If ParentID is non-nil, the namespace is created first and then re-parented; the re-parenting step is transactional with its audit row (decision D9). If the parent doesn't exist, the namespace creation is rolled back via SoftDelete... — currently we leave the namespace in place because the store doesn't expose a hard-delete primitive. Future work: combine create + set-parent into one transactional store call.
func (*Registry) DiscardStaging ¶
DiscardStaging clears all staged versions in a namespace without promoting.
func (*Registry) GetNamespaceChain ¶ added in v0.71.0
GetNamespaceChain returns the resolution chain for a namespace as an ordered slice of namespace IDs, child-first (the namespace itself at index 0, then its parent, grandparent, etc.). The implicit __builtins__ and Google WKT tiers are not included — they are resolver-level concerns, not addressable namespaces.
Read-only and not gated by authz; the chain is structural metadata. Returns an error only when the namespace doesn't exist.
func (*Registry) GetRebaseStatus ¶ added in v0.71.0
func (r *Registry) GetRebaseStatus(ctx context.Context, namespaceID, schemaID string) (*RebaseStatus, error)
GetRebaseStatus reports for each cross-namespace pin in the schema's current version, whether the parent has moved past it. Idempotent and read-only; safe to call without authz.
func (*Registry) Namespaces ¶
Namespaces returns the namespace registry for direct access.
func (*Registry) Promote ¶
Promote atomically moves all staged versions to current within a namespace. Before promoting, it runs backward compatibility checks on each staged schema against its current version.
func (*Registry) Publish ¶
func (r *Registry) Publish(ctx context.Context, req *PublishRequest) (*PublishResult, error)
Publish compiles new proto sources and stages the result. The new version is not yet visible to consumers — call Promote to make it current.
The compilation resolves imports against the namespace's proposed state (staged versions where they exist, current otherwise), enabling coordinated multi-schema changes.
func (*Registry) Rebase ¶ added in v0.71.0
func (r *Registry) Rebase(ctx context.Context, req *RebaseRequest) (*PublishResult, error)
Rebase re-resolves a schema's parent-chain dependencies against the parent's *current* state and publishes a new version with refreshed per-import pins. Sources are unchanged — pulled from the schema's current version on disk. The new version goes through the standard publish flow (D2 conflict detection, compat checks, staging).
Gated by authz.CanRebase. Internally uses publishInternal so the CanPublish gate doesn't fire — semantically Rebase grants the same access as Publish to the same namespace.
Serialization with concurrent publish (D8) is currently provided by the database's existing primary-key constraints on schema_versions: concurrent attempts to allocate the same next-version number conflict and one fails with a unique-violation. A future enhancement could add an explicit advisory lock per (namespace, schema) for cleaner error reporting.
func (*Registry) Restore ¶
Restore loads all current schema versions from the store and rebuilds the in-memory namespace state. Call this at startup.
Two passes are required so that namespace parent pointers are established before any per-schema work runs. The slow path of buildSnapshot (compiler-version mismatch) calls gatherChainTiers, which relies on the publishing namespace having its in-memory Chain() populated.
func (*Registry) Rollback ¶
func (r *Registry) Rollback(ctx context.Context, namespaceID, schemaID string, version uint64, opts RollbackOptions) error
Rollback stages a previous version of a schema for promotion.
Unless opts.Force is set, Rollback runs the same compat check as a forward Publish, treating the current version as "old" and the target version as "new". This catches the common screw-up of rolling back to a release that lacks API surface (fields, methods, enum values) added in the meantime, which would silently break consumers when the rollback is promoted.
The version must already exist in the store.
func (*Registry) SetNamespaceParent ¶ added in v0.71.0
func (r *Registry) SetNamespaceParent(ctx context.Context, req *SetNamespaceParentRequest) error
SetNamespaceParent re-parents an existing namespace. Gated by authz.CanSetNamespaceParent. The store-level change is transactional with the re-parenting audit-log row (decision D9). The in-memory parent pointer is updated only after a successful commit.
type RollbackOptions ¶
type RollbackOptions struct {
// Force bypasses the API-compat check that would otherwise reject a
// rollback whose target is not backward-compatible with the current
// version. Use sparingly: skipping the check shifts the cost to
// downstream consumers, who may break unexpectedly when the rollback
// is promoted.
Force bool
}
RollbackOptions configures a Rollback call.
type SetNamespaceParentRequest ¶ added in v0.71.0
type SetNamespaceParentRequest struct {
NamespaceID string
ParentID *string // nil clears the parent (reset to implicit root)
ActorID string
}
SetNamespaceParentRequest contains the parameters for re-parenting an existing namespace.
Directories
¶
| Path | Synopsis |
|---|---|
|
Package authz defines the authorization seam for protoregistry.
|
Package authz defines the authorization seam for protoregistry. |
|
Package client provides a remote-backed protobuf descriptor resolver that fetches schemas from a running protoregistry server over gRPC.
|
Package client provides a remote-backed protobuf descriptor resolver that fetches schemas from a running protoregistry server over gRPC. |
|
internal/clienttest
Package clienttest is a test-only harness that wires a real protoregistry server (Postgres + gRPC over bufconn) and exposes a *grpc.ClientConn ready to be passed to client.New, plus helpers for the publish/promote dance.
|
Package clienttest is a test-only harness that wires a real protoregistry server (Postgres + gRPC over bufconn) and exposes a *grpc.ClientConn ready to be passed to client.New, plus helpers for the publish/promote dance. |
|
cmd
|
|
|
protoregistry
command
|
|
|
Package compat checks backward compatibility between schema versions.
|
Package compat checks backward compatibility between schema versions. |
|
Package compiler wraps protocompile to provide namespace-scoped compilation of proto source files.
|
Package compiler wraps protocompile to provide namespace-scoped compilation of proto source files. |
|
internal
|
|
|
ctl
Package ctl implements the protoregistry CLI commands.
|
Package ctl implements the protoregistry CLI commands. |
|
Package migrations embeds the SQL migration files for use by goose.
|
Package migrations embeds the SQL migration files for use by goose. |
|
Package namespace provides the isolation boundary for schemas.
|
Package namespace provides the isolation boundary for schemas. |
|
proto
|
|
|
Package resolve bridges the protoregistry namespace snapshots with protobuf-go's protoregistry types, enabling runtime type resolution for external consumers.
|
Package resolve bridges the protoregistry namespace snapshots with protobuf-go's protoregistry types, enabling runtime type resolution for external consumers. |
|
Package server implements the gRPC RegistryService.
|
Package server implements the gRPC RegistryService. |
|
Package snapshot provides immutable, compiled descriptor sets that are safe for concurrent access.
|
Package snapshot provides immutable, compiled descriptor sets that are safe for concurrent access. |
|
Package store defines the persistence interface for the schema registry.
|
Package store defines the persistence interface for the schema registry. |
|
postgres
Package postgres implements the store.Store interface using PostgreSQL with sqlc-generated query code and pgx as the driver.
|
Package postgres implements the store.Store interface using PostgreSQL with sqlc-generated query code and pgx as the driver. |
|
postgres/pgtest
Package pgtest provides a shared test helper for spinning up a PostgreSQL container with migrations applied.
|
Package pgtest provides a shared test helper for spinning up a PostgreSQL container with migrations applied. |