JSON Schema Generation
Last updated:
JSON Schema Generation
Understanding how Prisma models are transformed to JSON Schema v7.
JSON Schema v7
The transformer generates JSON Schema Draft 7 compliant schemas:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"definitions": {},
"properties": {}
}Model to Schema Mapping
Prisma models become JSON Schema definitions:
Input (Prisma)
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
age Int
}Output (JSON Schema)
{
"definitions": {
"User": {
"type": "object",
"properties": {
"id": {
"type": "integer"
},
"email": {
"type": "string"
},
"name": {
"type": ["string", "null"]
},
"age": {
"type": "integer"
}
}
}
},
"properties": {
"user": {
"$ref": "#/definitions/User"
}
}
}Type Conversion
Scalar Types
Prisma types convert to JSON Schema types:
| Prisma Type | JSON Schema Type |
|---|---|
| String | "string" |
| Int | "integer" |
| BigInt | "integer" |
| Float | "number" |
| Decimal | "number" |
| Boolean | "boolean" |
| DateTime | "string" with format: "date-time" |
| Json | "object" |
| Bytes | "string" |
Optional Fields
Optional Prisma fields use null union types:
model User {
name String? // Optional
}{
"name": {
"type": ["string", "null"]
}
}Arrays
List fields use JSON Schema arrays:
model User {
tags String[]
}{
"tags": {
"type": "array",
"items": {
"type": "string"
}
}
}Enums
Prisma enums become JSON Schema enums:
enum Role {
USER
ADMIN
MODERATOR
}
model User {
role Role @default(USER)
}{
"definitions": {
"Role": {
"type": "string",
"enum": ["USER", "ADMIN", "MODERATOR"]
},
"User": {
"type": "object",
"properties": {
"role": {
"$ref": "#/definitions/Role"
}
}
}
}
}Relations
Relation handling depends on keepRelationScalarFields option:
With keepRelationScalarFields: "false"
Relations use object references:
model Post {
author User @relation(fields: [authorId], references: [id])
authorId Int
}{
"properties": {
"author": {
"$ref": "#/definitions/User"
}
}
}Foreign key (authorId) is omitted.
With keepRelationScalarFields: "true"
Both relation and foreign key are included:
{
"properties": {
"author": {
"$ref": "#/definitions/User"
},
"authorId": {
"type": "integer"
}
}
}Required Fields
With includeRequiredFields: "true", the schema includes required field constraints:
model User {
id Int @id
email String
name String?
}{
"type": "object",
"properties": {
"id": { "type": "integer" },
"email": { "type": "string" },
"name": { "type": ["string", "null"] }
},
"required": ["id", "email"]
}Original Type Information
With persistOriginalType: "true", Prisma types are preserved:
{
"email": {
"type": "string",
"prismaType": "String"
},
"createdAt": {
"type": "string",
"format": "date-time",
"prismaType": "DateTime"
}
}Useful for generators that need Prisma-specific information.
Schema ID
The schemaId option sets the $id property:
transformDMMF(dmmf, {
schemaId: "https://api.example.com/schema",
});{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://api.example.com/schema",
"type": "object",
"definitions": {}
}This creates resolvable references:
{
"$ref": "https://api.example.com/schema#/definitions/User"
}Definitions vs Properties
The schema has two main sections:
Definitions
Reusable model schemas:
{
"definitions": {
"User": { /* schema */ },
"Post": { /* schema */ }
}
}Properties
Top-level references (camelCase model names):
{
"properties": {
"user": { "$ref": "#/definitions/User" },
"post": { "$ref": "#/definitions/Post" }
}
}Composite Types
Prisma composite types (MongoDB) are transformed similarly:
type Address {
street String
city String
zip String
}
model User {
address Address
}{
"definitions": {
"Address": {
"type": "object",
"properties": {
"street": { "type": "string" },
"city": { "type": "string" },
"zip": { "type": "string" }
}
},
"User": {
"type": "object",
"properties": {
"address": {
"$ref": "#/definitions/Address"
}
}
}
}
}