0Pricing
tRPC End-to-End Type Safe APIs · 课时

创建 tRPC 上下文

理解如何创建并填充 tRPC 上下文对象,其中包含用户信息等请求特定数据。

创建 tRPC 上下文 是 CoddyKit 上的免费 tRPC End-to-End Type Safe APIs 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 tRPC End-to-End Type Safe APIs 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 tRPC End-to-End Type Safe APIs 课程共包含 4 节课。

本课时的部分内容尚未翻译,以英文显示。

What is tRPC Context?

Welcome! In tRPC, the context is a special object that's created for each incoming request to your server.

Think of it as a personalized backpack for every request. You can fill this backpack with any data that needs to be accessible by your tRPC procedures.

Why Use tRPC Context?

The tRPC context is incredibly useful for sharing request-specific data across all your API procedures. This prevents you from passing the same arguments repeatedly.

  • Authentication: Store authenticated user details.
  • Database Connections: Provide a database client for the current request.
  • Request-specific Data: Access headers, IP addresses, or other request info.
  • Logging: Attach a unique request ID for tracing.

Defining createContext

You define the context using a function, often named createContext. This function runs once for every incoming tRPC request.

It receives an object containing details about the incoming HTTP request (like headers) and should return the context object.

import { initTRPC } from '@trpc/server';

// This function runs on every request
function createContext(req: { headers: Record<string, string> }) {
  console.log('Context created for a new request!');
  return {
    // We'll add more here later!
  };
}

// We'll use this context to initialize tRPC
const t = initTRPC.context<ReturnType<typeof createContext>>().create();

console.log('tRPC initialized with context.');

Accessing Request Details

Inside your createContext function, you get access to the underlying HTTP request object. This allows you to extract information like request headers or query parameters.

Let's grab a custom header, for example.

import { initTRPC } from '@trpc/server';

function createContext(req: { headers: Record<string, string> }) {
  const userAgent = req.headers['user-agent'] || 'unknown';
  return {
    userAgent: userAgent
  };
}

type Context = ReturnType<typeof createContext>;
const t = initTRPC.context<Context>().create();

// Simulate a request
const mockRequest = {
  headers: { 'user-agent': 'CoddyKit-Browser' }
};

const ctx = createContext(mockRequest);
console.log('User Agent in context:', ctx.userAgent);

Populating Context with Custom Data

You can populate the context object with any data derived from the request. A common use case is adding a user's ID or a full user object after an authentication check.

For now, let's just add a dummy user ID based on a header.

import { initTRPC } from '@trpc/server';

function createContext(req: { headers: Record<string, string> }) {
  // In a real app, this would come from a JWT or session
  const userId = req.headers['x-user-id'] || 'guest_user';
  return {
    userId: userId,
    timestamp: new Date().toISOString()
  };
}

type Context = ReturnType<typeof createContext>;
const t = initTRPC.context<Context>().create();

// Simulate a request with a custom user ID header
const mockRequest = {
  headers: { 'x-user-id': 'coddykit_student_123' }
};

const ctx = createContext(mockRequest);
console.log('Context for request:', ctx);

Typing Your Context

TypeScript is tRPC's superpower! It's crucial to properly type your context object so tRPC can provide full end-to-end type safety.

You can infer the type of your context directly from your createContext function using ReturnType.

import { initTRPC } from '@trpc/server';

function createContext(req: { headers: Record<string, string> }) {
  const userId = req.headers['x-user-id'] || 'anonymous';
  return {
    userId: userId
  };
}

// Infer the Context type from createContext function
type Context = ReturnType<typeof createContext>;

// Now, when initializing tRPC, provide this type
const t = initTRPC.context<Context>().create();

console.log('Context type inferred and used!');
// Example of how TypeScript would see the context:
// const typedContext: Context = { userId: 'some_id' };

Using Context in Procedures

Once your context is defined and typed, any tRPC procedure can easily access it. Procedures receive an object with a ctx property, which holds your context object.

This makes user data, database clients, and other request-scoped data readily available.

import { initTRPC } from '@trpc/server';

function createContext(req: { headers: Record<string, string> }) {
  const userId = req.headers['x-user-id'] || 'guest';
  return { userId };
}

type Context = ReturnType<typeof createContext>;
const t = initTRPC.context<Context>().create();

const appRouter = t.router({
  whoAmI: t.procedure.query(({ ctx }) => {
    // Access userId directly from ctx
    return `Hello, ${ctx.userId}!`;
  }),
});

console.log('Procedure defined using context.');

Context in Action: Full Example

Here's a simplified full example showing how createContext is defined and how its data is used within a tRPC procedure.

The output simulates what the procedure would return if called with the mock request.

import { initTRPC } from '@trpc/server';

// 1. Define your context function
function createContext(req: { headers: Record<string, string> }) {
  const userId = req.headers['x-user-id'] || 'anonymous_user';
  return {
    userId: userId,
    requestTime: new Date().toLocaleTimeString()
  };
}

// 2. Infer the context type for type safety
type Context = ReturnType<typeof createContext>;

// 3. Initialize tRPC with the context type
const t = initTRPC.context<Context>().create();

// 4. Define a simple procedure that uses context
const appRouter = t.router({
  getUserGreeting: t.procedure.query(({ ctx }) => {
    return `Welcome back, ${ctx.userId}! Last accessed at: ${ctx.requestTime}.`;
  }),
});

// --- Simulate a request and context creation ---
const mockRequest = {
  headers: { 'x-user-id': 'CoddyKitUser' }
};

const contextForRequest = createContext(mockRequest);
console.log('Context created:', contextForRequest);

// Simulate the procedure call with the created context
const simulatedOutput = appRouter._def.procedures.getUserGreeting._def.query({ ctx: contextForRequest, input: undefined });
console.log('\nSimulated Procedure Output:');
console.log(simulatedOutput);

Context Best Practices

To keep your tRPC application performant and maintainable:

  • Keep it Lean: Only add data that's truly needed across multiple procedures.
  • Avoid Heavy Logic: Complex operations (like database queries for user data) might be better placed in middleware or services called from context.
  • Security: Always validate and sanitize any data extracted from the raw request before adding it to context.

Context Understanding Check

Let's check your understanding of tRPC context.

Recap: tRPC Context

You've learned about the powerful tRPC context!

  • It's an object created per-request.
  • It allows sharing data like user info or database clients across all procedures.
  • You define it with a createContext function.
  • Type safety is ensured by inferring its type and using it during tRPC initialization.
  • Procedures access context via the ctx parameter.

Next, you'll see how to use context to implement authentication with middleware!

常见问题解答

「创建 tRPC 上下文」课时是免费的吗?

是的 — 「创建 tRPC 上下文」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 tRPC End-to-End Type Safe APIs 课程的其余内容,请升级到 CoddyKit PRO。 tRPC End-to-End Type Safe APIs 课程共包含 4 节课。

「创建 tRPC 上下文」这节课中我会学到什么?

理解如何创建并填充 tRPC 上下文对象,其中包含用户信息等请求特定数据。 你通过在浏览器中直接运行的动手代码来练习 tRPC End-to-End Type Safe APIs,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 tRPC End-to-End Type Safe APIs 需要有经验吗?

无需任何先前经验。CoddyKit 上的 tRPC End-to-End Type Safe APIs 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。

「创建 tRPC 上下文」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 tRPC End-to-End Type Safe APIs 课中编写并运行代码吗?

能。每节 tRPC End-to-End Type Safe APIs 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 创建 tRPC 上下文
  2. 身份验证中间件
  3. 自定义中间件链
  4. 日志记录与性能计时中间件
← 返回 tRPC End-to-End Type Safe APIs