This plugin generates a complete GraphQL schema with relations, filtering, sorting, and pagination. Saving you hours of boilerplate code to match your database models with you graphql server.
- Zero Boilerplate: Go from data model to full GraphQL API schema using the Zenstack
- Dual Output Formats: Generate either GraphQL SDL schemas or TypeGraphQL TypeScript classes
- TypeGraphQL Support: Generate type-safe TypeScript classes with decorators for TypeGraphQL-based servers
- Relationship Handling: All your model relations become GraphQL connections automatically
- Modern API Features: Built-in filtering, sorting and Relay-compatible pagination
- Customization That Makes Sense: Rename fields, customize types, hide sensitive data, ignore generations...
TL;DR - See the graphql-server example with full code example
Install with your favorite package manager:
# Using bun (Recommended)
bun add @hakutakuai/zenstack-graphql -D
# Using npm
npm install @hakutakuai/zenstack-graphql --save-dev
# Using yarn
yarn add @hakutakuai/zenstack-graphql -D
#...Add to your schema.zmodel file:
Just a base example
plugin graphql {
provider = '@hakutakuai/zenstack-graphql'
output = './schema.graphql'
outputFormat = 'graphql' // or 'type-graphql' for TypeScript classes
}Generate your GraphQL schema:
zenstack generateThat's it! Your GraphQL schema is ready to use with any GraphQL server.
For TypeScript projects using TypeGraphQL, you can generate TypeScript classes instead:
plugin graphql {
provider = '@hakutakuai/zenstack-graphql'
output = './schema.ts'
outputFormat = 'type-graphql'
}This generates TypeScript classes with TypeGraphQL decorators instead of SDL.
Keep your GraphQL schema clean to your needs:
plugin graphql {
// Basic settings
output = './schema.graphql'
outputFormat = 'graphql' // 'graphql' for SDL or 'type-graphql' for TypeScript
// Use your preferred naming style
fieldNaming = 'snake_case' // Fields become like_this
typeNaming = 'PascalCase' // Types become LikeThis
// Customize scalar type mappings
scalarTypes = {
"DateTime": 'Date', // Use Date instead of DateTime
"Json": 'JSONObject' // Use JSONObject instead of JSON
}
// Turn features on/off as needed
connectionTypes = true // Add Relay pagination support
generateFilters = true // Add filtering capabilities
generateSorts = true // Add sorting functionality
}Control exactly what appears in your API:
model User {
id Int @id
email String @unique
// Hide sensitive fields from the API
password String @graphql.ignore
// Rename fields for better API design
emailAddress String @graphql.name("email")
// Add clear descriptions for your API docs
fullName String @graphql.description("User's complete name")
// Mark fields for filtering and sorting
createdAt DateTime @graphql.sortable @graphql.filterable
// Model-level customization
@@graphql.name("Member") // Rename the type
@@graphql.description("Platform member") // Add type description
@@graphql.connection(pageSize: 20) // Configure pagination
}Here's a complete reference of all available options:
| Option | Type | Default | Description |
|---|---|---|---|
output |
string |
'./schema.graphql' |
Output path for the generated schema |
outputFormat |
string |
'graphql' |
Output format: 'graphql' for SDL or 'type-graphql' for TypeScript |
scalarTypes |
object |
See below | Custom mappings for scalar types |
connectionTypes |
boolean |
true |
Generate Relay-compatible connection types |
generateEnums |
boolean |
true |
Generate GraphQL enum types |
generateScalars |
boolean |
true |
Generate GraphQL scalar types |
generateFilters |
boolean |
true |
Generate filter input types |
generateSorts |
boolean |
true |
Generate sort input types |
fieldNaming |
string |
'camelCase' |
Field naming convention |
typeNaming |
string |
'PascalCase' |
Type naming convention |
includeRelations |
boolean |
true |
Include model relations in schema |
Default scalar mappings:
{
"DateTime": 'DateTime',
"Json": 'JSON',
"Decimal": 'Decimal',
"Bytes": 'String'
}
You can see a example on custom-naming
The plugin transforms your ZModel schema into a GraphQL schema through these steps:
- Parsing: Reads your data models and extracts entities, relationships, and attributes
- Type Generation: Creates GraphQL types that match your data structure
- Relation Processing: Maps your model relationships to GraphQL connections
- Connection Generation: Builds Relay-compatible pagination support
- Schema Assembly: Puts everything together into a complete GraphQL schema
- Output: Writes the final schema to your specified location
All this happens automatically when you run
zenstack generate, you can see more about on Zenstack Plugin System!
Here's how easy it is to create a blog API:
First, define your data models:
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
generator client {
provider = "prisma-client-js"
}
plugin graphql {
provider = "@hakutakuai/zenstack-graphql"
output = "./schema.graphql"
}
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
posts Post[]
}
model Post {
id Int @id @default(autoincrement())
title String
content String?
published Boolean @default(false)
author User @relation(fields: [authorId], references: [id])
authorId Int
}Running zenstack generate automatically produces this GraphQL schema:
"""
An object with a unique identifier
"""
interface Node {
"""
The unique identifier for this object
"""
id: ID!
}
"""
A date-time string at UTC, such as 2007-12-03T10:15:30Z
"""
scalar DateTime
"""
The `JSON` scalar type represents JSON values as specified by ECMA-404
"""
scalar JSON
"""
An arbitrary-precision Decimal type
"""
scalar Decimal
# Base model types
type User {
id: Int!
email: String!
name: String
posts: [Post!]!
}
type Post {
id: Int!
title: String!
content: String
published: Boolean!
author: User!
authorId: Int!
}
# Pagination support (Relay-compatible)
type PageInfo {
hasNextPage: Boolean!
hasPreviousPage: Boolean!
startCursor: String
endCursor: String
}
# Connection types for related lists
type UserConnection {
pageInfo: PageInfo!
edges: [UserEdge!]!
totalCount: Int!
}
type UserEdge {
node: User!
cursor: String!
}
type PostConnection {
pageInfo: PageInfo!
edges: [PostEdge!]!
totalCount: Int!
}
type PostEdge {
node: Post!
cursor: String!
}
# Filtering and sorting inputs
input StringFilterInput {
equals: String
not: String
in: [String!]
notIn: [String!]
contains: String
startsWith: String
endsWith: String
}
input BooleanFilterInput {
equals: Boolean
not: Boolean
}
# ... and more generated types for complete API functionalityThis simple schema definition gives you a GraphQL API with:
- Custom Scalars: DateTime, JSON, and Decimal scalar types
- Base Types: User and Post types with their relationships
- Relay Connections: Connection types for efficient pagination
- Filtering: Filter inputs for complex data queries
- Sorting: Sort inputs for ordering results
- Standard Interfaces: Node interface for unified type handling
No need to write connection types, or filtering logic, everything is automatically generated from your data model.
For TypeScript projects using TypeGraphQL, the plugin can generate TypeScript classes with decorators:
plugin graphql {
provider = "@hakutakuai/zenstack-graphql"
output = "./schema.ts"
outputFormat = "type-graphql"
}
model User {
id String @id @default(cuid())
name String
email String @unique
bio String?
posts Post[]
}
model Post {
id String @id @default(cuid())
title String
content String
published Boolean @default(false)
author User @relation(fields: [authorId], references: [id])
authorId String
}import { ObjectType, Field, registerEnumType } from 'type-graphql'
import { GraphQLJSON } from 'graphql-scalars'
import 'reflect-metadata'
@ObjectType()
export class User {
@Field(() => String)
id!: string
@Field(() => String)
name!: string
@Field(() => String)
email!: string
@Field(() => String, { nullable: true })
bio?: string
}
@ObjectType()
export class Post {
@Field(() => String)
id!: string
@Field(() => String)
title!: string
@Field(() => String)
content!: string
@Field(() => Boolean)
published!: boolean
@Field(() => String)
authorId!: string
}These classes are ready to use with TypeGraphQL resolvers and provide full type safety for your GraphQL API.
Check the examples directory for more sample use cases!
Liked this plugin? Want to make it better? Contributions are always welcome! You can open a issue or pull requests on this repository 🧡
This project is licensed under the GNU General Public License v3.0 (GPL-3.0) - see the LICENSE file for details.