SQL databases provide us with many benefits, the most important of which is strong schema enforcement. Yes, you pay the cost of migration when the schema changes, but the gain is far more significant - your code is clean because it can assume all data are in correct shapes.
However, once in a while, we want to break free from such strong guarantees for valid reasons. You may have some tiny objects that you want to attach to the main entities (e.g., metadata of an image) without formalizing them into a separate table. Or you need to store records with many possible sparse fields but want to avoid creating wide tables.
Prisma's JSON type provides a generic escape hatch for such scenarios. It allows storing arbitrary data and gives you a generic JsonValue type in the query results.
// schema.prisma
model Image {
id Int @id @default(autoincrement())
metadata Json
}
// TS code
type Metadata {
width: number
height: number
format: string
}
const image = await prisma.image.findFirstOrThrow();
// an explicit cast into the desired type
const metadata = image.metadata as Metadata;
console.log('Image dimensions:',
metadata.width, 'by', metadata.height);
This is not always ideal because, in practice, many people use JSON type in a "controlled" way - only data of specific fixed shapes are stored in a field. So, regaining some of the strong typing capabilities would be very beneficial.
:
// find images with width greater than 102
const images = await db.image.findMany({
where: {
metadata: { path: ['width'], gt: 1024 }
}
});
We can potentially "enhance" that part to provide a typed experience like:
const images = await db.image.findMany({
where: {
metadata: { width: { gt: 1024 } }
}
});
Is it useful, or can it be confusing (as it looks the same as relation filters)? Let us know by leaving a comment below. You can also learn more about this feature in the is a TypeScript toolkit that systematically extends Prisma ORM's power. Besides strongly typed JSON fields, it offers a set of other capabilities that may greatly simplify your full-stack development:
- Authorization rules in schema
- Auto RESTful API generation
- Frontend query hooks generation
- ...
Make sure you check it out if you're using Prisma.
SOCIAL SHARE CARD GENERATOR