graphql

package
v1.9.0 Latest Latest
Warning

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

Go to latest
Published: Jun 8, 2026 License: Apache-2.0 Imports: 9 Imported by: 0

README

GraphQL Integration

This package provides dynamic GraphQL schema generation for operator catalog data, integrated into the catalogd storage server.

⚠️ Alpha Feature: This is an experimental feature controlled by the GraphQLCatalogQueries feature gate. See user documentation at docs/draft/howto/catalog-queries-graphql-endpoint.md.

Usage

The GraphQL endpoint is now available as part of the catalogd storage server at:

/catalogs/{catalog}/api/v1/graphql

Where {catalog} is replaced by the actual catalog name at runtime.

Example Usage

Making a GraphQL Request
curl -X POST http://localhost:8080/catalogs/my-catalog/api/v1/graphql \
  -H "Content-Type: application/json" \
  -d '{
    "query": "{ summary { totalSchemas schemas { name totalObjects totalFields } } }"
  }'
Sample Queries
Get catalog summary:
{
  summary {
    totalSchemas
    schemas {
      name
      totalObjects
      totalFields
    }
  }
}
Get bundles with pagination:
{
  olmbundles(limit: 5, offset: 0) {
    name
    package
    version
  }
}
Get packages:
{
  olmpackages(limit: 10) {
    name
    description
  }
}
Get channels:
{
  olmchannels(limit: 10) {
    name
    package
    entries
  }
}

Features

  • Dynamic Schema Generation: Automatically discovers schema structure from catalog metadata
  • Nested Object Support: Handles complex nested structures like bundle properties and related images
  • Pagination: Built-in limit/offset pagination for all queries
  • Field Name Sanitization: Converts JSON field names to valid GraphQL identifiers
  • Catalog-Specific: Each catalog gets its own dynamically generated schema
  • Query Performance: Pre-parsed objects cached during schema build eliminate JSON unmarshaling overhead

Integration

The GraphQL functionality is integrated across multiple packages:

  • internal/catalogd/server/handlers.go: CatalogHandlers.handleV1GraphQL() handles POST requests to the GraphQL endpoint
  • internal/catalogd/storage/localdir.go: LocalDirV1.GetCatalogFS() creates filesystem interface for catalog data
  • internal/catalogd/service/graphql_service.go: GraphQLService.GetSchema() and buildSchemaFromFS() build dynamic GraphQL schemas for specific catalogs

Technical Details

  • Uses declcfg.WalkMetasFS to discover schema structure from catalog metadata
  • Generates GraphQL object types dynamically from discovered fields
  • Handles nested objects (arrays of objects) by creating dynamic nested types
  • Pre-parses all catalog objects during schema build and caches them for fast query execution
  • Supports all standard GraphQL features including introspection

Field Naming Conventions

Schema to GraphQL Field Name Mapping

IMPORTANT: GraphQL field names are automatically generated from schema names using the following convention:

  1. Remove dots and special characters - olm.bundle becomes olmbundle
  2. Convert to lowercase - OLM.Bundle becomes olmbundle
  3. Append 's' for pluralization - olmbundle becomes olmbundles

Examples:

  • olm.bundleolmbundles
  • olm.packageolmpackages
  • olm.channelolmchannels
  • helm.charthelmcharts
  • custom.operatorcustomoperators
Limitations and Considerations

⚠️ Pluralization Limitations: The current implementation blindly appends 's' to create plural field names. This approach has known limitations:

  1. English grammar rules not applied: Words ending in 's', 'x', 'z', 'ch', 'sh' should use 'es', but currently just get 's' appended
  2. Irregular plurals not supported: Schema names like person, child, index will become persons, childs, indexs instead of proper English plurals
  3. Non-English schema names: Schemas using non-English words will not follow appropriate pluralization rules for their language
  4. Already-plural names: If a schema name is already plural, it will still get 's' appended

Recommendations for schema naming:

  • Use schema names that work well with simple 's' pluralization (e.g., bundle, package, chart)
  • Avoid schema names that are already plural or have irregular plural forms
  • Document the expected GraphQL field names in your catalog documentation
  • Use GraphQL introspection to discover actual field names: { __schema { queryType { fields { name } } } }
Field Name Sanitization

All field names within objects are sanitized to be valid GraphQL identifiers:

  • Special characters (dots, hyphens, etc.) are replaced with underscores
  • CamelCase conversion: package-namepackageName, default_channeldefaultChannel
  • Names starting with numbers get field_ prefix: 123invalidfield_123invalid
  • Empty or invalid names default to value

See remapFieldName() function for complete logic.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func PrintCatalogSummary

func PrintCatalogSummary(dynamicSchema *DynamicSchema)

PrintCatalogSummary prints a comprehensive summary of the discovered schema

Types

type CatalogSchema

type CatalogSchema struct {
	Schemas map[string]*SchemaInfo // schema name -> info
}

CatalogSchema holds the complete discovered schema

func DiscoverSchemaFromMetas

func DiscoverSchemaFromMetas(metas []*declcfg.Meta) (*CatalogSchema, error)

DiscoverSchemaFromMetas analyzes Meta objects to discover schema structure

type DynamicSchema

type DynamicSchema struct {
	Schema        graphql.Schema
	CatalogSchema *CatalogSchema
	ParsedObjects map[string][]map[string]interface{} // Pre-parsed JSON objects cached during schema build

}

DynamicSchema holds the generated GraphQL schema and metadata

func BuildDynamicGraphQLSchema

func BuildDynamicGraphQLSchema(catalogSchema *CatalogSchema, metasBySchema map[string][]*declcfg.Meta) (*DynamicSchema, error)

BuildDynamicGraphQLSchema creates a complete GraphQL schema from discovered structure

func LoadAndSummarizeCatalogDynamic

func LoadAndSummarizeCatalogDynamic(catalogFS fs.FS) (*DynamicSchema, error)

LoadAndSummarizeCatalogDynamic loads FBC using WalkMetasReader and builds dynamic GraphQL schema

type FieldInfo

type FieldInfo struct {
	Name         string
	GraphQLType  graphql.Type
	JSONType     reflect.Kind
	IsArray      bool
	SampleValues []interface{}
	NestedFields map[string]*FieldInfo // For array-of-objects, stores object structure
}

FieldInfo represents discovered field information

type SchemaInfo

type SchemaInfo struct {
	Fields       map[string]*FieldInfo
	TotalObjects int
	SampleObject map[string]interface{}
}

SchemaInfo holds discovered schema information

Jump to

Keyboard shortcuts

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