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' },
})
Includes related objects
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:
- Query
- Result
const { data: tweet, isLoading } = Api.tweet.findFirst.useQuery({
where: { id: '73733892' },
include: {
user: true,
comments: {
include: {
user: true
}
}
},
})
{
"id": "1",
"content": "My first tweet",
"userId": "2",
"user": {
"id": "2",
"name": "John",
},
"comments": [
{
"id": "3",
"user": {
"id": "4",
"name": "Ellen"
}
"content": "Superb tweet!"
}
]
}
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',
},
],
})
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',
},
],
})
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>
)
}