builder$

API for the builder$ function

This function should be used when we want to create a sort of re-useable procedure. For instance, lets assume we have a protected function, we don’t want to re-add the middlewares everytime, we just declare the builder once and use it, this will add the middleware by default.

Usage

Step 1

This is the recommended way to use the builder function (file structure, etc…)

Create a file under server called prpc (basically server/prpc.ts) and fill it with the following:

import { builder$ } from '@solid-mediakit/prpc'

export const helloBuilder = builder$()
  .middleware$(() => {
    return {
      hello: 1,
    }
  })
  .middleware$((ctx) => {
    return {
      ...ctx,
      world: 2,
    }
  })

Ofc you should use actual middleware but this is just an example and it works (copy paste).

Step 2

After you have created the builder, create the actual query/mutation, create a folder under server using the name of your builder (for instance helloBuilder so we are going to use hello). The folder is going to be server/hello and inside it create a file called hello.queries.ts to declare the queries of the procedure.

import { z } from 'zod'
import { helloBuilder } from '../prpc'

export const helloQuery = helloBuilder
  .input(
    z.object({
      hello: z.string(),
    })
  )
  .query$(({ payload, ctx$ }) => {
    if (payload.hello === 'hello') {
      return ctx$.hello
    }
    return ctx$.world
  }, 'myNewQuery')

So the format of the helloBuilder is basically:

  • helloBuilder.input(zodSchema) - to declare the input of the query, optional
  • helloBuilder.query$(function, ‘queryName’) - to declare the query & queryKey, the function is the actual query, the queryKey is the name of the query, using .query$ will declare this function as query (createQuery).
  • helloBuilder.mutation$(function, ‘mutationName’) - to declare the mutation & mutationKey, the function is the actual mutation, the mutationKey is the name of the mutation, using .mutation$ will declare this function as mutation (createMutation).
  • helloBuilder.middleware$(function) - to declare a middleware, this will be added to the builder, you can add multiple middlewares, the order of the middlewares is the order they are added and called.

Step 3

After setting all the logic, you can now use the query/mutation in your client.

import { type VoidComponent } from 'solid-js'
import { helloQuery } from '~/server/hello/hello.queries'

const Home: VoidComponent = () => {
  const hello = helloQuery(() => ({
    hello: 'JDev',
  }))
  return (
    <main class='flex min-h-screen flex-col items-center justify-center bg-gradient-to-b from-[#026d56] to-[#152a2c]'>
      <div class='container flex flex-col items-center justify-center gap-12 px-4 py-16 '>
        <h1 class='text-5xl font-extrabold tracking-tight text-white sm:text-[5rem]'>
          Query
        </h1>
        <p class='text-2xl text-white'>{hello.data}</p>
      </div>
    </main>
  )
}

export default Home

The format is basically:

myQuery(()=> myInput, ()=> myTanstackQueryOptions)

Invalid Usage

This is an example of invalid usage: DO NOT CREATE THE BUILDER AND SET THE QUERY DIRECTLY, SEPERATE THE TWO

import { builder$ } from '@solid-mediakit/prpc'

export const helloQuery = builder$()
  .middleware$(() => {
    return {
      hello: 1,
    }
  })
  .middleware$((ctx) => {
    return {
      ...ctx,
      world: 2,
    }
  }).query$(...)

What you should do

import { builder$ } from '@solid-mediakit/prpc'

export const helloBuilder = builder$()
  .middleware$(() => {
    return {
      hello: 1,
    }
  })
  .middleware$((ctx) => {
    return {
      ...ctx,
      world: 2,
    }
  });

export const helloQuery = helloBuilder.query$(...)