or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.mdisomorphic-functions.mdmiddleware.mdrequest-response.mdrpc-system.mdserver-functions.mdserver-utilities.mdssr-components.mdvite-plugin.md

middleware.mddocs/

0

# Middleware

1

2

The middleware system provides composable functions for server functions to handle validation, authentication, logging, and other cross-cutting concerns. Middleware can be chained together and applied to server functions for enhanced functionality.

3

4

## Capabilities

5

6

### Create Middleware

7

8

Creates middleware that can be applied to server functions for request/response processing.

9

10

```typescript { .api }

11

/**

12

* Creates middleware with optional configuration

13

* @param options - Configuration options including middleware type

14

* @returns CreateMiddlewareResult for chaining additional configuration

15

*/

16

function createMiddleware<TType extends MiddlewareType>(

17

options?: { type?: TType }

18

): CreateMiddlewareResult<{}, TType>;

19

20

interface CreateMiddlewareResult<TRegister, TType> {

21

/** Add middleware function to the chain */

22

middleware<T>(middleware: T): CreateMiddlewareResult<TRegister & T, TType>;

23

24

/** Add input validation to the middleware */

25

inputValidator<T>(validator: T): CreateMiddlewareResult<TRegister & T, TType>;

26

27

/** Add client-side processing */

28

client<T>(client: T): CreateMiddlewareResult<TRegister & T, TType>;

29

30

/** Add server-side processing */

31

server<T>(server: T): CreateMiddlewareResult<TRegister & T, TType>;

32

}

33

34

type MiddlewareType = 'request' | 'function';

35

```

36

37

**Usage Examples:**

38

39

```typescript

40

import { createMiddleware, createServerFn } from "@tanstack/react-start";

41

42

// Authentication middleware

43

const authMiddleware = createMiddleware()

44

.server(async (input, { request }) => {

45

const token = request.headers.get('Authorization');

46

if (!token) throw new Error('Unauthorized');

47

48

const user = await verifyToken(token);

49

return { ...input, user };

50

});

51

52

// Validation middleware

53

const validateUserInput = createMiddleware()

54

.inputValidator((data: unknown) => {

55

if (!data || typeof data !== 'object') {

56

throw new Error('Invalid input');

57

}

58

return data as { name: string; email: string };

59

});

60

61

// Apply middleware to server function

62

const createUser = createServerFn({ method: 'POST' })

63

.middleware(authMiddleware)

64

.middleware(validateUserInput)

65

.handler(async ({ name, email, user }) => {

66

// Handler receives validated input + auth context

67

return await db.user.create({

68

data: { name, email, createdBy: user.id }

69

});

70

});

71

```

72

73

### Function Middleware

74

75

Middleware specifically designed for server functions with type-safe parameter passing.

76

77

```typescript { .api }

78

interface FunctionMiddleware<TInput, TOutput, TContext = {}> {

79

(input: TInput, context: FunctionMiddlewareContext<TContext>):

80

Promise<TOutput> | TOutput;

81

}

82

83

interface FunctionMiddlewareContext<T = {}> {

84

/** Current request object */

85

request: Request;

86

/** Response headers */

87

headers: Headers;

88

/** Additional context data */

89

context: T;

90

/** Continue to next middleware */

91

next: () => Promise<any>;

92

}

93

94

interface FunctionMiddlewareOptions<

95

TRegister,

96

TResponse,

97

TMiddlewares,

98

TInputValidator,

99

THandler

100

> {

101

middleware?: TMiddlewares;

102

inputValidator?: TInputValidator;

103

handler?: THandler;

104

}

105

```

106

107

**Usage Examples:**

108

109

```typescript

110

import { createMiddleware } from "@tanstack/react-start";

111

112

// Logging middleware

113

const logMiddleware = createMiddleware()

114

.server(async (input, { request, next }) => {

115

console.log(`[${new Date().toISOString()}] ${request.method} ${request.url}`);

116

const start = Date.now();

117

118

const result = await next();

119

120

console.log(`Request completed in ${Date.now() - start}ms`);

121

return result;

122

});

123

124

// Rate limiting middleware

125

const rateLimitMiddleware = createMiddleware()

126

.server(async (input, { request, next }) => {

127

const ip = request.headers.get('x-forwarded-for') || 'unknown';

128

const key = `rate-limit:${ip}`;

129

130

const requests = await redis.incr(key);

131

if (requests === 1) {

132

await redis.expire(key, 60); // 1 minute window

133

}

134

135

if (requests > 100) {

136

throw new Error('Rate limit exceeded');

137

}

138

139

return await next();

140

});

141

```

142

143

### Request Middleware

144

145

Middleware that operates at the request level before server functions are invoked.

146

147

```typescript { .api }

148

interface RequestMiddleware<TContext = {}> {

149

(request: Request, context: RequestMiddlewareContext<TContext>):

150

Promise<Response | void> | Response | void;

151

}

152

153

interface RequestMiddlewareContext<T = {}> {

154

/** Additional context data */

155

context: T;

156

/** Continue to next middleware */

157

next: () => Promise<Response>;

158

}

159

160

interface RequestMiddlewareOptions<

161

TRegister,

162

TMiddlewares,

163

TServer

164

> {

165

type: 'request';

166

middleware?: TMiddlewares;

167

server?: TServer;

168

}

169

```

170

171

### Middleware Utilities

172

173

Helper functions for working with middleware chains and validation.

174

175

```typescript { .api }

176

/**

177

* Flattens nested middleware arrays into a single array

178

* @param middlewares - Array of middleware to flatten

179

* @returns Flattened middleware array

180

*/

181

function flattenMiddlewares(

182

middlewares: AnyFunctionMiddleware[]

183

): AnyFunctionMiddleware[];

184

185

/**

186

* Executes a middleware chain

187

* @param middlewares - The middleware chain to execute

188

* @param context - The execution context

189

* @returns Result of middleware execution

190

*/

191

function executeMiddleware<T>(

192

middlewares: AnyFunctionMiddleware[],

193

context: T

194

): Promise<T>;

195

196

/**

197

* Apply middleware to a function

198

* @param middleware - The middleware to apply

199

* @param fn - The function to wrap with middleware

200

* @returns Enhanced function with middleware

201

*/

202

function applyMiddleware<T>(

203

middleware: AnyFunctionMiddleware[],

204

fn: T

205

): T;

206

207

/**

208

* Execute validation logic

209

* @param validator - The validator to execute

210

* @param input - The input to validate

211

* @returns Validated output

212

*/

213

function execValidator<T, U>(

214

validator: Validator<T, U>,

215

input: T

216

): U;

217

```

218

219

### Middleware Composition

220

221

```typescript { .api }

222

interface IntersectAllValidatorInputs<T extends ReadonlyArray<any>> {

223

// Type helper for combining validator inputs

224

}

225

226

interface IntersectAllValidatorOutputs<T extends ReadonlyArray<any>> {

227

// Type helper for combining validator outputs

228

}

229

230

interface AssignAllMiddleware<T extends ReadonlyArray<any>> {

231

// Type helper for combining middleware types

232

}

233

```

234

235

## Advanced Patterns

236

237

### Conditional Middleware

238

239

```typescript

240

import { createMiddleware } from "@tanstack/react-start";

241

242

const conditionalAuth = createMiddleware()

243

.server(async (input, { request, next }) => {

244

const publicPaths = ['/health', '/api/public'];

245

const path = new URL(request.url).pathname;

246

247

if (publicPaths.includes(path)) {

248

return await next();

249

}

250

251

// Apply authentication for protected paths

252

const token = request.headers.get('Authorization');

253

if (!token) throw new Error('Authentication required');

254

255

const user = await verifyToken(token);

256

return { ...input, user };

257

});

258

```

259

260

### Error Handling Middleware

261

262

```typescript

263

import { createMiddleware } from "@tanstack/react-start";

264

265

const errorHandlerMiddleware = createMiddleware()

266

.server(async (input, { next }) => {

267

try {

268

return await next();

269

} catch (error) {

270

console.error('Server function error:', error);

271

272

if (error.message === 'Unauthorized') {

273

throw new Response('Unauthorized', { status: 401 });

274

}

275

276

throw new Response('Internal Server Error', { status: 500 });

277

}

278

});

279

```

280

281

## Types

282

283

```typescript { .api }

284

// Middleware type definitions

285

type MiddlewareType = 'request' | 'function';

286

287

interface AnyFunctionMiddleware {

288

type: 'function';

289

middleware: (...args: any[]) => any;

290

}

291

292

interface AnyRequestMiddleware {

293

type: 'request';

294

middleware: (request: Request, context: any) => any;

295

}

296

297

// Function middleware types

298

interface FunctionMiddlewareWithTypes<

299

TRegister,

300

TResponse,

301

TMiddlewares,

302

TInputValidator,

303

THandler

304

> {

305

middleware?: TMiddlewares;

306

inputValidator?: TInputValidator;

307

handler?: THandler;

308

}

309

310

interface FunctionMiddlewareValidator<T, U> {

311

(input: T): U;

312

}

313

314

interface FunctionMiddlewareServer<TInput, TOutput> {

315

(input: TInput, context: ServerFnCtx): Promise<TOutput> | TOutput;

316

}

317

318

interface FunctionMiddlewareClient<TInput, TOutput> {

319

(input: TInput): Promise<TOutput> | TOutput;

320

}

321

322

// Request middleware types

323

interface RequestMiddlewareWithTypes<

324

TRegister,

325

TMiddlewares,

326

TServer

327

> {

328

type: 'request';

329

middleware?: TMiddlewares;

330

server?: TServer;

331

}

332

333

interface RequestServerFn<T> {

334

(request: Request, context: T): Promise<Response | void> | Response | void;

335

}

336

337

// Middleware context types

338

interface FunctionMiddlewareAfterMiddleware<T> {

339

context: T;

340

next: () => Promise<any>;

341

}

342

343

interface RequestMiddlewareAfterMiddleware<T> {

344

context: T;

345

next: () => Promise<Response>;

346

}

347

348

// Validator types

349

interface Validator<TInput, TOutput> {

350

(input: TInput): TOutput;

351

}

352

353

// Context assignment helpers

354

interface AssignAllClientContextBeforeNext<T extends ReadonlyArray<any>> {

355

// Type helper for client context assignment

356

}

357

358

interface FunctionClientResultWithContext<T, U> {

359

result: T;

360

context: U;

361

}

362

363

interface FunctionServerResultWithContext<T, U> {

364

result: T;

365

context: U;

366

}

367

```