Skip to main content

Schema Design

Hugr apps organize their API using schemas which map to GraphQL modules (nested types).

Default Schema​

Functions and tables registered under the "default" schema appear at the app's top-level module — no extra nesting.

mux.HandleFunc("default", "add", handler, ...)
mux.Table("default", &ItemsTable{})
# Functions at: function → app_name → add
{ function { my_app { add(a: 1, b: 2) } } }

# Tables at: app_name → items
{ my_app { items { id name } } }

You can customize the default schema name via AppInfo.DefaultSchema:

func (a *MyApp) Info() app.AppInfo {
return app.AppInfo{
Name: "my_app",
DefaultSchema: "main", // "main" schema = top-level (instead of "default")
// ...
}
}

Named Schemas (Nested Modules)​

Any non-default schema creates a nested module:

mux.HandleFunc("admin", "user_count", handler, ...)
mux.HandleTableFunc("admin", "audit", handler, ...)
# Functions: function → app_name → schema_name → function_name
{ function { my_app { admin { user_count } } } }

# Table functions: app_name → schema_name → table_function_name
{ my_app { admin { admin_audit(args: { limit: 10 }) { id action } } } }

Naming Conventions​

App Name → GraphQL Module​

The app name becomes the top-level GraphQL module:

App NameModule Path
my_app{ my_app { ... } }
analytics{ analytics { ... } }

DS Name → Sub-Module​

Data source names use dot notation: appName.dsName:

DS RegistrationGraphQL Path
my_app.store{ my_app { store { ... } } }
my_app.logs{ my_app { logs { ... } } }

Table Functions in Named Schemas​

Table functions in named schemas get a prefixed name to avoid collisions:

SchemaNameGraphQL Field
defaultsearchsearch
adminauditadmin_audit
reportsdailyreports_daily

Reserved Names​

These names cannot be used as app names:

  • function — conflicts with Function root type
  • mutation_function — conflicts with MutationFunction root type
  • core — reserved for system functions
  • _system — reserved for internal use
  • Names starting with _ — reserved

Example: Multi-Schema App​

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

// Default schema — top-level
mux.HandleFunc("default", "version", versionHandler, app.Return(app.String))
mux.Table("default", &UsersTable{})

// Admin schema — nested module
mux.HandleFunc("admin", "stats", statsHandler, app.Return(app.Int64))
mux.HandleTableFunc("admin", "logs", logsHandler, ...)

// Reports schema — another nested module
mux.HandleTableFunc("reports", "daily", dailyHandler, ...)

return mux, nil
}

GraphQL schema:

# Functions
{ function { my_app { version } } }
{ function { my_app { admin { stats } } } }

# Tables and table functions
{ my_app { users { id name } } }
{ my_app { admin { admin_logs(args: {...}) { ... } } } }
{ my_app { reports { reports_daily(args: {...}) { ... } } } }