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

ingest

package
v0.1.4 Latest Latest
Warning

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

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

Documentation

Overview

Package ingest converts source API descriptions into the Forge IR. OpenAPI 3.0/3.1 is the primary format; GraphQL (introspection) is also supported.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func GRPC

func GRPC(data []byte) (*ir.API, error)

GRPC ingests a compiled protobuf FileDescriptorSet into the Forge IR.

The input bytes are the binary FileDescriptorSet produced by either

protoc --descriptor_set_out=set.pb --include_imports *.proto
buf build -o set.pb

Each UNARY service method becomes one ir.Operation modeled as a unary POST to the gRPC HTTP/2 path "/<fully-qualified-service>/<Method>" (the wire path gRPC uses), so generators can describe and document the surface uniformly with REST sources. gRPC has no REST base URL, so the single server URL is empty.

SERVER-STREAMING methods are emitted into api.Streams (not Operations): design 015 maps them to background streaming sessions with ring-buffer capture. At runtime a session opens the HTTP request against a grpc-gateway-style JSON bridge and consumes its newline-delimited {"result":…}/{"error":…} frames; the model polls the session for new frames and stops it when done. Keeping them out of Operations keeps every unary generator (SDKs, docs, static tools) honest — a one-shot wrapper for a streaming method would hang or truncate at call time. Connect's enveloped streaming framing is NOT supported — only NDJSON (grpc-gateway style).

CLIENT-STREAMING and BIDI methods remain excluded (API.Skipped, by kind): they need the model to produce a request stream over a full-duplex connection, which cannot ride a JSON-over-HTTP bridge sanely. The exclusion is reported at add time, never silent.

Field-type mapping (proto → JSON-schema): see protoFieldSchema. The read-vs-write (mutating) heuristic and recursion handling are documented on readMethodPrefixes and buildMessageSchema respectively.

func GRPCReflect

func GRPCReflect(ctx context.Context, target string, opts GRPCReflectOptions) ([]byte, error)

GRPCReflect connects to a RUNNING gRPC server at target ("host:port"), uses the server reflection protocol to discover its services, and returns the wire bytes of a FileDescriptorSet containing every file needed to describe them — the exact input the file-based GRPC ingester consumes, so callers store it and flow it through the existing pipeline unchanged.

The v1 reflection service is tried first, falling back to v1alpha when the server predates v1 (still common outside grpc-go).

func GraphQL

func GraphQL(data []byte) (*ir.API, error)

GraphQL converts a GraphQL introspection result (the JSON returned by the standard __schema introspection query, with or without the {"data":…} envelope) into the IR. Query fields become non-mutating operations and Mutation fields become mutating operations, each POSTed to the GraphQL endpoint with its arguments modeled as the request body.

Live execution is wired through the generic graphql_schema / graphql_query tools (toolpack.RegisterGraphQL + runtime.GraphQLExecutor): the agent composes a document and the executor POSTs {query, variables} to the endpoint.

Subscription fields are push streams delivered over graphql-ws, which a single request/response POST tool cannot honestly serve — so they are recorded in API.Streams and exposed at runtime as background streaming sessions (graphql_subscribe starts a graphql-transport-ws subscription whose "next" frames land in a bounded ring buffer; the model polls and stops the session). Keeping them out of Operations keeps unary generators honest.

func GraphQLIntrospect

func GraphQLIntrospect(ctx context.Context, endpoint string, headers http.Header, timeout time.Duration) ([]byte, error)

GraphQLIntrospect fetches the schema of a RUNNING GraphQL endpoint by POSTing the standard introspection query and returns the raw response body — the same introspection JSON the file-based GraphQL ingester consumes — so callers store it and flow it through the existing pipeline unchanged.

headers are set after the defaults, so a caller-supplied Content-Type or Accept wins. timeout <= 0 falls back to 30s: an unbounded hang inside `forge add` would look like a wedged CLI.

func LooksLikeDescriptorSet

func LooksLikeDescriptorSet(data []byte) bool

LooksLikeDescriptorSet reports whether data is plausibly a compiled protobuf FileDescriptorSet, for source auto-detection when the filename gives no hint.

Deliberately conservative. proto.Unmarshal is lenient — it will happily consume many byte strings, including some JSON — so a bare "did it parse?" test would misclassify OpenAPI and GraphQL specs as gRPC. Three gates:

  1. Reject valid UTF-8 text outright. Every OpenAPI/GraphQL spec rysh accepts is text; a real descriptor set contains length-prefixed binary fields and is vanishingly unlikely to be valid UTF-8 in full.
  2. Require the payload to parse as a FileDescriptorSet with at least one file.
  3. Require that file to carry a name, which every protoc/buf output does. Random bytes that happen to parse will not satisfy this.

False negatives are cheap — the user passes --source grpc. A false positive would send an OpenAPI spec down the gRPC path, so the bias is intentional.

func OpenAPI

func OpenAPI(data []byte) (*ir.API, error)

OpenAPI parses an OpenAPI 3.0/3.1 document (JSON or YAML) into the IR.

Types

type GRPCReflectOptions

type GRPCReflectOptions struct {
	// TLS dials with TLS using the system roots; the default is plaintext
	// (h2c), which is what local/dev gRPC servers speak.
	TLS bool
	// Metadata is sent as call metadata on the reflection stream (e.g.
	// authorization tokens for reflection-gated servers).
	Metadata map[string]string
}

GRPCReflectOptions configures a live reflection fetch.

Jump to

Keyboard shortcuts

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