Create an API endpoint
While ZenStack automatically handles CRUD operations for your data models, you can also create custom API endpoints using tRPC. This is particularly useful for implementing custom business logic, integrating external services, or creating specialized endpoints. Existing plugins such as file upload are already defined following this pattern in the project.
Creating a Custom Router
Here's a basic example of how to create a custom router:
import { z } from 'zod'
import { Trpc } from '~/core/trpc/base'
export const CustomRouter = Trpc.createRouter({
greet: Trpc.procedure
.input(z.object({ name: z.string() }))
.query(async ({ input }) => {
return `Hello, ${input.name}!`
}),
randomNumber: Trpc.procedurePublic
.query(() => {
return Math.random()
}),
})
In this example, we've created two endpoints:
greet
: Takes a name as input and returns a greeting. This endpoint is protected by default.randomNumber
: Returns a random number. This endpoint is public and can be accessed without authentication.
Adding the Custom Router to the App Router
To make your custom router available, you need to add it to the main app router at app/core/trpc/server/index.tsx
:
import { createRouter } from '../../.marblism/zenstack/routers'
import { Trpc } from '../base'
import { CustomRouter } from './custom.router'
export const appRouter = Trpc.mergeRouters(
createRouter(Trpc.createRouter, Trpc.procedure),
// Add your custom router here
Trpc.createRouter({
custom: CustomRouter,
// ... other routers
}),
)
export type AppRouter = typeof appRouter
export const Server = {
appRouter,
}
Using the Custom Endpoint in the Frontend
Once your custom router is added to the app router, you can use it in your frontend components like this:
import { Api } from '@/core/trpc'
// In a React component
const MyComponent = () => {
const greetQuery = Api.custom.greet.useQuery({ name: 'World' })
const randomNumberQuery = Api.custom.randomNumber.useQuery()
if (greetQuery.isLoading || randomNumberQuery.isLoading) return <div>Loading...</div>
return (
<div>
<p>{greetQuery.data}</p>
<p>Random number: {randomNumberQuery.data}</p>
</div>
)
}
By following this pattern, you can create custom endpoints for various functionalities while still leveraging the power of tRPC and ZenStack's automatic CRUD operations. Remember that you can control the access level of your endpoints using Trpc.procedure
for protected routes and Trpc.procedurePublic
for public routes.