Generate GraphQL schemas from Go structs with annotations, generics support, and advanced field control.
📖 Full Documentation: https://pablor21.github.io/gqlschemagen
💡 VS Code Extension: gqlschemagen-vscode
GQLSchemaGen generates GraphQL schema files (.graphqls) from your Go code using simple annotations. Designed to work seamlessly with gqlgen, it turns your Go structs into GraphQL types, inputs, and enums—keeping your schema in sync with your codebase.
✨ Code-First Schema Generation - Annotate Go structs to generate types, inputs, and enums
🎯 Advanced Field Control - Fine-grained visibility with ro/wo/rw tags and field filtering
🔄 Auto-Discovery - Automatically generate schemas for referenced types
🧬 Full Generics Support - Works with Go 1.18+ generic types (Response[T], Connection[T])
🗂️ Namespace Organization - Organize schemas into folders/namespaces
🔧 Scalar Mappings - Map Go types to GraphQL scalars globally (UUID → ID, time.Time → DateTime)
🛡️ Schema Preservation - Keep manual edits with @GqlKeepBegin/@GqlKeepEnd markers
⚙️ gqlgen Integration - Generates @goModel, @goField directives automatically (requires Opt-in via config or --gqlgen flag)
go install github.com/pablor21/gqlschemagen@latest1. Annotate your Go structs:
package models
// @gqlType
type User struct {
ID string `gql:"id,type:ID"`
Name string `gql:"name"`
Email string `gql:"email"`
CreatedAt time.Time `gql:"createdAt,ro"` // Read-only (excluded from inputs)
}
// @gqlInput
type CreateUserInput struct {
Name string `gql:"name"`
Email string `gql:"email"`
Password string `gql:"password,wo"` // Write-only (excluded from types)
}
// @gqlEnum
type UserRole string
const (
UserRoleAdmin UserRole = "admin" // @gqlEnumValue(name:"ADMIN")
UserRoleViewer UserRole = "viewer" // @gqlEnumValue(name:"VIEWER")
)2. Create config file gqlschemagen.yml:
gqlschemagen initThis command generates a default gqlschemagen.yml configuration file in your current directory.
3. Generate schema:
gqlschemagen generate --gqlgen4. Generated schema.graphqls:
type User @goModel(model: "your-module/models.User") {
id: ID!
name: String!
email: String!
createdAt: String!
}
input CreateUserInput {
name: String!
email: String!
password: String!
}
enum UserRole {
ADMIN
VIEWER
}// @gqlType(name:"User")
// @gqlType(name:"PublicUser", ignoreAll:"true")
// @gqlInput(name:"CreateUserInput")
// @gqlInput(name:"UpdateUserInput")
type User struct {
ID string `gql:"id,type:ID,ro"`
Name string `gql:"name,include:*"` // Include in all
Email string `gql:"email,include:User"` // Only in User type
}scalars:
ID:
model:
- github.com/google/uuid.UUID
DateTime:
model:
- time.Timeauto_generate:
strategy: referenced # none | referenced | all | patterns
max_depth: 3We welcome contributions! To add new features or improvements, please follow these steps:
-
Update configuration Modify the
Configstruct inconfig.goto include any new settings required by your feature. -
Add parsing logic Implement the necessary parsing in
directives.goto handle any new directives or annotations. -
Implement code generation Extend
generator.gowith the generation logic for your feature. -
Update documentation Make sure to update this README or relevant docs to reflect your changes, including a brief explanation of the feature.
-
Add examples Provide usage examples or sample code demonstrating how to use your feature.
Following these steps ensures that your contribution is clear, well-documented, and easy for others to understand.
MIT License. See LICENSE for details.
Made with ❤️ by Pablo Ramirez pablo@pramirez.dev | Website | GitHub