app

package
v0.3.31 Latest Latest
Warning

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

Go to latest
Published: Apr 19, 2026 License: MIT Imports: 17 Imported by: 0

README

hugr-app SDK (client/app)

Build pluggable applications for the Hugr data mesh platform. Apps connect via DuckDB Airport extension and publish functions, tables, and views into hugr's shared GraphQL schema.

Quick Start

package main

import (
    "context"
    "net"
    "os/signal"
    "syscall"

    "github.com/hugr-lab/airport-go/catalog"
    "github.com/hugr-lab/query-engine/client"
    "github.com/hugr-lab/query-engine/client/app"
)

type MyApp struct{}

func (a *MyApp) Info() app.AppInfo {
    return app.AppInfo{
        Name:    "my_app",
        Version: "1.0.0",
        URI:     "grpc://localhost:50051",
    }
}

func (a *MyApp) Listner() (net.Listener, error) {
    return net.Listen("tcp", "localhost:50051")
}

func (a *MyApp) Init(ctx context.Context) error    { return nil }
func (a *MyApp) Shutdown(ctx context.Context) error { return nil }

func (a *MyApp) Catalog(ctx context.Context) (catalog.Catalog, error) {
    mux := app.New()

    // Register a scalar function
    mux.HandleFunc("default", "add", func(w *app.Result, r *app.Request) error {
        return w.Set(r.Int64("a") + r.Int64("b"))
    }, app.Arg("a", app.Int64), app.Arg("b", app.Int64), app.Return(app.Int64))

    // Register a table function
    mux.HandleTableFunc("default", "search", func(w *app.Result, r *app.Request) error {
        w.Append(int64(1), "Alice")
        w.Append(int64(2), "Bob")
        return nil
    }, app.Arg("query", app.String), app.ColPK("id", app.Int64), app.Col("name", app.String))

    return mux, nil
}

func main() {
    ctx, cancel := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
    defer cancel()

    c := client.NewClient("http://localhost:15100/ipc")
    c.RunApplication(ctx, &MyApp{}, client.WithSecretKey("my-secret"))
}

After connecting, your app is queryable:

{ function { my_app { add(a: 1, b: 2) } } }
# → {"data": {"function": {"my_app": {"add": 3}}}}

{ my_app { search(query: "test") { id name } } }
# → {"data": {"my_app": {"search": [{"id": 1, "name": "Alice"}, ...]}}}

CatalogMux API

Method Description
HandleFunc(schema, name, handler, opts...) Register scalar function
HandleTableFunc(schema, name, handler, opts...) Register table function
Table(schema, table, opts...) Register catalog.Table
TableRef(schema, ref, opts...) Register catalog.TableRef
ScalarFunc(schema, fn) Register catalog.ScalarFunction directly
TableFunc(schema, fn) Register catalog.TableFunction directly
TableFuncInOut(schema, fn) Register catalog.TableFunctionInOut directly
WithSDL(sdl) Override all auto-generated SDL with custom SDL

Per-item SDL wrapping: app.WithSDL(table, sdl), app.WithScalarFuncSDL(fn, sdl), app.WithTableFuncSDL(fn, sdl), app.WithTableRefSDL(ref, sdl)

Struct Return and Input Types

For functions that return or accept structured data, use the Struct / InputStruct builders. The wire format is JSON; the planner inlines complex argument values automatically and casts JSON returns to typed GraphQL structures via @function(json_cast: true).

// Output struct with @field_source rename and a list field
weather := app.Struct("weather_result").
    Desc("Current weather snapshot").
    Field("temp", app.Float64).
    Field("humidity", app.Int64).
    FieldFromSource("city", app.String, "city_name").
    FieldList("conditions", app.String) // [String!]!

// Input struct
location := app.InputStruct("location_input").
    Field("lat", app.Float64).
    Field("lon", app.Float64)

mux.HandleFunc("default", "get_weather",
    func(w *app.Result, r *app.Request) error {
        var loc struct{ Lat, Lon float64 }
        if err := r.JSON("location", &loc); err != nil {
            return err
        }
        return w.SetJSON(map[string]any{
            "temp":       22.5,
            "humidity":   60,
            "city_name":  "Berlin",
            "conditions": []string{"sunny", "windy"},
        })
    },
    app.Arg("location", location.AsType()),
    app.Return(weather.AsType()),
)

Generated SDL:

input location_input {
    lat: Float!
    lon: Float!
}

"""Current weather snapshot"""
type weather_result {
    temp: Float!
    humidity: BigInt!
    city: String! @field_source(field: "city_name")
    conditions: [String!]!
}

extend type Function {
    get_weather(location: location_input!): weather_result
        @function(name: "...", json_cast: true)
}

Helpers:

  • Result.SetJSON(v) — marshals v to JSON and stores as the return value. Runtime check ensures the function's return type accepts JSON.
  • Result.SetJSONValue(v) — accepts string, []byte, or any value (marshaled). Most flexible variant.
  • Request.JSON(name, &out) — unmarshals the named arg's JSON string value into out.

Raw JSON without struct definition: app.Return(app.JSON) for opaque JSON returns; app.Arg(name, app.JSON) for opaque JSON inputs.

Lists of scalars: app.ReturnList(app.String) for [String!]-style returns. Uses native Arrow LIST as the wire format (not JSON), so the handler returns a Go slice via Set: []string, []int64, []float64, []bool, and other scalar slice types are supported ([]any works as a fallback). The outer list is nullable, matching the scalar-return convention — elements are non-null.

Lists of structs are NOT supported as scalar function returns — use HandleTableFunc instead.

Type deduplication: the same StructType (by name) used in multiple functions is emitted once in SDL. Conflicting registrations (same name, different fields) fail at registration time.

Thread safety: HandleFunc / HandleTableFunc (and the other registration methods) are not safe to call concurrently on the same CatalogMux. Build the catalog from a single goroutine (typically inside Application.Catalog), then publish it — after the catalog is handed to the runtime, all reads are safe for any number of goroutines.

Options

Function options: Arg(name, type), ArgDesc(name, type, desc), ArgFromContext(name, type, placeholder), Return(type), ReturnList(type), Desc(description), Mutation()

ArgFromContext() declares a server-injected function argument bound to a context placeholder. The argument is hidden from the GraphQL schema — clients cannot see or set it. At handler execution time, read it via r.String(name) / r.Int64(name) like any other argument.

mux.HandleFunc("default", "my_orders",
    func(w *app.Result, r *app.Request) error {
        userID := r.String("user_id") // injected from auth context
        limit := r.Int64("limit")
        // ... fetch orders for userID ...
        return w.Set("ok")
    },
    app.Arg("limit", app.Int64),
    app.ArgFromContext("user_id", app.String, app.AuthUserID),
    app.Return(app.String),
)

// GraphQL: { function { my_app { my_orders(limit: 10) } } }
// Note: user_id is NOT in the schema — server-injected.

Available placeholders (typed app.ContextPlaceholder constants):

Constant Resolves to
app.AuthUserID Authenticated user ID (string)
app.AuthUserIDInt Authenticated user ID parsed as integer
app.AuthUserName Authenticated user display name
app.AuthRole Authenticated role
app.AuthType Auth method (apiKey, jwt, oidc, etc.)
app.AuthProvider Auth provider name
app.AuthImpersonatedByRole Original role when impersonating
app.AuthImpersonatedByUserID Original user ID when impersonating
app.AuthImpersonatedByUserName Original user name when impersonating
app.Catalog Current catalog name

Mutation() marks a scalar function as a GraphQL mutation. Without it, the function is exposed as a query (extends Function); with it, the function extends MutationFunction and must be called via mutation { ... }. Use it for operations with side effects.

mux.HandleFunc("default", "send_email",
    func(w *app.Result, r *app.Request) error {
        return w.Set(fmt.Sprintf("sent to %s", r.String("to")))
    },
    app.Arg("to", app.String),
    app.Arg("body", app.String),
    app.Return(app.String),
    app.Mutation(),
)

// GraphQL: mutation { function { my_app { send_email(to: "alice", body: "hi") } } }

Table column options: Col(name, type), ColPK(name, type), ColDesc(name, type, desc), ColNullable(name, type)

Schema options: WithPK(fields...), WithDescription(desc), WithReferences(...), WithFieldReferences(...), WithM2M(), WithFilterRequired(fields...)

Types

Boolean, Int8, Int16, Int32, Int64, Uint8...Uint64, Float32, Float64, String, Binary, Timestamp, Date, Geometry

Schemas

  • "default" schema → objects at app's root module level
  • Named schemas → nested modules (e.g., schema "reports"{ my_app { reports { ... } } })
  • "_mount" — reserved for system metadata

Application Interfaces

Interface Required Description
Application Yes Info, Catalog, Init, Shutdown, Listener
DataSourceUser No Declare database dependencies
ApplicationDBInitializer No Provide SQL for schema initialization
ApplicationDBMigrator No Provide SQL for versioned migrations
MultiCatalogProvider No Dynamic catalog registration at runtime
TLSConfigProvider No TLS configuration for gRPC

Documentation

Full documentation: hugr-lab.github.io/docs/hugr-apps

Examples: examples/hugr-app/

Documentation

Index

Constants

View Source
const DefaultSchema = "default"

DefaultSchema is the fixed schema name treated as root level (no @module directive). All other schema names become nested modules.

Variables

View Source
var (
	Boolean   = Type{/* contains filtered or unexported fields */}
	Int8      = Type{/* contains filtered or unexported fields */}
	Int16     = Type{/* contains filtered or unexported fields */}
	Int32     = Type{/* contains filtered or unexported fields */}
	Int64     = Type{/* contains filtered or unexported fields */}
	Uint8     = Type{/* contains filtered or unexported fields */}
	Uint16    = Type{/* contains filtered or unexported fields */}
	Uint32    = Type{/* contains filtered or unexported fields */}
	Uint64    = Type{/* contains filtered or unexported fields */}
	Float32   = Type{/* contains filtered or unexported fields */}
	Float64   = Type{/* contains filtered or unexported fields */}
	String    = Type{/* contains filtered or unexported fields */}
	Binary    = Type{/* contains filtered or unexported fields */}
	Timestamp = Type{/* contains filtered or unexported fields */}
	Date      = Type{/* contains filtered or unexported fields */}
	Geometry  = Type{/* contains filtered or unexported fields */}

	// JSON is the raw JSON scalar type. The wire representation is a string;
	// the handler is responsible for json.Marshal / json.Unmarshal of complex
	// values. In the public GraphQL schema this is the JSON scalar — clients
	// receive the raw JSON value.
	JSON = Type{/* contains filtered or unexported fields */}
)

Arrow type references — use these in Arg(), Return(), Col() options.

View Source
var ReservedSchemas = map[string]bool{
	"_mount": true,
	"_funcs": true,
}

ReservedSchemas that cannot be used by app developers.

Functions

func GenerateTableRefSDL

func GenerateTableRefSDL(schemaName string, ref catalog.TableRef, opts ...SchemaOption) string

GenerateTableRefSDL generates SDL for a catalog.TableRef from its Arrow schema. Table refs are always @view (read-only). If WithRawSDL is provided, returns that SDL directly.

func GenerateTableSDL

func GenerateTableSDL(schemaName string, table catalog.Table, opts ...SchemaOption) string

GenerateTableSDL generates SDL for a catalog.Table from its Arrow schema. Mutable tables get @table, read-only tables get @view. If WithRawSDL is provided, returns that SDL directly.

func IsKnownArgPlaceholder added in v0.3.24

func IsKnownArgPlaceholder(p ContextPlaceholder) bool

IsKnownArgPlaceholder reports whether the given context placeholder is in the recognized whitelist for app.ArgFromContext.

func ToGraphQLName

func ToGraphQLName(name string) string

ToGraphQLName transforms a string into a valid GraphQL identifier. Replaces invalid characters with underscores, prepends _ if starts with digit.

func ValidGraphQLName

func ValidGraphQLName(name string) bool

ValidGraphQLName returns true if name is a valid GraphQL identifier.

func WithSDL

func WithSDL(table catalog.Table, sdl string) catalog.Table

WithSDL wraps a catalog.Table with its hugr SDL definition.

func WithScalarFuncSDL

func WithScalarFuncSDL(fn catalog.ScalarFunction, sdl string) catalog.ScalarFunction

WithScalarFuncSDL wraps a catalog.ScalarFunction with its hugr SDL definition.

func WithTableFuncInOutSDL

func WithTableFuncInOutSDL(fn catalog.TableFunctionInOut, sdl string) catalog.TableFunctionInOut

WithTableFuncInOutSDL wraps a catalog.TableFunctionInOut with its hugr SDL definition.

func WithTableFuncSDL

func WithTableFuncSDL(fn catalog.TableFunction, sdl string) catalog.TableFunction

WithTableFuncSDL wraps a catalog.TableFunction with its hugr SDL definition.

func WithTableRefSDL

func WithTableRefSDL(ref catalog.TableRef, sdl string) catalog.TableRef

WithTableRefSDL wraps a catalog.TableRef with its hugr SDL definition.

Types

type AppInfo

type AppInfo struct {
	Name        string `json:"name"`
	Description string `json:"description"`
	Version     string `json:"version"`
	URI         string `json:"uri"`
}

type Application

type Application interface {
	Listner() (net.Listener, error)
	Info() AppInfo
	Catalog(ctx context.Context) (catalog.Catalog, error)

	// Init is called during server startup to perform any necessary initialization.
	// This performs after registering the application data sources on the hugr side.
	// This will be called by the Hugr server
	Init(ctx context.Context) error

	// Shutdown is called during graceful shutdown to clean up resources.
	// Called before unregistering from hugr.
	Shutdown(ctx context.Context) error
}

type ApplicationDBInitializer

type ApplicationDBInitializer interface {
	InitDBSchemaTemplate(ctx context.Context, name string) (string, error)
}

type ApplicationDBMigrator

type ApplicationDBMigrator interface {
	ApplicationDBInitializer
	MigrateDBSchemaTemplate(ctx context.Context, name, version string) (string, error)
}

type CatalogMux

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

CatalogMux is a goroutine-safe catalog multiplexer. Like http.ServeMux routes URLs to handlers, CatalogMux routes schema+name pairs to functions, tables, and table references.

The catalog is static once built — SDL does not change at runtime. For dynamic multi-catalog scenarios, see MultiCatalogProvider in client/apps.

Thread safety: read methods (Schemas, Schema, SDL) and the direct registration methods (ScalarFunc, TableFunc, Table, TableRef, ...) are safe for concurrent use. The higher-level registration helpers HandleFunc and HandleTableFunc additionally update the shared struct-type registry and are **not** goroutine-safe among themselves: build the catalog from a single goroutine (typically Application.Catalog), then publish it. After the catalog is handed to the runtime, all subsequent reads are safe for any number of goroutines.

func New

func New() *CatalogMux

New creates a new empty CatalogMux.

func (*CatalogMux) HandleFunc

func (m *CatalogMux) HandleFunc(schema, name string, handler HandlerFunc, opts ...Option) error

HandleFunc registers a Go function as a scalar function. The handler is called once per row with typed arguments via Request. Options declare arguments and return type: Arg(), Return().

mux.HandleFunc("math", "add", func(w *app.Result, r *app.Request) error {
    return w.Set(r.Int64("a") + r.Int64("b"))
}, app.Arg("a", app.Int64), app.Arg("b", app.Int64), app.Return(app.Int64))

func (*CatalogMux) HandleTableFunc

func (m *CatalogMux) HandleTableFunc(schema, name string, handler HandlerFunc, opts ...Option) error

HandleTableFunc registers a Go function as a table function. The handler is called once and writes rows via Result.Append(). Options declare arguments and result columns: Arg(), Col(), ColPK(), ColNullable().

mux.HandleTableFunc("users", "search", func(w *app.Result, r *app.Request) error {
    w.Append(int64(1), "Alice")
    return nil
}, app.Arg("query", app.String), app.ColPK("id", app.Int64), app.Col("name", app.String))

func (*CatalogMux) SDL

func (m *CatalogMux) SDL() string

SDL returns the full GraphQL SDL for the catalog. If WithSDL was called, returns that string. Otherwise collects SDL from all registered items across non-system schemas. Objects from the default schema have no @module directive; objects from named schemas get @module(name) injected per-definition during SDL generation (see schemaModuleName in sdl_gen.go). System schemas (_mount, _funcs) are excluded.

func (*CatalogMux) ScalarFunc

func (m *CatalogMux) ScalarFunc(schema string, fn catalog.ScalarFunction)

ScalarFunc registers a catalog.ScalarFunction directly.

func (*CatalogMux) Schema

func (m *CatalogMux) Schema(ctx context.Context, name string) (catalog.Schema, error)

func (*CatalogMux) Schemas

func (m *CatalogMux) Schemas(ctx context.Context) ([]catalog.Schema, error)

func (*CatalogMux) Table

func (m *CatalogMux) Table(schema string, table catalog.Table, opts ...SchemaOption)

Table registers a catalog.Table directly. If the table doesn't have SDL attached (via WithSDL), SDL is auto-generated from the Arrow schema. Mutable tables → @table, read-only → @view. SchemaOptions configure PK, references, field_references, etc.

func (*CatalogMux) TableFunc

func (m *CatalogMux) TableFunc(schema string, fn catalog.TableFunction)

TableFunc registers a catalog.TableFunction directly.

func (*CatalogMux) TableFuncInOut

func (m *CatalogMux) TableFuncInOut(schema string, fn catalog.TableFunctionInOut)

TableFuncInOut registers a catalog.TableFunctionInOut directly.

func (*CatalogMux) TableRef

func (m *CatalogMux) TableRef(schema string, ref catalog.TableRef, opts ...SchemaOption)

TableRef registers a catalog.TableRef in the given schema. If the ref doesn't have SDL attached (via WithTableRefSDL), SDL is auto-generated from the Arrow schema as a @view. SchemaOptions configure PK, references, field_references, etc.

func (*CatalogMux) WithSDL

func (m *CatalogMux) WithSDL(sdl string)

WithSDL sets a raw SDL string that overrides all auto-generated SDL. When set, SDL() returns this string instead of collecting from registered items.

type ContextPlaceholder added in v0.3.24

type ContextPlaceholder string

ContextPlaceholder is a typed wrapper for server-side context placeholders used with app.ArgFromContext. Use the predefined constants below — passing a string that isn't in the recognized whitelist will fail at registration.

const (
	// AuthUserID — current user's ID as a string.
	AuthUserID ContextPlaceholder = "[$auth.user_id]"
	// AuthUserIDInt — current user's ID parsed as integer.
	AuthUserIDInt ContextPlaceholder = "[$auth.user_id_int]"
	// AuthUserName — current user's display name.
	AuthUserName ContextPlaceholder = "[$auth.user_name]"
	// AuthRole — current authenticated role.
	AuthRole ContextPlaceholder = "[$auth.role]"
	// AuthType — auth method (e.g. "apiKey", "jwt", "oidc", "impersonation").
	AuthType ContextPlaceholder = "[$auth.auth_type]"
	// AuthProvider — auth provider name.
	AuthProvider ContextPlaceholder = "[$auth.provider]"
	// AuthImpersonatedByRole — original role when impersonating.
	AuthImpersonatedByRole ContextPlaceholder = "[$auth.impersonated_by_role]"
	// AuthImpersonatedByUserID — original user ID when impersonating.
	AuthImpersonatedByUserID ContextPlaceholder = "[$auth.impersonated_by_user_id]"
	// AuthImpersonatedByUserName — original user name when impersonating.
	AuthImpersonatedByUserName ContextPlaceholder = "[$auth.impersonated_by_user_name]"
)

Recognized context placeholders. The hugr planner resolves these via perm.AuthVars(ctx) at request time. When the underlying value is unavailable (e.g. unauthenticated request), the planner substitutes NULL.

This list mirrors pkg/catalog/sdl/placeholders.go on the server side; keep them in sync.

type DataSourceInfo

type DataSourceInfo struct {
	Name        string `json:"name"`
	Type        string `json:"type"`
	Description string `json:"description"`
	ReadOnly    bool   `json:"read_only"`
	Path        string `json:"path"`
	Version     string `json:"version"`
	HugrSchema  string `json:"hugr_schema"`
}

type DataSourceUser

type DataSourceUser interface {
	Application
	DataSources(ctx context.Context) ([]DataSourceInfo, error)
}

type HandlerFunc

type HandlerFunc func(w *Result, r *Request) error

HandlerFunc is the function signature for scalar and table function handlers.

type MultiCatalogMux

type MultiCatalogMux interface {
	AddCatalog(cat catalog.Catalog) error
	RemoveCatalog(name string) error
	IsExists(name string) bool
}

type MultiCatalogProvider

type MultiCatalogProvider interface {
	SetMultiCatalogMux(mux MultiCatalogMux)
	InitMultiCatalog(ctx context.Context) error
}

type Option

type Option func(*funcDef)

Option configures function registration.

func Arg

func Arg(name string, typ Type) Option

Arg declares a function argument.

func ArgDesc

func ArgDesc(name string, typ Type, description string) Option

ArgDesc declares a function argument with a description.

func ArgFromContext added in v0.3.24

func ArgFromContext(name string, typ Type, placeholder ContextPlaceholder) Option

ArgFromContext declares a function argument whose value is server-injected from a context placeholder. The argument is hidden from the GraphQL schema — clients cannot pass a value for it. At handler execution time, read it via Request.String(name), Request.Int64(name), etc., the same as a regular argument.

Use the predefined ContextPlaceholder constants (AuthUserID, AuthRole, etc.). Passing an unknown placeholder fails at registration time.

Example:

mux.HandleFunc("default", "my_orders", handler,
    app.Arg("limit", app.Int64),
    app.ArgFromContext("user_id", app.String, app.AuthUserID),
    app.Return(app.String),
)

func Col

func Col(name string, typ Type) Option

Col declares a result column for a table function.

func ColDesc

func ColDesc(name string, typ Type, description string) Option

ColDesc declares a result column with a description.

func ColNullable

func ColNullable(name string, typ Type) Option

ColNullable declares a nullable result column for a table function.

func ColPK

func ColPK(name string, typ Type) Option

ColPK declares a primary key result column for a table function.

func Desc

func Desc(description string) Option

Desc sets the function description.

func Mutation added in v0.3.23

func Mutation() Option

Mutation marks a scalar function as a mutation. The generated SDL will extend MutationFunction instead of Function, exposing the function as a GraphQL mutation operation rather than a query.

func Return

func Return(typ Type) Option

Return declares the scalar function return type.

func ReturnList added in v0.3.24

func ReturnList(typ Type) Option

ReturnList declares that the scalar function returns a list of the given scalar element type (e.g. ReturnList(app.String) → [String!]).

The wire format is a native Arrow LIST of the element's underlying type (NOT JSON), so DuckDB receives a proper LIST value and the planner does not need json_cast. The handler returns a Go slice via Set.

ReturnList does NOT support struct element types — for lists of structs, register the function as a table function via HandleTableFunc instead. Passing a struct type sets a registration error that fails registration.

The generated SDL preserves the scalar-return convention (outer-nullable, element-non-null): `[String!]`.

type Request

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

Request provides typed access to function arguments.

func (*Request) Bool

func (r *Request) Bool(name string) bool

func (*Request) Bytes

func (r *Request) Bytes(name string) []byte

func (*Request) Context

func (r *Request) Context() context.Context

Context returns the request context.

func (*Request) Float32

func (r *Request) Float32(name string) float32

func (*Request) Float64

func (r *Request) Float64(name string) float64

func (*Request) Geometry

func (r *Request) Geometry(name string) orb.Geometry

func (*Request) Get

func (r *Request) Get(name string) any

func (*Request) Int8

func (r *Request) Int8(name string) int8

func (*Request) Int16

func (r *Request) Int16(name string) int16

func (*Request) Int32

func (r *Request) Int32(name string) int32

func (*Request) Int64

func (r *Request) Int64(name string) int64

func (*Request) JSON added in v0.3.24

func (r *Request) JSON(name string, out any) error

JSON unmarshals the named argument's JSON string value into out. Use this for arguments declared with Arg(name, JSON) or Arg(name, struct.AsType()), where the planner inlines the GraphQL input value as a JSON literal that arrives at the handler as a string.

Returns nil (no-op) if the argument is empty.

func (*Request) String

func (r *Request) String(name string) string

func (*Request) Uint8

func (r *Request) Uint8(name string) uint8

func (*Request) Uint16

func (r *Request) Uint16(name string) uint16

func (*Request) Uint32

func (r *Request) Uint32(name string) uint32

func (*Request) Uint64

func (r *Request) Uint64(name string) uint64

type Result

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

Result writes function output. For scalar functions, use Set() to write the return value. For table functions, use Append() to write rows.

func (*Result) Append

func (w *Result) Append(values ...any) error

Append writes a row to a table function result. Values must match the column order from Col() options.

func (*Result) Set

func (w *Result) Set(v any) error

Set writes a scalar function return value.

func (*Result) SetJSON added in v0.3.24

func (w *Result) SetJSON(v any) error

SetJSON marshals the value to a JSON string and stores it as the scalar return. Use this when the function's Return type is JSON or a struct (via Struct().AsType()).

Returns an error if the function's return type is not JSON-compatible (including when called on a table function).

func (*Result) SetJSONValue added in v0.3.24

func (w *Result) SetJSONValue(v any) error

SetJSONValue is the most flexible JSON setter. It accepts:

  • string: stored as-is (assumed valid JSON)
  • []byte: stored as string(b) (assumed valid JSON)
  • any other value: marshaled via json.Marshal

Returns an error if the function's return type is not JSON-compatible (including when called on a table function).

type SchemaOption

type SchemaOption func(*schemaDef)

SchemaOption configures SDL generation for tables, table functions, and table refs.

func WithDescription

func WithDescription(desc string) SchemaOption

WithDescription sets the description for the table/view/function type.

func WithFieldDescription

func WithFieldDescription(field, desc string) SchemaOption

WithFieldDescription sets the description for a specific field.

func WithFieldReferences

func WithFieldReferences(fieldName, referencesName, query, referencesQuery string) SchemaOption

WithFieldReferences adds a field-level @field_references directive.

func WithFilterRequired

func WithFilterRequired(fields ...string) SchemaOption

WithFilterRequired marks fields as requiring a filter when queried.

func WithM2M

func WithM2M() SchemaOption

WithM2M marks the table as a many-to-many junction table.

func WithM2MReferences

func WithM2MReferences(referencesName string, sourceFields, referencesFields []string, query, referencesQuery, m2mName string) SchemaOption

WithM2MReferences adds an object-level @references directive with is_m2m flag.

func WithPK

func WithPK(fields ...string) SchemaOption

WithPK marks fields as primary key. Multiple calls or multiple names for composite PK.

func WithRawSDL

func WithRawSDL(sdl string) SchemaOption

WithRawSDL provides user-written SDL directly, skipping auto-generation.

func WithReferences

func WithReferences(referencesName string, sourceFields, referencesFields []string, query, referencesQuery string) SchemaOption

WithReferences adds an object-level @references directive.

type StructKind added in v0.3.24

type StructKind int

StructKind selects whether the struct is used as an output type (GraphQL OBJECT) or as an input type (GraphQL INPUT_OBJECT).

const (
	// StructKindOutput produces a GraphQL Object type used as a function return.
	StructKindOutput StructKind = iota
	// StructKindInput produces a GraphQL InputObject type used as a function argument.
	StructKindInput
)

type StructType added in v0.3.24

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

StructType describes a custom GraphQL struct type generated by the SDK SDL builder. Use Struct or InputStruct to start a builder, add fields, then call AsType to convert it into a Type usable with Return / Arg.

The wire representation is a JSON string. The hugr planner inlines complex argument values automatically; for return values the SDL emits @function (json_cast: true) so the planner casts the JSON output to the structured type before returning to the client.

func InputStruct added in v0.3.24

func InputStruct(name string) *StructType

InputStruct begins building an input struct (GraphQL InputObject type).

func Struct added in v0.3.24

func Struct(name string) *StructType

Struct begins building an output struct (GraphQL Object type). The returned builder is mutable; chain Field/Desc/etc. and finish with AsType.

func (*StructType) AsType added in v0.3.24

func (s *StructType) AsType() Type

AsType converts the struct definition into a Type usable with Return / Arg. The wire dt is arrow.BinaryTypes.String (JSON wire format); the GraphQL type name is the struct's name. The structDef back-pointer enables the SDL generator to emit the type definition alongside the function field.

func (*StructType) Desc added in v0.3.24

func (s *StructType) Desc(description string) *StructType

Desc sets the GraphQL doc description for the type.

func (*StructType) Field added in v0.3.24

func (s *StructType) Field(name string, typ Type) *StructType

Field adds a non-null field of the given type. The type may be a scalar (e.g. app.String, app.Int64) or another struct via its AsType() method (the JSON wire format handles nesting).

func (*StructType) FieldDesc added in v0.3.24

func (s *StructType) FieldDesc(name string, typ Type, description string) *StructType

FieldDesc adds a non-null field with a description.

func (*StructType) FieldFromSource added in v0.3.24

func (s *StructType) FieldFromSource(name string, typ Type, originalName string) *StructType

FieldFromSource adds a non-null field whose underlying JSON key differs from the GraphQL name. The generated SDL emits a @field_source(field: "<originalName>") directive so the planner extracts the value from the underlying JSON correctly.

Only valid on output structs. Panics if called on an input struct (caught at builder time as a programmer error).

func (*StructType) FieldList added in v0.3.24

func (s *StructType) FieldList(name string, typ Type) *StructType

FieldList adds a non-null list field ([Type!]!). The element type may be any scalar or struct — JSON serialization handles nested arrays naturally.

func (*StructType) FieldNullable added in v0.3.24

func (s *StructType) FieldNullable(name string, typ Type) *StructType

FieldNullable adds a nullable field of the given type.

type TLSConfigProvider

type TLSConfigProvider interface {
	TLSConfig(ctx context.Context) (*tls.Config, error)
}

type Type

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

Type wraps an arrow.DataType with a GraphQL type name for SDL generation. When structDef is non-nil, the type represents a custom struct that the SDL generator emits as a separate type definition; the wire representation is a JSON string (arrow.BinaryTypes.String).

Jump to

Keyboard shortcuts

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