### Vanilla Client Setup Source: https://github.com/befabri/trpcgo/blob/main/README.md Demonstrates setting up a vanilla tRPC client without any specific framework. It configures the client with an HTTP batch link and shows an example of making a query. ```typescript import { createTRPCClient, httpBatchLink, } from "@trpc/client"; import type { AppRouter } from "../gen/trpc.js"; const client = createTRPCClient({ links: [httpBatchLink({ url: "http://localhost:8080/trpc" })], }); const user = await client.user.getById.query({ id: "1" }); ``` -------------------------------- ### Install trpcgo Runtime and Code Generator Source: https://github.com/befabri/trpcgo/blob/main/README.md Instructions for adding the trpcgo runtime library to your Go module and installing the code generator using Go tool directives. ```bash # Add the runtime library to your Go module go get github.com/befabri/trpcgo@latest # Install the code generator (Go 1.26+ tool directive) # In your go.mod: tool github.com/befabri/trpcgo/cmd/trpcgo ``` -------------------------------- ### React Query Client Setup Source: https://github.com/befabri/trpcgo/blob/main/README.md Sets up the tRPC client for use with React Query. It defines the `trpc` instance and configures the client with appropriate links for handling different operation types (query, mutation, subscription). ```typescript // trpc.ts import { createTRPCReact, httpBatchLink, splitLink, unstable_httpSubscriptionLink, } from "@trpc/react-query"; import type { AppRouter } from "../gen/trpc.js"; export const trpc = createTRPCReact(); // main.tsx const trpcClient = trpc.createClient({ links: [ splitLink({ condition: (op) => op.type === "subscription", true: unstable_httpSubscriptionLink({ url: "/trpc", }), false: httpBatchLink({ url: "/trpc", }), }), ], }); ``` -------------------------------- ### Execute trpcgo CLI for Code Generation Source: https://context7.com/befabri/trpcgo/llms.txt Commands to install and run the trpcgo generator. Supports outputting TypeScript files, Zod schemas, watch mode, and directory targeting. ```bash go get github.com/befabri/trpcgo/cmd/trpcgo@latest trpcgo generate -o ./web/gen/trpc.ts --zod ./web/gen/zod.ts trpcgo generate -o ./web/gen/trpc.ts --zod ./web/gen/zod.ts -w trpcgo generate -dir ./cmd/server -o ../web/gen/trpc.ts ``` -------------------------------- ### Define API Types and Handlers in Go with trpcgo Source: https://github.com/befabri/trpcgo/blob/main/README.md Example of defining input/output structures, handlers, and setting up a tRPC router in Go using trpcgo. It includes generating TypeScript and Zod outputs. ```go //go:generate go tool trpcgo generate -o ../web/gen/trpc.ts --zod ../web/gen/zod.ts package main import ( "context" "github.com/befabri/trpcgo" ) type CreateUserInput struct { Name string `json:"name" validate:"required,min=1,max=100"` Email string `json:"email" validate:"required,email"` } type User struct { ID string `json:"id" tstype:",readonly"` Name string `json:"name"` Email string `json:"email"` } func CreateUser(ctx context.Context, input CreateUserInput) (User, error) { // your logic here return User{ID: "1", Name: input.Name, Email: input.Email}, nil } func main() { router := trpcgo.NewRouter( trpcgo.WithDev(true), trpcgo.WithTypeOutput("../web/gen/trpc.ts"), trpcgo.WithZodOutput("../web/gen/zod.ts"), ) defer router.Close() trpcgo.MustMutation(router, "user.create", CreateUser) http.ListenAndServe(":8080", router.Handler("/trpc")) } ``` -------------------------------- ### Perform Typed and Raw Server-Side Calls in trpcgo Source: https://github.com/befabri/trpcgo/blob/main/README.md This Go code shows how to invoke procedures from within the server using trpcgo. It includes examples of typed calls with automatic marshaling of input/output and raw calls that handle JSON bytes directly, both executing the full middleware chain. ```go // Typed call, input/output marshaled automatically user, err := trpcgo.Call[CreateUserInput, User](router, ctx, "user.create", input) // Raw call, JSON in, any out result, err := router.RawCall(ctx, path, jsonBytes) ``` -------------------------------- ### Generated TypeScript AppRouter Type Source: https://github.com/befabri/trpcgo/blob/main/README.md Example of the TypeScript `AppRouter` type generated by trpcgo, reflecting the Go API definitions for client-side usage. ```typescript export interface CreateUserInput { name: string; email: string; } export interface User { readonly id: string; name: string; email: string; } export type AppRouter = { /* ... structural types matching @trpc/client */ }; ``` -------------------------------- ### Generated Zod Schemas for Validation Source: https://github.com/befabri/trpcgo/blob/main/README.md Example of Zod validation schemas generated by trpcgo from Go `validate` tags, used for frontend data validation. ```typescript import { z } from "zod"; export const CreateUserInputSchema = z.object({ name: z.string().min(1).max(100), email: z.email(), }); ``` -------------------------------- ### Generate TypeScript and Zod Schemas with go:generate Source: https://github.com/befabri/trpcgo/blob/main/README.md Example of integrating trpcgo code generation into the Go build process using the `//go:generate` directive. This ensures types are generated before compilation. ```go //go:generate go tool trpcgo generate -o ../web/gen/trpc.ts --zod ../web/gen/zod.ts ``` -------------------------------- ### Implement Untyped Output Validation and Parsing in trpcgo Source: https://github.com/befabri/trpcgo/blob/main/README.md This Go example shows how to use untyped `WithOutputValidator` and `WithOutputParser` methods on a reusable procedure builder in trpcgo. This approach is useful for applying common validation or transformation logic across multiple procedures. ```go // Untyped: useful on reusable builders authedProcedure := trpcgo.Procedure().Use(authMW). WithOutputValidator(func(v any) error { return nil }). WithOutputParser(func(v any) (any, error) { // validate or transform v return v, nil }) ``` -------------------------------- ### Create and Configure tRPC Router in Go Source: https://context7.com/befabri/trpcgo/llms.txt Demonstrates how to create a new tRPC router using `trpcgo.NewRouter` with various configuration options. This includes settings for request handling, validation, SSE subscriptions, development mode, error formatting, context injection, and code generation for TypeScript and Zod schemas. ```go package main import ( "context" "log" "net/http" "time" "github.com/befabri/trpcgo" "github.com/go-playground/validator/v10" ) func main() { validate := validator.New() router := trpcgo.NewRouter( // Request handling trpcgo.WithBatching(true), // Enable batch requests trpcgo.WithMethodOverride(true), // Allow POST for queries trpcgo.WithMaxBodySize(2 << 20), // 2MB request limit (default 1MB) trpcgo.WithMaxBatchSize(20), // Max procedures per batch (default 10) trpcgo.WithStrictInput(true), // Reject unknown JSON fields // Validation trpcgo.WithValidator(validate.Struct), // go-playground/validator compatible // SSE subscriptions trpcgo.WithSSEPingInterval(5 * time.Second), trpcgo.WithSSEMaxDuration(10 * time.Minute), // Default 30m, -1 for unlimited trpcgo.WithSSEMaxConnections(1000), // Concurrent SSE limit trpcgo.WithSSEReconnectAfterInactivity(30 * time.Second), // Development & errors trpcgo.WithDev(true), // Stack traces in error responses trpcgo.WithOnError(func(ctx context.Context, err *trpcgo.Error, path string) { log.Printf("error on %s: %v", path, err) }), trpcgo.WithErrorFormatter(func(input trpcgo.ErrorFormatterInput) any { return map[string]any{ "error": map[string]any{ "code": input.Shape.Error.Code, "message": input.Shape.Error.Message, "data": input.Shape.Error.Data, }, } }), // Context injection trpcgo.WithContextCreator(func(ctx context.Context, r *http.Request) context.Context { return context.WithValue(ctx, "auth", r.Header.Get("Authorization")) }), // Code generation (auto-regenerates on file save in dev mode) trpcgo.WithTypeOutput("../web/gen/trpc.ts"), trpcgo.WithZodOutput("../web/gen/zod.ts"), trpcgo.WithZodMini(false), // true for zod/mini syntax trpcgo.WithWatchPackages("./internal/...", "./cmd/api"), ) defer router.Close() // Stop file watcher on shutdown // Register procedures here... http.ListenAndServe(":8080", router.Handler("/trpc")) } ``` -------------------------------- ### Implement Global and Per-Procedure Middleware in trpcgo Source: https://context7.com/befabri/trpcgo/llms.txt Demonstrates how to define middleware functions for request timing, authentication, and rate limiting. Shows application of global middleware via the router and specific middleware chains for individual mutations and queries. ```go package main import ( "context" "log" "time" "github.com/befabri/trpcgo" ) func requestTimer(next trpcgo.HandlerFunc) trpcgo.HandlerFunc { return func(ctx context.Context, input any) (any, error) { meta, _ := trpcgo.GetProcedureMeta(ctx) start := time.Now() result, err := next(ctx, input) log.Printf("[%s] %s took %s", meta.Type, meta.Path, time.Since(start)) return result, err } } func authRequired(next trpcgo.HandlerFunc) trpcgo.HandlerFunc { return func(ctx context.Context, input any) (any, error) { token := ctx.Value("auth") if token == nil || token == "" { return nil, trpcgo.NewError(trpcgo.CodeUnauthorized, "authentication required") } return next(ctx, input) } } func rateLimiter(next trpcgo.HandlerFunc) trpcgo.HandlerFunc { return func(ctx context.Context, input any) (any, error) { return next(ctx, input) } } func main() { router := trpcgo.NewRouter() router.Use(requestTimer) trpcgo.MustMutation(router, "user.create", CreateUser, trpcgo.Use(authRequired, rateLimiter), trpcgo.WithMeta(map[string]string{"action": "write"}), ) trpcgo.MustQuery(router, "admin.stats", GetStats, trpcgo.Use(trpcgo.Chain(authRequired, rateLimiter)), ) } ``` -------------------------------- ### Configure tRPC Provider and Client Source: https://context7.com/befabri/trpcgo/llms.txt Sets up the QueryClient and tRPC client with link middleware, including support for HTTP batching and SSE subscriptions. Wraps the application in the necessary providers to enable data fetching. ```typescript import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; import { httpBatchLink, splitLink, unstable_httpSubscriptionLink } from "@trpc/client"; import { trpc } from "./trpc"; const queryClient = new QueryClient(); const trpcClient = trpc.createClient({ links: [ splitLink({ condition: (op) => op.type === "subscription", true: unstable_httpSubscriptionLink({ url: "/trpc" }), false: httpBatchLink({ url: "/trpc" }), }), ], }); function App() { return ( ); } ``` -------------------------------- ### Implement React Components with Queries and Mutations Source: https://context7.com/befabri/trpcgo/llms.txt Demonstrates usage of useQuery, useMutation, and useSubscription hooks within a React component. Types are automatically inferred from the Go backend definitions. ```typescript import { trpc } from "./trpc"; function UserList() { const users = trpc.user.listUsers.useQuery({ page: 1, perPage: 10 }); const createUser = trpc.user.createUser.useMutation(); trpc.user.onCreated.useSubscription(undefined, { onData: (user) => console.log("New user:", user), }); const handleCreate = () => { createUser.mutate({ name: "Alice", email: "alice@example.com", role: "viewer", }); }; return (
{users.data?.items.map((user) => (
{user.name}
))}
); } ``` -------------------------------- ### Initialize Vanilla tRPC Client Source: https://context7.com/befabri/trpcgo/llms.txt Configures a standalone tRPC client for use outside of React. Useful for Node.js scripts or non-React frontend frameworks. ```typescript import { createTRPCClient, httpBatchLink } from "@trpc/client"; import type { AppRouter } from "../gen/trpc.js"; const client = createTRPCClient({ links: [httpBatchLink({ url: "http://localhost:8080/trpc" })], }); const user = await client.user.getById.query({ id: "1" }); const newUser = await client.user.createUser.mutate({ name: "Bob", email: "bob@example.com" }); ``` -------------------------------- ### Register tRPC Query Procedures in Go Source: https://context7.com/befabri/trpcgo/llms.txt Illustrates how to register query procedures with a tRPC router in Go. It shows the usage of `trpcgo.MustQuery` and `trpcgo.Query` for procedures with input, and `trpcgo.MustVoidQuery` for procedures without input. The `Must*` variants panic on duplicate registration. ```go package main import ( "context" "github.com/befabri/trpcgo" ) type GetUserInput struct { ID string `json:"id" validate:"required"` } type User struct { ID string `json:"id" tstype:",readonly"` Name string `json:"name"` Email string `json:"email"` } type HealthInfo struct { OK bool `json:"ok"` Uptime string `json:"uptime"` } func GetUserById(ctx context.Context, input GetUserInput) (User, error) { // Database lookup... return User{ID: input.ID, Name: "Alice", Email: "alice@example.com"}, nil } func ServerHealth(ctx context.Context) (HealthInfo, error) { return HealthInfo{OK: true, Uptime: "24h"}, nil } func main() { router := trpcgo.NewRouter() // Query with input - panics on duplicate path trpcgo.MustQuery(router, "user.getById", GetUserById) // VoidQuery - no input required trpcgo.MustVoidQuery(router, "system.health", ServerHealth) // Non-Must variant returns error for handling if err := trpcgo.Query(router, "user.getByEmail", GetUserById); err != nil { log.Fatal(err) } } ``` -------------------------------- ### Accessing Procedure Metadata in Middleware (Go) Source: https://context7.com/befabri/trpcgo/llms.txt Demonstrates how to access procedure metadata within middleware using `GetProcedureMeta` for general metadata and `GetMeta[T]` for typed custom metadata. This allows middleware to inspect and act upon procedure details like path, type, and custom data. ```go package main import ( "context" "log" "github.com/befabri/trpcgo" ) type auditMeta struct { Action string Resource string } func auditLogger(next trpcgo.HandlerFunc) trpcgo.HandlerFunc { return func(ctx context.Context, input any) (any, error) { // Get procedure metadata meta, ok := trpcgo.GetProcedureMeta(ctx) if ok { log.Printf("Procedure: %s (type: %s)", meta.Path, meta.Type) // meta.Path = "user.create" // meta.Type = "mutation" // meta.Meta = any (your custom metadata) } // Get typed metadata using generics audit, ok := trpcgo.GetMeta[auditMeta](ctx) if ok { log.Printf("Audit: %s on %s", audit.Action, audit.Resource) } return next(ctx, input) } } func main() { router := trpcgo.NewRouter() router.Use(auditLogger) trpcgo.MustMutation(router, "user.create", createUser, trpcgo.WithMeta(auditMeta{Action: "create", Resource: "user"}), ) } ``` -------------------------------- ### Run go generate Source: https://github.com/befabri/trpcgo/blob/main/README.md Command to execute all `//go:generate` directives within the current module and its subdirectories. ```bash go generate ./... ``` -------------------------------- ### Registering tRPC Procedures in Go Source: https://github.com/befabri/trpcgo/blob/main/README.md Demonstrates how to register queries, mutations, and subscriptions using Must* variants for bootstrapping or standard variants for error handling. These functions define the core API endpoints for the tRPC router. ```go trpcgo.MustQuery(router, "user.getById", func(ctx context.Context, input GetUserInput) (User, error) { return db.FindUser(input.ID) }) trpcgo.MustVoidQuery(router, "system.health", func(ctx context.Context) (HealthInfo, error) { return HealthInfo{OK: true}, nil }) trpcgo.MustMutation(router, "user.create", func(ctx context.Context, input CreateUserInput) (User, error) { return db.CreateUser(input) }) trpcgo.MustVoidMutation(router, "system.reset", func(ctx context.Context) (string, error) { return "done", nil }) trpcgo.MustSubscribe(router, "chat.messages", func(ctx context.Context, input RoomInput) (<-chan Message, error) { ch := make(chan Message) return ch, nil }) trpcgo.MustVoidSubscribe(router, "user.onCreated", func(ctx context.Context) (<-chan User, error) { ch := make(chan User) return ch, nil }) if err := trpcgo.Query(router, "user.getById", handler); err != nil { log.Fatal(err) } ``` -------------------------------- ### Apply Middleware to Specific Procedures in trpcgo Source: https://github.com/befabri/trpcgo/blob/main/README.md This snippet demonstrates how to apply middleware like authentication and rate limiting to individual procedures using trpcgo. It shows the use of `trpcgo.Use` for middleware and `trpcgo.WithMeta` for procedure-specific metadata. ```go trpcgo.MustMutation(router, "user.create", handler, trpcgo.Use(authRequired, rateLimiter), trpcgo.WithMeta(map[string]string{"action": "write"}), ) ``` -------------------------------- ### Create Reusable Procedures with ProcedureBuilder Source: https://context7.com/befabri/trpcgo/llms.txt Explains the use of ProcedureBuilder to create immutable, reusable procedure templates. This allows for inheritance of middleware and metadata across multiple route registrations. ```go package main import ( "context" "github.com/befabri/trpcgo" ) type roleMeta struct { Admin bool } func main() { router := trpcgo.NewRouter() publicProcedure := trpcgo.Procedure() authedProcedure := publicProcedure.Use(authMiddleware) adminProcedure := authedProcedure.Use(adminCheckMiddleware).WithMeta(roleMeta{Admin: true}) orgProcedure := trpcgo.Procedure(authedProcedure).Use(orgScopeMiddleware) trpcgo.MustQuery(router, "user.list", listUsers, authedProcedure) trpcgo.MustMutation(router, "admin.ban", banUser, adminProcedure) trpcgo.MustQuery(router, "org.members", listOrgMembers, orgProcedure) } ``` -------------------------------- ### Router Merging in Go Source: https://github.com/befabri/trpcgo/blob/main/README.md Illustrates how to split tRPC procedures into different routers and then merge them into a single main router. This is useful for organizing larger applications. ```go userRouter := trpcgo.NewRouter() trpcgo.MustQuery(userRouter, "user.list", listUsers) adminRouter := trpcgo.NewRouter() trpcgo.MustMutation(adminRouter, "admin.ban", banUser) router := trpcgo.NewRouter() if err := router.Merge(userRouter, adminRouter); err != nil { log.Fatal(err) // duplicate procedure path } // or: router, err := trpcgo.MergeRouters(userRouter, adminRouter) ``` -------------------------------- ### Initialize tRPC React hooks Source: https://context7.com/befabri/trpcgo/llms.txt Creates the tRPC React context using the generated AppRouter type. This is the entry point for accessing type-safe hooks in React components. ```typescript import { createTRPCReact } from "@trpc/react-query"; import type { AppRouter } from "../gen/trpc.js"; export const trpc = createTRPCReact(); ``` -------------------------------- ### Using trpcgo with @trpc/client in TypeScript Source: https://github.com/befabri/trpcgo/blob/main/README.md Demonstrates how to use the generated `AppRouter` type with `@trpc/client` and `@trpc/react-query` for fully type-safe API calls from the frontend. ```typescript import { createTRPCReact } from "@trpc/react-query"; import type { AppRouter } from "../gen/trpc.js"; export const trpc = createTRPCReact(); // Fully typed: input and output inferred from Go types const mutation = trpc.user.create.useMutation(); mutation.mutate({ name: "Alice", email: "alice@example.com" }); ``` -------------------------------- ### Creating Reusable Base Procedures Source: https://github.com/befabri/trpcgo/blob/main/README.md Shows how to create immutable procedure builders to bundle middleware and metadata. This pattern allows for clean, composable API definitions across different service layers. ```go publicProcedure := trpcgo.Procedure() authedProcedure := publicProcedure.Use(authMiddleware) adminProcedure := authedProcedure.Use(adminCheckMiddleware).WithMeta(roleMeta{Admin: true}) trpcgo.MustQuery(router, "user.list", listUsers, authedProcedure) trpcgo.MustMutation(router, "user.create", createUser, authedProcedure) trpcgo.MustMutation(router, "admin.ban", banUser, adminProcedure) trpcgo.MustQuery(router, "report.get", getReport, authedProcedure, trpcgo.WithMeta(auditLog{})) orgProcedure := trpcgo.Procedure(authedProcedure).Use(orgScopeMiddleware) ``` -------------------------------- ### Automate Generation with go:generate Source: https://context7.com/befabri/trpcgo/llms.txt Integrates the trpcgo generator into the Go build process using the go:generate directive. ```go //go:generate go tool trpcgo generate -o ../web/gen/trpc.ts --zod ../web/gen/zod.ts package main func main() { // Run: go generate ./... } ``` -------------------------------- ### Organize and Merge Routers in Go Source: https://context7.com/befabri/trpcgo/llms.txt Provides patterns for splitting API procedures into domain-specific routers and combining them into a single main router. This is essential for maintaining clean codebases in large-scale applications. ```go func main() { userRouter := createUserRouter() adminRouter := createAdminRouter() mainRouter := trpcgo.NewRouter( trpcgo.WithBatching(true), trpcgo.WithDev(true), ) if err := mainRouter.Merge(userRouter, adminRouter); err != nil { log.Fatal(err) } combined, err := trpcgo.MergeRouters(userRouter, adminRouter) if err != nil { log.Fatal(err) } } ``` -------------------------------- ### Registering Subscription Procedures (SSE) in Go Source: https://context7.com/befabri/trpcgo/llms.txt Registers real-time streaming procedures using Server-Sent Events (SSE) with trpcgo. Handlers return a channel that emits values, and closing the channel signals the end of the stream. Supports subscriptions with and without input. ```go package main import ( "context" "github.com/befabri/trpcgo" "time" ) type RoomInput struct { RoomID string `json:"roomId" validate:"required" LastEventId string `json:"lastEventId,omitempty"` // For reconnection } type Message struct { ID string `json:"id" Content string `json:"content" Author string `json:"author" } type User struct { ID string `json:"id" Name string `json:"name" } // Subscribe with input - chat room messages func SubscribeMessages(ctx context.Context, input RoomInput) (<-chan Message, error) { ch := make(chan Message, 10) go func() { defer close(ch) // Stream messages until context is cancelled (client disconnect) for { select { case <-ctx.Done(): return default: // Push messages from your message source // ch <- Message{ID: "1", Content: "Hello", Author: "Alice"} } } }() return ch, nil } // VoidSubscribe - no input, streams all new users func OnUserCreated(ctx context.Context) (<-chan User, error) { ch := make(chan User, 8) go func() { <-ctx.Done() close(ch) }() // Register ch with your broadcast system return ch, nil } func main() { router := trpcgo.NewRouter( trpcgo.WithSSEPingInterval(5 * time.Second), trpcgo.WithSSEMaxDuration(10 * time.Minute), trpcgo.WithSSEMaxConnections(1000), ) trpcgo.MustSubscribe(router, "chat.messages", SubscribeMessages) trpcgo.MustVoidSubscribe(router, "user.onCreated", OnUserCreated) } ``` -------------------------------- ### Calling Procedures from Server-Side Go Code (Go) Source: https://context7.com/befabri/trpcgo/llms.txt Explains how to invoke tRPC procedures directly from within Go code using `Call` for typed operations and `RawCall` for untyped operations. Both methods execute the full middleware chain without relying on HTTP transport. ```go package main import ( "context" "encoding/json" "github.com/befabri/trpcgo" ) type CreateUserInput struct { Name string `json:"name"` Email string `json:"email"` } type User struct { ID string `json:"id"` Name string `json:"name"` Email string `json:"email"` } func SeedDatabase(router *trpcgo.Router, ctx context.Context) error { // Typed call - input/output marshaled automatically user, err := trpcgo.Call[CreateUserInput, User]( router, ctx, "user.create", CreateUserInput{Name: "Alice", Email: "alice@example.com"}, ) if err != nil { return err } log.Printf("Created user: %+v", user) // Raw call - JSON input, any output jsonInput, _ := json.Marshal(map[string]string{"id": user.ID}) result, err := router.RawCall(ctx, "user.getById", jsonInput) if err != nil { return err } log.Printf("Fetched user: %+v", result) return nil } func main() { router := trpcgo.NewRouter() // Register procedures... ctx := context.Background() if err := SeedDatabase(router, ctx); err != nil { log.Fatal(err) } } ``` -------------------------------- ### Validate and Parse Handler Outputs in Go Source: https://context7.com/befabri/trpcgo/llms.txt Demonstrates how to use OutputValidator to enforce data integrity without changing types, and OutputParser to transform internal data structures into public-facing formats. These tools ensure sensitive fields are stripped and data meets specific requirements before reaching the client. ```go package main import ( "context" "errors" "github.com/befabri/trpcgo" ) type User struct { ID string `json:"id"` Name string `json:"name"` Email string `json:"email"` PasswordHash string `json:"passwordHash,omitempty"` } type PublicUser struct { ID string `json:"id"` Name string `json:"name"` Email string `json:"email"` } func GetUser(ctx context.Context, input GetUserInput) (User, error) { return User{ ID: input.ID, Name: "Alice", Email: "alice@example.com", PasswordHash: "secret_hash_never_expose", }, nil } func main() { router := trpcgo.NewRouter() trpcgo.MustQuery(router, "user.get", GetUser, trpcgo.OutputValidator(func(u User) error { if u.ID == "" { return errors.New("user ID cannot be empty") } return nil }), ) trpcgo.MustQuery(router, "user.getPublic", GetUser, trpcgo.OutputParser(func(u User) (PublicUser, error) { return PublicUser{ ID: u.ID, Name: u.Name, Email: u.Email, }, nil }), ) } ``` -------------------------------- ### Configuring the tRPC Router Source: https://github.com/befabri/trpcgo/blob/main/README.md Configures the tRPC router with options for batching, validation, SSE settings, error formatting, and code generation paths for TypeScript and Zod schemas. ```go router := trpcgo.NewRouter( trpcgo.WithBatching(true), trpcgo.WithMethodOverride(true), trpcgo.WithMaxBodySize(2 << 20), trpcgo.WithValidator(validate.Struct), trpcgo.WithSSEPingInterval(5 * time.Second), trpcgo.WithSSEMaxDuration(10 * time.Minute), trpcgo.WithSSEMaxConnections(1000), trpcgo.WithSSEReconnectAfterInactivity(30 * time.Second), trpcgo.WithDev(true), trpcgo.WithOnError(func(ctx context.Context, err *trpcgo.Error, path string) { log.Printf("error on %s: %v", path, err) }), trpcgo.WithErrorFormatter(func(input trpcgo.ErrorFormatterInput) any { return map[string]any{ "error": map[string]any{ "code": input.Shape.Error.Code, "message": input.Shape.Error.Message, "data": input.Shape.Error.Data, }, } }), trpcgo.WithContextCreator(func(r *http.Request) context.Context { return context.WithValue(r.Context(), authKey, r.Header.Get("Authorization")) }), trpcgo.WithTypeOutput("../web/gen/trpc.ts"), trpcgo.WithZodOutput("../web/gen/zod.ts"), trpcgo.WithZodMini(false), trpcgo.WithWatchPackages("./internal/...", "./cmd/api"), ) ``` -------------------------------- ### Implement Typed Output Parsing and Transformation in trpcgo Source: https://github.com/befabri/trpcgo/blob/main/README.md This Go code demonstrates using `trpcgo.OutputParser` for both validating and transforming procedure output. It shows how to return a modified type or a subset of the original data, ensuring the client receives data in the desired format. ```go // Typed: validate or transform the output trpcgo.MustQuery(router, "user.get", getUser, trpcgo.OutputParser(func(u User) (User, error) { if u.ID == "" { return User{}, errors.New("id required") } return u, nil }), ) // Typed — transform (strip sensitive fields before sending to client) type PublicUser struct { ID string `json:"id"` } trpcgo.MustQuery(router, "user.get", getUser, trpcgo.OutputParser(func(u User) (PublicUser, error) { return PublicUser{ID: u.ID}, nil }), ) ``` -------------------------------- ### Configure Go Struct Tags for TypeScript and Zod Generation Source: https://context7.com/befabri/trpcgo/llms.txt Demonstrates how to use struct tags to define JSON serialization, TypeScript type overrides, and Zod validation rules. These tags enable the trpcgo generator to produce accurate frontend types and validation schemas. ```go type User struct { ID string `json:"id"` Name string `json:"name"` Bio string `json:"bio,omitempty"` CreatedAt string `json:"createdAt" tstype:",readonly"` Prefs any `json:"prefs" tstype:"Record"` Internal string `json:"internal" tstype:"-"` Email string `json:"email" tstype:",required"` Username string `json:"username" validate:"required,min=3,max=20"` Age int `json:"age" validate:"gte=18,lte=150"` Role string `json:"role" validate:"oneof=admin editor viewer"` Tags []string `json:"tags" validate:"min=1,dive,min=1,max=50"` URL string `json:"url" validate:"url"` UUID string `json:"uuid" validate:"uuid"` PasswordHash string `json:"-"` } ``` -------------------------------- ### Manage HTTP Cookies and Headers in Go Source: https://context7.com/befabri/trpcgo/llms.txt Shows how to manipulate HTTP response metadata using SetCookie and SetResponseHeader within trpcgo handlers. It also demonstrates how to inspect these values using WithResponseMetadata and GetResponse helpers. ```go func Login(ctx context.Context, input LoginInput) (LoginResult, error) { userID := "user_123" token := "jwt_token_here" trpcgo.SetCookie(ctx, &http.Cookie{ Name: "auth_token", Value: token, Path: "/", HttpOnly: true, Secure: true, SameSite: http.SameSiteStrictMode, Expires: time.Now().Add(24 * time.Hour), }) trpcgo.SetResponseHeader(ctx, "X-Request-ID", "req_abc123") trpcgo.SetResponseHeader(ctx, "X-User-ID", userID) return LoginResult{UserID: userID}, nil } ``` -------------------------------- ### Create and Wrap Errors in trpcgo Source: https://github.com/befabri/trpcgo/blob/main/README.md This Go snippet illustrates how to create and wrap errors in trpcgo using predefined tRPC error codes. It demonstrates `trpcgo.NewError`, `trpcgo.NewErrorf` for formatted errors, and `trpcgo.WrapError` for wrapping existing errors, all mapping to standard HTTP status codes. ```go // Create errors with tRPC error codes trpcgo.NewError(trpcgo.CodeNotFound, "user not found") trpcgo.NewErrorf(trpcgo.CodeBadRequest, "invalid id: %s", id) trpcgo.WrapError(trpcgo.CodeInternalServerError, "db failed", err) ``` -------------------------------- ### Registering Mutation Procedures in Go Source: https://context7.com/befabri/trpcgo/llms.txt Registers write operations using HTTP POST with trpcgo. Supports mutations with and without input, and ensures operations are registered safely. Uses MustMutation and MustVoidMutation for guaranteed registration. ```go package main import ( "context" "fmt" "github.com/befabri/trpcgo" ) type CreateUserInput struct { Name string `json:"name" validate:"required,min=1,max=100" Email string `json:"email" validate:"required,email" Role string `json:"role,omitempty" validate:"omitempty,oneof=admin editor viewer" } type User struct { ID string `json:"id" tstype:",readonly" Name string `json:"name" Email string `json:"email" Role string `json:"role" } type ResetResult struct { Message string `json:"message" UserCount int `json:"userCount" } var nextID = 1 func CreateUser(ctx context.Context, input CreateUserInput) (User, error) { nextID++ role := input.Role if role == "" { role = "viewer" } return User{ ID: fmt.Sprintf("%d", nextID), Name: input.Name, Email: input.Email, Role: role, }, nil } func ResetDemo(ctx context.Context) (ResetResult, error) { nextID = 0 return ResetResult{Message: "Demo reset complete", UserCount: 0}, nil } func main() { router := trpcgo.NewRouter() // Mutation with input trpcgo.MustMutation(router, "user.create", CreateUser) // VoidMutation - no input required trpcgo.MustVoidMutation(router, "system.reset", ResetDemo) } ``` -------------------------------- ### Implementing Global Middleware Source: https://github.com/befabri/trpcgo/blob/main/README.md Defines a global middleware function that intercepts requests to log execution time and procedure metadata. ```go router.Use(func(next trpcgo.HandlerFunc) trpcgo.HandlerFunc { return func(ctx context.Context, input any) (any, error) { meta, _ := trpcgo.GetProcedureMeta(ctx) start := time.Now() result, err := next(ctx, input) log.Printf("[%s] %s took %s", meta.Type, meta.Path, time.Since(start)) return result, err } }) ``` -------------------------------- ### Access Procedure Metadata within trpcgo Middleware Source: https://github.com/befabri/trpcgo/blob/main/README.md This Go code defines an authentication middleware for trpcgo. It shows how to access procedure metadata, such as path, type, and custom meta information, from the context within a middleware function using `trpcgo.GetProcedureMeta`. ```go func authRequired(next trpcgo.HandlerFunc) trpcgo.HandlerFunc { return func(ctx context.Context, input any) (any, error) { meta, _ := trpcgo.GetProcedureMeta(ctx) // meta.Path = "user.create" // meta.Type = "mutation" // meta.Meta = map[string]string{"action": "write"} return next(ctx, input) } } ``` -------------------------------- ### Creating tRPC Errors with JSON-RPC 2.0 Codes (Go) Source: https://context7.com/befabri/trpcgo/llms.txt Illustrates how to create and handle errors in tRPC services using standard JSON-RPC 2.0 error codes. Functions like `NewError`, `NewErrorf`, and `WrapError` are used to generate errors with appropriate codes and messages, which map to HTTP status codes. ```go package main import ( "context" "database/sql" "errors" "github.com/befabri/trpcgo" ) type GetUserInput struct { ID string `json:"id"` } type User struct { ID string `json:"id"` Name string `json:"name"` } func GetUser(ctx context.Context, input GetUserInput) (User, error) { if input.ID == "" { // Simple error with code and message return User{}, trpcgo.NewError(trpcgo.CodeBadRequest, "user ID required") } user, err := findUserInDB(input.ID) if err != nil { if errors.Is(err, sql.ErrNoRows) { // Formatted error message return User{}, trpcgo.NewErrorf(trpcgo.CodeNotFound, "user %q not found", input.ID) } // Wrap underlying error (cause accessible via Unwrap) return User{}, trpcgo.WrapError(trpcgo.CodeInternalServerError, "database error", err) } return user, nil } // Available error codes (map to HTTP status codes): // trpcgo.CodeParseError -32700 (400) // trpcgo.CodeBadRequest -32600 (400) // trpcgo.CodeInternalServerError -32603 (500) // trpcgo.CodeUnauthorized -32001 (401) // trpcgo.CodeForbidden -32003 (403) // trpcgo.CodeNotFound -32004 (404) // trpcgo.CodeMethodNotSupported -32005 (405) // trpcgo.CodeTimeout -32008 (408) // trpcgo.CodeConflict -32009 (409) // trpcgo.CodePreconditionFailed -32012 (412) // trpcgo.CodePayloadTooLarge -32013 (413) // trpcgo.CodeTooManyRequests -32029 (429) // trpcgo.CodeServiceUnavailable -32503 (503) ``` -------------------------------- ### trpcgo Generate CLI Command Source: https://github.com/befabri/trpcgo/blob/main/README.md The primary command for generating TypeScript types and Zod schemas from Go code. It supports various flags for output customization, watch mode, and Zod schema generation. ```bash trpcgo generate [flags] [packages] ``` -------------------------------- ### trpcgo Generate with Watch Mode Source: https://github.com/befabri/trpcgo/blob/main/README.md Enables watch mode for the trpcgo generate command. This automatically regenerates TypeScript types and Zod schemas when Go source files change. ```bash go tool trpcgo generate -o ../web/gen/trpc.ts --zod ../web/gen/zod.ts -w ``` -------------------------------- ### Define Input Validation with `validate` Tags in Go Source: https://github.com/befabri/trpcgo/blob/main/README.md This Go struct uses `validate` tags from the `go-playground/validator` library to define input validation rules. These tags generate both server-side validation logic and corresponding Zod schemas for client-side validation, covering required fields, lengths, formats, and ranges. ```go type Input struct { Name string `json:"name" validate:"required,min=1,max=100"` // z.string().min(1).max(100) Email string `json:"email" validate:"required,email"` // z.email() Role string `json:"role" validate:"oneof=admin editor viewer"` // z.enum([...]) Tags []string `json:"tags" validate:"min=1,dive,min=1,max=50"` // z.array(z.string().min(1).max(50)).min(1) Age int `json:"age" validate:"gte=18,lte=150"` // z.int().gte(18).lte(150) URL string `json:"url" validate:"url"` // z.url() UUID string `json:"uuid" validate:"uuid"` // z.uuidv4() } ``` -------------------------------- ### Map Struct Fields for JSON using `json` Tags in Go Source: https://github.com/befabri/trpcgo/blob/main/README.md This Go struct definition uses standard `json` tags to control how struct fields are serialized and deserialized as JSON. It covers basic field mapping and marking fields as optional using `omitempty`. ```go type User struct { ID string `json:"id"` Name string `json:"name"` Bio string `json:"bio,omitempty"` // optional in TypeScript } ``` -------------------------------- ### Using TrackedEvent for SSE Reconnection in Go Source: https://context7.com/befabri/trpcgo/llms.txt Implements SSE reconnection support in trpcgo by wrapping streamed values with `TrackedEvent`. Clients can send `lastEventId` to resume streams from the correct position upon reconnection. This ensures data continuity. ```go package main import ( "context" "fmt" "github.com/befabri/trpcgo" ) type StreamInput struct { LastEventId string `json:"lastEventId,omitempty" } type Update struct { Sequence int `json:"sequence" Data string `json:"data" } func StreamUpdates(ctx context.Context, input StreamInput) (<-chan trpcgo.TrackedEvent[Update], error) { ch := make(chan trpcgo.TrackedEvent[Update], 10) // Parse lastEventId to resume from correct position startSeq := 0 if input.LastEventId != "" { fmt.Sscanf(input.LastEventId, "%d", &startSeq) } go func() { defer close(ch) seq := startSeq for { select { case <-ctx.Done(): return default: seq++ // Wrap with Tracked to include event ID for reconnection ch <- trpcgo.Tracked( fmt.Sprintf("%d", seq), Update{Sequence: seq, Data: "update data"}, ) } } }() return ch, nil } func main() { router := trpcgo.NewRouter() trpcgo.MustSubscribe(router, "updates.stream", StreamUpdates) } ``` -------------------------------- ### Override TypeScript Generation with `tstype` Tags in Go Source: https://github.com/befabri/trpcgo/blob/main/README.md This Go struct demonstrates the use of `tstype` tags to customize TypeScript type generation. It shows how to specify readonly properties, map to complex TypeScript types like `Record`, exclude fields entirely, and enforce required fields. ```go type User struct { ID string `json:"id" tstype:",readonly"` // readonly id: string Preferences map[string]any `json:"prefs" tstype:"Record"` Internal string `json:"internal" tstype:"-"` // excluded from TS Email string `json:"email" tstype:",required"` // never optional } ``` -------------------------------- ### Implement Typed Output Validation in trpcgo Source: https://github.com/befabri/trpcgo/blob/main/README.md This Go snippet shows how to use `trpcgo.OutputValidator` to validate the output of a procedure without changing its type. The validator function receives the output and returns an error if validation fails, ensuring data integrity before it's sent to the client. ```go // Typed: validate only trpcgo.MustQuery(router, "user.get", getUser, trpcgo.OutputValidator(func(u User) error { if u.ID == "" { return errors.New("id required") } return nil }), ) ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.