Provides highly productive ways of creating APIs with Prisma and Stainless.
Warning
This is alpha software, and we may make significant changes in the coming months. We're eager for you to try it out and let us know what you think!
npm i --save stainless-api/stl-api#prisma-0.0.3
// ~/libs/stl.ts
import { Stl } from "stainless";
+import { makePrismaPlugin } from "@stl-api/prisma";
const plugins = {
+ prisma: makePrismaPlugin(),
};
export const stl = new Stl({
plugins,
});
// ~/api/posts/models.ts
import { z } from "stainless";
+import prisma from "~/libs/prisma";
export const Post = z.response({
id: z.string().uuid(),
body: z.string().nullable().optional(),
userId: z.string().uuid(),
}).prismaModel(prisma.post);
Any endpoint whose response
has a prismaModel
declared with have ctx.prisma
available in its handler
. ctx.prisma
provides wrappers for the following methods
that magically inject options for include
and select
params as necessary:
findUnique
findUniqueOrThrow
findMany
(also magically injects pagination options from parameters)create
update
delete
Warning
This currently only works if the primary key is named
id
. We plan to remove this limitation soon.
// ~/api/posts/retrieve.ts
import { stl } from "~/libs/stl";
import { z } from "stainless";
import prisma from "~/libs/prismadb";
import { Post } from "./models";
export const retrieve = stl.endpoint({
endpoint: "GET /api/posts/{postId}",
response: Post,
path: z.object({
postId: z.string(),
}),
query: z.object({
include: z.includes(Post, 3).optional(),
select: z.selects(Post, 3).optional(),
}),
async handler({ postId }, ctx) {
// Prisma plugin magically injects options for include and select!
return await ctx.prisma.findUniqueOrThrow({ where: { id: postId } });
},
});
// ~/api/posts/create.ts
import { stl } from "~/libs/stl";
import { z } from "stainless";
import { Post } from "./models";
export const create = stl.endpoint({
endpoint: "POST /api/posts",
response: Post,
body: z.object({
body: z.string(),
}),
async handler({ body }, ctx) {
return await ctx.prisma.create({
data: {
userId: ctx.requireCurrentUser().id,
body,
},
});
},
});
The following post: z.string().prismaModelLoader(prisma.post)
parameter takes a string id
as input from the {post}
path
parameter and is transformed to the fetched model instance in
the handler
.
Warning
This currently only works if the primary key is named
id
. We plan to remove this limitation soon.
// ~/api/posts/retrieve.ts
import { stl } from "@/libs/stl";
import { z } from "stainless";
import prisma from "@/libs/prismadb";
import { Post } from "./models";
export const retrieve = stl.endpoint({
endpoint: "GET /api/posts/{post}",
response: Post,
path: z.object({
post: z.string().prismaModelLoader(prisma.post),
}),
async handler({ post }, ctx) {
// here post is fetched Prisma model, not a string
return post;
},
});
@stl-api/prisma
makes it easy to implement pagination with Prisma.