* Introduced GUID field to Database, Domain, DomainTable, Schema, Table, View, Sequence, Column, Index, Relationship, Constraint, Enum, and Script models. * Updated initialization functions to assign new GUIDs using uuid package. * Enhanced DCTX reader and writer to utilize GUIDs from models where available.
GraphQL Schema Reader
The GraphQL reader parses GraphQL Schema Definition Language (SDL) files and converts them into RelSpec's internal database model.
Features
- Standard GraphQL SDL support (generic, non-framework-specific)
- Type to Table mapping: GraphQL types become database tables
- Field to Column mapping: GraphQL fields become table columns
- Enum support: GraphQL enums are preserved
- Custom scalars: DateTime, JSON, Date automatically mapped to appropriate SQL types
- Implicit relationships: Detects relationships from field types
- Many-to-many support: Creates junction tables for bidirectional array relationships
- Configurable ID mapping: Choose between bigint (default) or UUID for ID fields
Supported GraphQL Features
Built-in Scalars
ID→ bigint (default) or uuid (configurable)String→ textInt→ integerFloat→ double precisionBoolean→ boolean
Custom Scalars
DateTime→ timestampJSON→ jsonbDate→ dateTime→ timeDecimal→ numeric
Additional custom scalars can be mapped via metadata.
Relationships
Relationships are inferred from field types:
type Post {
id: ID!
title: String!
author: User! # Many-to-one (creates authorId FK column, NOT NULL)
reviewer: User # Many-to-one nullable (creates reviewerId FK column, NULL)
tags: [Tag!]! # One-to-many or many-to-many (depending on reverse)
}
type User {
id: ID!
posts: [Post!]! # Reverse of Post.author (no FK created)
}
type Tag {
id: ID!
posts: [Post!]! # Many-to-many with Post (creates PostTag junction table)
}
Relationship Detection Rules:
- Single type reference (
user: User) → Creates FK column (e.g.,userId) - Array type reference (
posts: [Post!]!) → One-to-many reverse (no FK on this table) - Bidirectional arrays → Many-to-many (creates junction table)
Enums
enum Role {
ADMIN
USER
GUEST
}
type User {
role: Role!
}
Enums are preserved in the schema and can be used as column types.
Usage
Basic Usage
import (
"git.warky.dev/wdevs/relspecgo/pkg/readers"
"git.warky.dev/wdevs/relspecgo/pkg/readers/graphql"
)
opts := &readers.ReaderOptions{
FilePath: "schema.graphql",
}
reader := graphql.NewReader(opts)
db, err := reader.ReadDatabase()
With UUID ID Type
opts := &readers.ReaderOptions{
FilePath: "schema.graphql",
Metadata: map[string]interface{}{
"idType": "uuid", // Map ID scalar to uuid instead of bigint
},
}
reader := graphql.NewReader(opts)
db, err := reader.ReadDatabase()
With Per-Type ID Mapping
opts := &readers.ReaderOptions{
FilePath: "schema.graphql",
Metadata: map[string]interface{}{
"typeIdMappings": map[string]string{
"User": "uuid", // User.id → uuid
"Post": "bigint", // Post.id → bigint
},
},
}
With Custom Scalar Mappings
opts := &readers.ReaderOptions{
FilePath: "schema.graphql",
Metadata: map[string]interface{}{
"customScalarMappings": map[string]string{
"Upload": "bytea",
"Decimal": "numeric(10,2)",
},
},
}
CLI Usage
# Convert GraphQL to JSON
relspec convert --from graphql --from-path schema.graphql \
--to json --to-path schema.json
# Convert GraphQL to GORM models
relspec convert --from graphql --from-path schema.graphql \
--to gorm --to-path models/ --package models
# Convert GraphQL to PostgreSQL SQL
relspec convert --from graphql --from-path schema.graphql \
--to pgsql --to-path schema.sql
Metadata Options
| Option | Type | Description | Default |
|---|---|---|---|
idType |
string | Global ID type mapping ("bigint" or "uuid") | "bigint" |
typeIdMappings |
map[string]string | Per-type ID mappings | {} |
customScalarMappings |
map[string]string | Custom scalar to SQL type mappings | {} |
schemaName |
string | Schema name for all tables | "public" |
Limitations
- Only supports GraphQL SDL (Schema Definition Language), not queries or mutations
- Directives are ignored (except for future extensibility)
- Interfaces and Unions are not supported
- GraphQL's concept of "schema" is different from database schemas; all types go into a single database schema (default: "public")
Example
Input (schema.graphql):
scalar DateTime
enum Role {
ADMIN
USER
}
type User {
id: ID!
email: String!
role: Role!
createdAt: DateTime!
posts: [Post!]!
}
type Post {
id: ID!
title: String!
content: String
published: Boolean!
author: User!
}
Result: Database with:
- 2 tables:
UserandPost Posttable hasauthorIdforeign key toUser.idRoleenum with values: ADMIN, USER- Custom scalar
DateTimemapped totimestamp