invariant

package module
v0.3.1 Latest Latest
Warning

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

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

Documentation

Overview

CLI projection — call tools from command-line arguments or request files.

Format: ServiceName Method [-r request]

Values for -r are auto-detected:

  • Existing file path → load by extension (.json, .binpb, .pb)
  • Otherwise → parse as inline JSON

Internally proto-first: input is deserialized directly into a proto.Message, passed through invoke() (proto in/out), then marshaled to JSON only at the terminal output boundary.

Package invariant parses FileDescriptorSets into typed descriptor info and projects gRPC services into MCP/CLI/HTTP tools.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func DefaultHTTPMetadataMapper added in v0.3.0

func DefaultHTTPMetadataMapper(r *http.Request) metadata.MD

DefaultHTTPMetadataMapper forwards only common tracing/correlation headers. Authentication middleware should validate credentials and place trusted identity in context, not copy caller-provided identity headers into metadata.

func ParseDescriptorBytes

func ParseDescriptorBytes(data []byte) (*invpb.ParsedDescriptor, error)

ParseDescriptorBytes parses a serialized FileDescriptorSet and returns a ParsedDescriptor. Use this with go:embed to avoid runtime file dependencies.

func Validation added in v0.0.2

func Validation() (grpc.UnaryServerInterceptor, error)

Validation returns an interceptor that runs protovalidate on each request.

Validation failures are returned as INVALID_ARGUMENT with field-level BadRequest details. Requests of types without protovalidate constraints pass through unchanged.

v, err := invariant.Validation()
if err != nil {
    return err
}
server.Use(v)

Streaming RPCs are not covered by the unary interceptor — pair it with ValidationStream and `server.UseStream(vs)` when you have streaming methods with protovalidate constraints.

func ValidationStream added in v0.0.3

func ValidationStream() (grpc.StreamServerInterceptor, error)

ValidationStream returns a stream interceptor that runs protovalidate on the request before opening the stream. Failures short-circuit with INVALID_ARGUMENT and never produce any response messages — the same guarantee callers expect from the unary variant.

Types

type HTTPHeaderProvider

type HTTPHeaderProvider func(ctx context.Context, req *OutboundHTTPRequest) (map[string]string, error)

HTTPHeaderProvider returns extra outbound HTTP headers for ConnectHTTP requests. Typical use: API signatures, short-lived tokens, per-request timestamps.

type HTTPMetadataMapper added in v0.3.0

type HTTPMetadataMapper func(*http.Request) metadata.MD

HTTPMetadataMapper selects untrusted HTTP request values that may be exposed to handlers as incoming gRPC metadata. Invariant applies a reserved-key filter after the mapper returns; identity and authorization metadata cannot be asserted by naming an HTTP header.

type MethodConfig added in v0.2.3

type MethodConfig struct {
	// MaxUnaryRequestBytes overrides the per-server unary cap. Zero =
	// inherit. Use a positive value for methods that legitimately need
	// large bodies (e.g. an object-store Upload accepting hundreds of
	// MiB) while keeping the rest of the surface tight.
	MaxUnaryRequestBytes int64
	// MaxUnaryResponseBytes overrides the encoded unary HTTP response cap.
	// The selected wire encoding (JSON or protobuf) is measured.
	MaxUnaryResponseBytes int64
	// MaxStreamRequestBytes overrides the per-server Connect-streaming
	// request envelope cap. Zero = inherit.
	MaxStreamRequestBytes int64
	// MaxStreamResponseBytes overrides the encoded Connect response-message
	// cap. It applies independently to each message, like gRPC limits.
	MaxStreamResponseBytes int64
}

MethodConfig overrides per-server defaults for one RPC method. Zero-valued fields fall back to the server-level setting. Apply via `Server.ConfigureMethod("/pkg.Service/Method", MethodConfig{...})`.

Request and response limits are independent because protobuf and JSON wire sizes are not interchangeable.

type OutboundHTTPRequest

type OutboundHTTPRequest struct {
	MethodPath string // e.g. "/greet.v1.GreetService/Greet"
	Method     string // e.g. "GET", "POST"
	URL        string // fully expanded URL with query string
	Body       []byte // JSON body bytes (may be empty)
}

OutboundHTTPRequest describes an HTTP request that will be sent by ConnectHTTP. It is passed to HTTPHeaderProvider so callers can compute dynamic auth headers.

type Projection

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

Projection specifies a protocol to serve.

func CLI

func CLI() Projection

CLI returns a projection that runs as a CLI from os.Args.

func GRPC deprecated

func GRPC(port int, opts ...grpc.ServerOption) Projection

GRPC returns the deprecated port-owning gRPC projection. The variadic options remain for source compatibility but are rejected at serve time; pass ordinary grpc.ServerOption values to ServerFromDescriptor/ServerFromBytes instead.

Deprecated: create a listener and call Server.Serve.

func HTTP

func HTTP(port int) Projection

HTTP returns a projection that serves HTTP on the given port.

func MCP

func MCP() Projection

MCP returns a projection that serves MCP over stdio.

type Server

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

Server holds parsed descriptors and registered tools.

func ServerFromBytes

func ServerFromBytes(data []byte, grpcOptions ...grpc.ServerOption) (*Server, error)

ServerFromBytes parses an embedded FileDescriptorSet and returns a configured Server.

func ServerFromDescriptor

func ServerFromDescriptor(path string, grpcOptions ...grpc.ServerOption) (*Server, error)

ServerFromDescriptor reads a descriptor file and returns a configured Server.

func (*Server) ConfigureMethod added in v0.2.3

func (s *Server) ConfigureMethod(methodPath string, cfg MethodConfig)

ConfigureMethod registers a per-method override. The method path is the Connect/gRPC URL form — `/pkg.Service/Method`. Same identity Register and Connect use, so callers can copy-paste from their proto schema. Zero-valued fields in `cfg` inherit from the server-level setting; non-zero fields override.

Typical use: a service has one big RPC (Upload, BulkImport) plus lots of small ones; set the server cap tight and raise just the outlier.

srv := invariant.ServerFromBytes(desc)
srv.SetMaxUnaryRequestBytes(16 * 1024 * 1024)
srv.ConfigureMethod("/files.v1.FileService/Upload", invariant.MethodConfig{
    MaxUnaryRequestBytes: 1 << 30, // 1 GiB
})

Last write wins; re-calling overrides the previous config for that method.

func (*Server) Connect deprecated

func (s *Server) Connect(conn grpc.ClientConnInterface) error

Connect is the compatibility spelling for ConnectGRPC.

Deprecated: use ConnectGRPC to supply a grpc.ClientConnInterface and optional default grpc.CallOption values.

func (*Server) ConnectGRPC added in v0.3.0

func (s *Server) ConnectGRPC(conn grpc.ClientConnInterface, defaultCallOptions ...grpc.CallOption) error

ConnectGRPC registers a gRPC client connection's methods as tools. The caller creates and owns the grpc.ClientConnInterface. Default call options are applied to every projected unary call. Use Include/Exclude to filter optional projection tools; the native proxy service retains every supported unary method.

func (*Server) ConnectHTTP

func (s *Server) ConnectHTTP(baseURL string, serviceName ...string) error

ConnectHTTP registers tools that proxy to a remote HTTP endpoint. Routes are derived from google.api.http annotations when present, otherwise fallback to canonical RPC route: POST /{serviceFullName}/{method}.

func (*Server) Exclude added in v0.0.2

func (s *Server) Exclude(patterns ...string)

Exclude adds glob patterns for methods to exclude. Methods matching any exclude pattern are skipped during projection registration. Exclude is applied after include. Patterns use the same syntax as Include.

func (*Server) GRPCServer added in v0.3.0

func (s *Server) GRPCServer() *grpc.Server

GRPCServer returns the owned native grpc.Server. Access freezes Invariant registration so serving it directly cannot race projection metadata capture.

func (*Server) GetServiceInfo added in v0.3.0

func (s *Server) GetServiceInfo() map[string]grpc.ServiceInfo

func (*Server) GracefulStop added in v0.3.0

func (s *Server) GracefulStop()

func (*Server) HTTPHandler added in v0.0.2

func (s *Server) HTTPHandler() (http.Handler, error)

HTTPHandler returns an http.Handler that serves all registered tools over the Connect protocol. Mount on an existing http.ServeMux or framework router instead of binding a separate port:

mux := http.NewServeMux()
h, _ := server.HTTPHandler()
mux.Handle("/inv/", http.StripPrefix("/inv", h))

Routes:

POST /{package.Service}/{Method}      — invoke a tool (Connect protocol)
GET  /                                — tool catalog (same shape as MCP tools/list)
GET  /__invariant/tools               — tool catalog
GET  /__invariant/descriptor.binpb    — raw FileDescriptorSet bytes

func (*Server) Include added in v0.0.2

func (s *Server) Include(patterns ...string)

Include adds glob patterns for methods to include. Only methods matching at least one include pattern are registered. Patterns are matched against the fully qualified method path: "service.full.Name.MethodName". Use "*" to match any sequence of characters (including dots). Examples: "temporal.api.workflowservice.v1.WorkflowService.*", "*.StartWorkflow*".

func (*Server) Invoke added in v0.0.2

func (s *Server) Invoke(ctx context.Context, toolName string, req proto.Message) (proto.Message, error)

Invoke dispatches a unary request to a registered tool by name. Useful for in-process callers (workflow runtimes, tests) that don't need to spin up a projection.

Returns NOT_FOUND if the tool is unknown, and FAILED_PRECONDITION if the tool is server-streaming — use InvokeStream for those. Both errors project to the right code through every projection.

func (*Server) InvokeStream added in v0.0.2

func (s *Server) InvokeStream(ctx context.Context, toolName string, req proto.Message, send func(proto.Message) error) error

InvokeStream dispatches a server-streaming tool by name. Each emitted response message is delivered to send; the call returns once the handler returns or send returns an error.

Like Invoke, this is the in-process entry point — no projection required.

func (*Server) Register deprecated

func (s *Server) Register(servicer any, serviceName ...string) error

Register discovers methods on servicer that match the service's RPCs and creates tools for each unary (non-streaming) method. If serviceName is empty, auto-matches by finding services whose RPC method names exist on the servicer.

Deprecated: implement the generated server interface and call its Register<Service>Server function with this Server.

func (*Server) RegisterService added in v0.3.0

func (s *Server) RegisterService(desc *grpc.ServiceDesc, impl any)

RegisterService implements grpc.ServiceRegistrar. Generated Register<Service>Server functions can register directly with an Invariant server; the same descriptor and implementation are retained for HTTP, MCP, and CLI projection dispatch.

grpc.ServiceRegistrar cannot return an error, so invalid or late registrations panic with a deterministic invariant-prefixed message, just as generated registration is expected to fail during process setup.

func (*Server) Serve

func (s *Server) Serve(listener net.Listener) error

Serve is the canonical native gRPC lifecycle entry point.

func (*Server) ServeGRPC added in v0.3.0

func (s *Server) ServeGRPC(listener net.Listener) error

ServeGRPC serves the registered generated services on listener.

func (*Server) ServeProjections added in v0.3.0

func (s *Server) ServeProjections(ctx context.Context, projections ...Projection) error

ServeProjections starts the specified optional projections and blocks until ctx is canceled or the first projection returns an error.

ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt)
defer cancel()
server.ServeProjections(ctx, invariant.HTTP(8080))
server.ServeProjections(ctx, invariant.HTTP(8080), invariant.MCP())

On error or cancellation, all projections receive a graceful shutdown signal.

func (*Server) SetMaxStreamRequestBytes added in v0.0.3

func (s *Server) SetMaxStreamRequestBytes(n int64)

SetMaxStreamRequestBytes overrides the Connect streaming request envelope cap. Pass 0 to reset to the default (16 MiB).

func (*Server) SetMaxStreamResponseBytes added in v0.3.0

func (s *Server) SetMaxStreamResponseBytes(n int64)

SetMaxStreamResponseBytes overrides the per-message encoded Connect stream response cap. Pass 0 to reset to the default (16 MiB).

func (*Server) SetMaxUnaryRequestBytes added in v0.0.3

func (s *Server) SetMaxUnaryRequestBytes(n int64)

SetMaxUnaryRequestBytes overrides the HTTP unary body-size cap. Pass 0 to reset to the default (16 MiB).

func (*Server) SetMaxUnaryResponseBytes added in v0.3.0

func (s *Server) SetMaxUnaryResponseBytes(n int64)

SetMaxUnaryResponseBytes overrides the encoded HTTP unary response cap. Pass 0 to reset to the default (16 MiB).

func (*Server) Stop

func (s *Server) Stop()

func (*Server) ToolCatalog added in v0.0.2

func (s *Server) ToolCatalog() []map[string]any

ToolCatalog returns the canonical tool catalog (same shape as MCP `tools/list`). Used by both the HTTP `GET /` endpoint and MCP's `tools/list`.

Streaming tools carry `_meta.streaming: true` so clients can render and consume them differently from unary tools. The MCP spec reserves `_meta` for exactly this kind of server-specific annotation.

func (*Server) Tools added in v0.0.2

func (s *Server) Tools() map[string]*Tool

Tools returns a snapshot of the registered tool names to their Tool metadata.

func (*Server) Use

func (s *Server) Use(interceptor grpc.UnaryServerInterceptor)

Use registers a unary interceptor. Runs in registration order (first registered = outermost) on every unary tool invocation across all projections. Stream RPCs are not affected — use UseStream for those.

func (*Server) UseHTTPHeaderProvider

func (s *Server) UseHTTPHeaderProvider(provider HTTPHeaderProvider)

UseHTTPHeaderProvider sets an optional outbound header provider for ConnectHTTP. The current provider is called for every outbound HTTP request. Like other configuration, it may be changed until serving or invocation begins.

func (*Server) UseHTTPMetadataMapper added in v0.3.0

func (s *Server) UseHTTPMetadataMapper(mapper HTTPMetadataMapper)

UseHTTPMetadataMapper replaces the inbound HTTP metadata mapper. Reserved protocol, authorization, tenant, principal, role, and internal identity keys are removed from the mapper's result before it reaches application code.

func (*Server) UseStream added in v0.0.2

func (s *Server) UseStream(interceptor grpc.StreamServerInterceptor)

UseStream registers a server-streaming interceptor. Mirrors Use but for server-streaming RPCs. Same registration-order semantics.

type ServerCallInfo deprecated

type ServerCallInfo = grpc.UnaryServerInfo

ServerCallInfo is the compatibility name for grpc.UnaryServerInfo.

Deprecated: use grpc.UnaryServerInfo.

type ServerStream deprecated added in v0.0.2

type ServerStream interface {
	Send(msg proto.Message) error
	Context() context.Context
}

ServerStream is retained only for the reflection-based Register compatibility API.

Deprecated: implement the generated grpc.ServerStreamingServer method.

type StreamHandler deprecated added in v0.0.2

type StreamHandler = grpc.StreamHandler

StreamHandler is the compatibility name for grpc.StreamHandler.

Deprecated: use grpc.StreamHandler.

type StreamServerInterceptor deprecated added in v0.0.2

type StreamServerInterceptor = grpc.StreamServerInterceptor

StreamServerInterceptor is the compatibility name for grpc.StreamServerInterceptor.

Deprecated: use grpc.StreamServerInterceptor.

type Tool

type Tool struct {
	Name            string
	Description     string
	InputSchema     map[string]any
	Handler         any
	InputType       string
	OutputType      string
	ServiceFullName string
	MethodName      string
	ServerStreaming bool
	// contains filtered or unexported fields
}

Tool represents a single registered RPC method projected as a tool.

type UnaryHandler deprecated

type UnaryHandler = grpc.UnaryHandler

UnaryHandler is the compatibility name for grpc.UnaryHandler.

Deprecated: use grpc.UnaryHandler.

type UnaryServerInterceptor deprecated

type UnaryServerInterceptor = grpc.UnaryServerInterceptor

UnaryServerInterceptor is the compatibility name for grpc.UnaryServerInterceptor.

Deprecated: use grpc.UnaryServerInterceptor.

Directories

Path Synopsis
gen
tests
gen

Jump to

Keyboard shortcuts

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