Skip to main content

Querying the API

Marblism automatically generates secure CRUD (create/read/update/delelete) endpoint from your data model.

For example, considering this data model:

model Tweet {
id String @id @default(uuid())
content String
user User @relation(fields: [authorId], references: [id])
userId String
}

Zenstack will generate all the following endpoints for the table Tweet:

Api.tweet.findMany
Api.tweet.findFirst
Api.tweet.create
Api.tweet.update
Api.tweet.delete

Let's see how to use them:

Using the Api object

First, import the Api object from @/core/trpc:

import { Api } from '@/core/trpc'

The Api object contains methods corresponding to your API endpoints. You can use these methods to make queries or mutations.

Create

const { mutateAsync: createTweet, isLoading } = Api.tweet.create.useMutation()

await createTweet({
data: {
userId: '5',
content: 'My first tweet!',
},
})

Update

const { mutateAsync: updateTweet, isLoading } = Api.tweet.update.useMutation()

await updateTweet({
where: {
id: '2',
},
data: {
content: 'My first tweet, updated :)',
},
})

Delete

const { mutateAsync: deleteTweet, isLoading } = Api.tweet.delete.useMutation()

await deleteTweet({
where: {
id: '2',
},
})

Read

const { data: tweets, isLoading } = Api.tweet.findMany.useQuery({})

const { data: aSpecificTweet, isLoading } = Api.tweet.findFirst.useQuery({
where: { id: '1' },
})

Tweet is related to User and related to Comment. I can include the tweet's User and the comments + the user associated to each comment of a specific tweet with just one request:

const { data: tweet, isLoading } = Api.tweet.findFirst.useQuery({
where: { id: '73733892' },
include: {
user: true,
comments: {
include: {
user: true
}
}
},
})

Filter data by attributes

const { data: users, isLoading } = Api.user.findMany.useQuery({
where: {
email: {
endsWith: 'marblism.com',
},
name: {
equals: 'Archibald',
},
},
})

Check out the full list of operators you can use.

Order by date

const { data: tweets, isLoading } = Api.tweet.findMany.useQuery({
orderBy: [
{
dateCreated: 'desc',
},
{
name: 'asc',
},
],
})

Advanced sorting

Pagination

Skip the last 10 tweets and get 20 of them.

const { data: tweets, isLoading } = Api.tweet.findMany.useQuery({
skip: 10,
take: 20,
orderBy: [
{
dateCreated: 'desc',
},
],
})
info

The query options you can use replicate exactly Prisma query options. Check out their documentation for more advanced use cases.

Full Example

Here's a complete example of how you might use find many and create API queries on our tweet example.

import React from 'react'
import { Api } from '@/core/trpc'
import { List, Button, Spin, Form, Input, message, Card } from 'antd'

export default function HomePage() {
const { data: tweets, isLoading } = Api.tweet.findMany.useQuery({
include: { user: true },
})
const { mutateAsync: createTweet, isLoading: isLoadingCreate } =
Api.tweet.create.useMutation()

const [form] = Form.useForm()

const handleCreateTweet = async (values: any) => {
try {
await createTweet({ content: values.content })

message.success('Tweet created successfully')

form.resetFields()
} catch (err) {
message.error('Failed to create tweet')
}
}

return (
<div>
<h2>Tweets</h2>
{isLoading && <Spin tip="Fetching the tweets..." />}
{!isLoading && (
<div>
{tweets?.map(tweet => (
<Card key={tweet.id} title={tweet.user?.name}>
<p>{tweet.content}</p>
</Card>
))}
</div>
)}

<Form form={form} onFinish={handleCreateTweet}>
<Form.Item name="content">
<Input.TextArea rows={4} placeholder="What's on your mind?" />
</Form.Item>
<Form.Item>
<Button type="primary" htmlType="submit" loading={isLoadingCreate}>
Create Tweet
</Button>
</Form.Item>
</Form>
</div>
)
}