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

federation

package
v1.2.7 Latest Latest
Warning

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

Go to latest
Published: Aug 18, 2026 License: MIT Imports: 8 Imported by: 0

Documentation

Overview

Package federation implements GraphQL Federation support for multi-service nSelf deployments. Federation is opt-in via NSELF_FEDERATION=true or nself config set federation=true. Single-service deployments continue to use Hasura as the sole GraphQL engine (no Apollo Router injected).

Architecture:

Client
  → Apollo Router (CS_7, port 4000)   — supergraph gateway
    ├─ Hasura subgraph
    ├─ ai subgraph (if installed)
    ├─ claw subgraph (if installed)
    └─ … other plugin subgraphs

Build pipeline (federation mode):

  1. Registry.FromManifests reads installed plugins, collects graphql blocks.
  2. compose.BuildSupergraphYAML writes rover supergraph compose config.
  3. External: rover supergraph compose → supergraph.graphql.
  4. router.ComposeService returns the Apollo Router docker-compose block (CS_7 slot).
  5. nginx template routes /graphql to port 4000 instead of 8080.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func BuildSupergraphYAML

func BuildSupergraphYAML(entries []SubgraphEntry) ([]byte, error)

BuildSupergraphYAML renders the rover supergraph compose configuration from the provided subgraph entries and returns the YAML content as a byte slice. The caller is responsible for writing the result to disk (typically at .nself/federation/supergraph.yaml).

entries must be non-empty. At minimum, the Hasura subgraph must be present.

func ComposeService

func ComposeService(opts RouterComposeOptions) (string, error)

ComposeService returns the docker-compose YAML block for the Apollo Router CS_7 service. The returned string is ready to be injected into the services: section of docker-compose.yml when NSELF_FEDERATION=true.

func NginxDirective

func NginxDirective(federationEnabled bool) string

NginxDirective returns the nginx upstream + location block to redirect /graphql traffic to Apollo Router (port 4000) when federation is enabled, or to Hasura (port 8080) when disabled.

federationEnabled should mirror the NSELF_FEDERATION env var.

func RouterBaseConfig

func RouterBaseConfig() string

RouterBaseConfig returns the base Apollo Router YAML configuration content. This is written to .nself/federation/router.yaml and mounted into the Apollo Router container.

func RunRoverCompose

func RunRoverCompose(ctx context.Context, opts ComposeOptions) error

RunRoverCompose executes `rover supergraph compose --config <yaml> --output <out>`. It returns an error if rover is not found, exits non-zero, or produces no output file. This satisfies the acceptance criterion: "Plugin with invalid schema fails nself build with clear error."

Types

type ComposeOptions

type ComposeOptions struct {
	// SupergraphYAMLPath is the path to the rover supergraph compose config.
	SupergraphYAMLPath string
	// OutputPath is where rover writes supergraph.graphql.
	OutputPath string
	// RoverBin is the path to the rover binary. Defaults to "rover" on PATH.
	RoverBin string
}

ComposeOptions controls the behaviour of RunRoverCompose.

type EntityKey

type EntityKey struct {
	// Type is the GraphQL type name (e.g. "User").
	Type string `yaml:"type" json:"type"`
	// Key is the field used as the @key directive value (e.g. "id").
	Key string `yaml:"key" json:"key"`
}

EntityKey describes a single Apollo Federation entity type owned by a subgraph.

type ManifestGraphQLBlock

type ManifestGraphQLBlock struct {
	// PluginName is the plugin.yaml name field (used in error messages).
	PluginName string
	// PluginPort is the plugin's declared port (substituted for ${PORT}).
	PluginPort int
	// GraphQL is the graphql: block from the manifest.
	GraphQL SubgraphConfig
}

ManifestGraphQLBlock is the subset of the plugin manifest that carries federation registration. It mirrors the YAML fields that plugin authors write in their plugin.yaml under the graphql: key.

This type lives here (not in plugin/) to avoid a circular import: federation → plugin is not allowed because plugin/ is a lower-level package. The caller (build/) reads manifests with plugin.PluginManifest and then calls federation.FromManifestBlocks with the extracted GraphQL fields.

type RouterComposeOptions

type RouterComposeOptions struct {
	// SupergraphPath is the absolute host path to supergraph.graphql.
	SupergraphPath string
	// RouterConfigPath is the absolute host path to router.yaml base config.
	RouterConfigPath string
}

RouterComposeOptions controls the Apollo Router service block generation.

type SubgraphConfig

type SubgraphConfig struct {
	// Enabled must be true for the plugin to participate in federation.
	Enabled bool `yaml:"enabled" json:"enabled"`
	// SubgraphName is the unique lowercase name used in the supergraph schema.
	// Must be a valid GraphQL SDL name: [a-z][a-z0-9_]*.
	SubgraphName string `yaml:"subgraph_name" json:"subgraph_name"`
	// SubgraphURL is the HTTP endpoint that serves the subgraph SDL and
	// resolves federation queries. May contain ${PORT} which is interpolated
	// from the plugin's Port field at build time.
	SubgraphURL string `yaml:"subgraph_url" json:"subgraph_url"`
	// SchemaPath is a repo-relative path to the plugin's static SDL file.
	// Used by rover supergraph compose. Either SchemaPath or SubgraphURL
	// must be non-empty for rover to compose the schema.
	SchemaPath string `yaml:"schema_path,omitempty" json:"schema_path,omitempty"`
	// Entities lists the Apollo Federation entity types this subgraph owns.
	// Each entry has a Type name and the Key field used for cross-subgraph
	// entity resolution.
	Entities []EntityKey `yaml:"entities,omitempty" json:"entities,omitempty"`
}

SubgraphConfig describes a single plugin's GraphQL subgraph registration, parsed from the graphql block in plugin.yaml.

type SubgraphEntry

type SubgraphEntry struct {
	// Name is the unique subgraph identifier in the supergraph schema.
	Name string
	// URL is the resolved HTTP endpoint.
	URL string
	// SchemaPath is the rover-usable schema path (may be empty).
	SchemaPath string
}

SubgraphEntry is the resolved form of a plugin subgraph — name, URL, and schema path are fully interpolated and validated. Used as input to compose.BuildSupergraphYAML.

func FromManifestBlocks

func FromManifestBlocks(blocks []ManifestGraphQLBlock, hasuraURL string) ([]SubgraphEntry, error)

FromManifestBlocks converts a slice of plugin manifest GraphQL blocks into a deduplicated, validated list of SubgraphEntry values ready for supergraph composition. Hasura is prepended as the first entry.

Rules:

  • Plugins with graphql.enabled == false are silently excluded.
  • Each enabled plugin must have a non-empty SubgraphName and SubgraphURL.
  • SubgraphName must match [a-z][a-z0-9_]* and must not be "hasura".
  • Duplicate SubgraphName values cause an error (fail-closed).
  • ${PORT} in SubgraphURL is substituted with the plugin's declared port.

hasuraURL is the Hasura GraphQL endpoint used as the first subgraph.

type SubgraphStatus

type SubgraphStatus struct {
	// Name is the subgraph name.
	Name string `json:"name"`
	// URL is the subgraph endpoint.
	URL string `json:"url"`
	// SchemaHash is the SHA-256 hex digest of the last composed schema.
	SchemaHash string `json:"schema_hash"`
	// LastComposed is the RFC 3339 timestamp of the last successful composition.
	LastComposed string `json:"last_composed"`
	// Status is one of "active", "inactive", "error".
	Status string `json:"status"`
}

SubgraphStatus is the runtime health record for a single subgraph, returned by StatusReport.

Jump to

Keyboard shortcuts

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