app

package
v0.3.15 Latest Latest
Warning

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

Go to latest
Published: Apr 3, 2026 License: MIT Imports: 16 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)

Options

Function options: Arg(name, type), ArgDesc(name, type, desc), Return(type), Desc(description)

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"

DefaultSchemaName is the schema name treated as root level (no @module directive).

Variables

View Source
var (
	Boolean   = Type{arrow.FixedWidthTypes.Boolean, "Boolean"}
	Int8      = Type{arrow.PrimitiveTypes.Int8, "Int"}
	Int16     = Type{arrow.PrimitiveTypes.Int16, "Int"}
	Int32     = Type{arrow.PrimitiveTypes.Int32, "Int"}
	Int64     = Type{arrow.PrimitiveTypes.Int64, "BigInt"}
	Uint8     = Type{arrow.PrimitiveTypes.Uint8, "UInt"}
	Uint16    = Type{arrow.PrimitiveTypes.Uint16, "UInt"}
	Uint32    = Type{arrow.PrimitiveTypes.Uint32, "UInt"}
	Uint64    = Type{arrow.PrimitiveTypes.Uint64, "BigUInt"}
	Float32   = Type{arrow.PrimitiveTypes.Float32, "Float"}
	Float64   = Type{arrow.PrimitiveTypes.Float64, "Float"}
	String    = Type{arrow.BinaryTypes.String, "String"}
	Binary    = Type{arrow.BinaryTypes.Binary, "Base64"}
	Timestamp = Type{arrow.FixedWidthTypes.Timestamp_us, "DateTime"}
	Date      = Type{arrow.FixedWidthTypes.Date32, "Date"}
	Geometry  = Type{catalog.NewGeometryExtensionType(), "Geometry"}
)

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 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"`
	DefaultSchema string `json:"default_schema,omitempty"` // default: "default"
}

func (AppInfo) DefaultSchemaName

func (i AppInfo) DefaultSchemaName() string

DefaultSchemaName returns the schema name treated as root (no @module).

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.

All methods are safe for concurrent use from multiple 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.

func (*CatalogMux) SDLWithModules

func (m *CatalogMux) SDLWithModules(defaultSchema string) string

SDLWithModules returns the full GraphQL SDL with module directives. Objects from defaultSchema have no @module. Other schemas get @module(name: schemaName). 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 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 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 Return

func Return(typ Type) Option

Return declares the scalar function return type.

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) 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.

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 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.

Jump to

Keyboard shortcuts

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