Write server code, query / mutate it on the server and validate inputs using zod with only few lines of code. Supporting SolidStart and Bling.
Read more at our docs
pRPC currently has 2 adapters, one for Bling and one for SolidStart.
Read More Here Regarding Bling
Read More Here Regarding SolidStart
import { query$ } from '@prpc/solid'
import {
createSignal,
Match,
Suspense,
Switch,
type VoidComponent,
} from 'solid-js'
import { z } from 'zod'
const queryOnServer = query$({
queryFn: async ({ payload, request$ }) => {
console.log('on server', request$.headers.get('user-agent'))
return { result: payload.num / 2 }
},
key: 'queryOnServer',
schema: z.object({
num: z.number().max(5),
}),
})
const Query: VoidComponent = () => {
const [num, setNum1] = createSignal(1)
const queryRes = queryOnServer(
() => ({ num: num() }),
() => ({
placeholderData: (prev) => prev,
onError: (error) => {
if (error.isZodError()) {
const fieldErrors = error.cause.fieldErrors
console.log(fieldErrors.num)
}
},
retry: false,
})
)
return (
<div class='flex flex-col gap-3 px-3'>
<Suspense fallback='Loading...'>
<Switch>
<Match when={queryRes.error}>Error: {queryRes.error?.message}</Match>
<Match when={queryRes.data}>Result: {queryRes.data?.result}</Match>
</Switch>
</Suspense>
<button
class='border border-gray-300 p-3'
onClick={() => setNum1((num) => num + 1)}
>
{num()} - Increment
</button>
{queryRes.error?.message && <pre>{queryRes.error?.message}</pre>}
</div>
)
}
export default Query
The code in this image is
import { query$ } from '@prpc/solid'
import { z } from 'zod'
export const helloQuery = query$(
({ payload, request$ }) => {
console.log(request$.headers.get('user-agent'))
return `server says hello: ${payload.name}`
},
'hello',
z.object({ name: z.string() })
)
But how is this code working / running on the server? request$ is not an actual thing and you cannot use closures. We use a babel plugin built on top of vite that is meant to wrap functions that passed to query$ with server, so for instance:
query$(myFn)
becomes
query$(server$(myFn))
This piece of code make the function run on the server, but how do we access the request?
Well as you know request$ is not an actual thing in in SolidStart, this is again where our babel plugin helps, we pass an empty object to this function called request$ and then our babel plugin makes sure to replace all request$ acccess with server$.request (which is a way to get the request in SolidStart)
So for instance:
query$(({ request$ }) => {
const headers = request$.headers
})
becomes
query$(
server$(() => {
const headers = server$.request.headers
})
)
How do i call this function from the client?
query$ returns: (...) => createQuery(...)
So what it does is, it is taking the function that is running on the server (wrapped with server$) and basically try to query it using createQuery
from solid query.
So:
const myQuery = query$(myFn)
Can be used client side (still will run on the server):
const queryRes = myQuery(() => input)
// queryRes is basically tanstack query
queryRes.isLoading
queryRes.data