Skip to content

$socket – Real-time Event API

The $socket API provides access to real-time backend events that are emitted after data operations (create, update, delete, etc.) If you have configered the routes to do so via the fastify route config.

How to define routes
typescript
import type { Static } from "@sinclair/typebox"
import type { FastifyReply, FastifyRequest } from "fastify"
import { Type } from "@sinclair/typebox"
import type { PluginFastifyInstance } from "@raclettejs/types"

const ParamsSchema = Type.Object({
  _id: Type.String(),
})
type Params = Static<typeof ParamsSchema>

export default (fastify: PluginFastifyInstance) => {
  const handler = async (
    req: FastifyRequest<{
      Params: Params
    }>,
    reply: FastifyReply,
  ) => {
    try {
      /* YOUR BUSINESS LOGIC */
    } catch (err: any) {
      fastify.log.error(err.message)
      return reply.internalServerError(err.message)
    }
  }

  return {
    handler,
    onRequest: [fastify.authenticate],
    config: {
      type: dataCreate,
      broadcastChannels: ["todoCreated","mySuperFancyCustomEvent"],
    },
    schema: {
      summary: "Example todo post Route",
      description: "Example todo post Route",
      tags: ["myApp/todo"],
      body: todoBaseSchema,
    },
  }
}

It is the bridge between:

  • backend channels
  • frontend reactive updates
  • $data operations

🧠 Core Concept

Backend operations emit named channels after execution.

Frontend listens to these channels via $socket:

ts
$socket.on(channelKey, callback)

📡 Listening to Events

Basic Usage

ts
$socket.on("todoCreated", (payload) => {
  console.log("Todo created:", payload)
})
  • channelKey → logical event name (not full channel string)
  • payload → data emitted from backend

🔁 Typical Pattern (Refresh on Event)

Most commonly, $socket is used to refresh queries after mutations:

ts
const { execute } = $data.todo.getAll()

$socket.on("todoCreated", () => {
  execute()
})
ts
$socket.on("todoDeleted", () => {
  execute()
})

🧩 Real Usage Example

ts
$socket.on("todoCreated", (payload) => {
  $log("todoCreated", payload)

  execute() // refetch data
})

$socket.on("todoDeleted", (payload) => {
  $log("todoDeleted", payload)

  $eventbus.global.emit("ui/addToSnackbar", {
    message: "My custom notification next to the default core 'delete' notification",
    color: "yellow",
  })

  execute()
})

🔌 Channel Mapping Concept

Each event name corresponds to a backend-emitted channel.

Frontend only uses:

ts
channelKey

Example:

Backend ChannelFrontend Event
...--todoCreatedtodoCreated
...--todoUpdatedtodoUpdated
...--todoDeletedtodoDeleted

🧠 Mental Model

  • Backend emits → channel event
  • $socket receives → normalized event name
  • UI reacts → refresh, notify, mutate store

⚖️ When to Use $socket

Use $socket when you need to:

  • react to backend changes in real time
  • sync multiple clients
  • refresh $data after mutations
  • trigger UI updates globally

🚫 Important Notes

  • $socket is event-driven, not request-driven
  • It does not replace $data.execute()
  • It complements $data by keeping UI in sync
  • Events are non-reactive by default (you must handle updates manually)

🧠 Key Takeaway

$data performs actions $socket reacts to actions

👉 Together they form a request → event → sync loop