or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

advanced-features.mdclient-creation.mderror-handling.mdhttp-links.mdindex.mdutility-links.mdwebsocket-links.md

http-links.mddocs/

0

# HTTP Transport Links

1

2

HTTP-based transport mechanisms including standard HTTP, batching, and streaming capabilities for queries and mutations. These links handle communication with tRPC servers over HTTP protocols.

3

4

## Capabilities

5

6

### httpLink

7

8

Standard HTTP transport for individual queries and mutations. Each operation results in a separate HTTP request.

9

10

```typescript { .api }

11

/**

12

* Creates an HTTP transport link for individual requests

13

* @param opts - HTTP link configuration options

14

* @returns HTTP transport link for the client chain

15

*/

16

function httpLink<TRouter extends AnyRouter>(

17

opts: HTTPLinkOptions<TRouter['_def']['_config']['$types']>

18

): TRPCLink<TRouter>;

19

20

interface HTTPLinkOptions<TRoot extends AnyClientTypes> {

21

/** Server endpoint URL */

22

url: string | URL;

23

24

/** Static headers or function returning headers */

25

headers?: HTTPHeaders | ((opts: { op: Operation }) => HTTPHeaders | Promise<HTTPHeaders>);

26

27

/** Data transformation configuration */

28

transformer?: TRoot['transformer'];

29

30

/** Custom fetch implementation */

31

fetch?: FetchEsque;

32

33

/** Send all requests as POST regardless of procedure type */

34

methodOverride?: 'POST';

35

}

36

37

type HTTPHeaders = Record<string, string | string[]> | Headers;

38

```

39

40

**Usage Examples:**

41

42

```typescript

43

import { createTRPCClient, httpLink } from "@trpc/client";

44

45

// Basic HTTP link

46

const client = createTRPCClient<AppRouter>({

47

links: [

48

httpLink({

49

url: "http://localhost:3000/trpc",

50

}),

51

],

52

});

53

54

// HTTP link with authentication headers

55

const client = createTRPCClient<AppRouter>({

56

links: [

57

httpLink({

58

url: "http://localhost:3000/trpc",

59

headers: {

60

authorization: "Bearer " + getToken(),

61

},

62

}),

63

],

64

});

65

66

// Dynamic headers based on operation

67

const client = createTRPCClient<AppRouter>({

68

links: [

69

httpLink({

70

url: "http://localhost:3000/trpc",

71

headers: async ({ op }) => {

72

return {

73

authorization: await getAuthToken(),

74

"x-request-type": op.type,

75

"x-procedure-path": op.path,

76

};

77

},

78

}),

79

],

80

});

81

82

// Custom fetch implementation (Node.js)

83

const client = createTRPCClient<AppRouter>({

84

links: [

85

httpLink({

86

url: "http://localhost:3000/trpc",

87

fetch: fetch, // Node.js fetch polyfill

88

}),

89

],

90

});

91

```

92

93

### httpBatchLink

94

95

Batches multiple requests into single HTTP calls to reduce network overhead. Automatically groups operations and sends them together when possible.

96

97

```typescript { .api }

98

/**

99

* Creates an HTTP transport link that batches multiple requests

100

* @param opts - HTTP batch link configuration options

101

* @returns HTTP batch transport link for the client chain

102

*/

103

function httpBatchLink<TRouter extends AnyRouter>(

104

opts: HTTPBatchLinkOptions<TRouter['_def']['_config']['$types']>

105

): TRPCLink<TRouter>;

106

107

interface HTTPBatchLinkOptions<TRoot extends AnyClientTypes> {

108

/** Server endpoint URL */

109

url: string | URL;

110

111

/** Maximum URL length for batched requests */

112

maxURLLength?: number;

113

114

/** Maximum number of operations per batch */

115

maxItems?: number;

116

117

/** Static headers or batch-aware function returning headers */

118

headers?: HTTPHeaders | ((opts: { opList: NonEmptyArray<Operation> }) => HTTPHeaders | Promise<HTTPHeaders>);

119

120

/** Data transformation configuration */

121

transformer?: TRoot['transformer'];

122

123

/** Custom fetch implementation */

124

fetch?: FetchEsque;

125

126

/** Send all requests as POST regardless of procedure type */

127

methodOverride?: 'POST';

128

}

129

130

type NonEmptyArray<T> = [T, ...T[]];

131

```

132

133

**Usage Examples:**

134

135

```typescript

136

import { createTRPCClient, httpBatchLink } from "@trpc/client";

137

138

// Basic batch link

139

const client = createTRPCClient<AppRouter>({

140

links: [

141

httpBatchLink({

142

url: "http://localhost:3000/trpc",

143

}),

144

],

145

});

146

147

// Batch link with size limits

148

const client = createTRPCClient<AppRouter>({

149

links: [

150

httpBatchLink({

151

url: "http://localhost:3000/trpc",

152

maxURLLength: 2048, // Limit URL size

153

maxItems: 10, // Limit batch size

154

}),

155

],

156

});

157

158

// Batch-aware headers

159

const client = createTRPCClient<AppRouter>({

160

links: [

161

httpBatchLink({

162

url: "http://localhost:3000/trpc",

163

headers: ({ opList }) => ({

164

authorization: "Bearer " + getToken(),

165

"x-batch-size": opList.length.toString(),

166

"x-batch-operations": opList.map(op => op.path).join(","),

167

}),

168

}),

169

],

170

});

171

172

// Using the batched client (automatically batches concurrent calls)

173

const [user, posts, comments] = await Promise.all([

174

client.user.getById.query({ id: 1 }),

175

client.posts.getByUserId.query({ userId: 1 }),

176

client.comments.getByUserId.query({ userId: 1 }),

177

]);

178

```

179

180

### httpBatchStreamLink

181

182

Streaming batch transport using JSONL (JSON Lines) format for handling large batched responses efficiently.

183

184

```typescript { .api }

185

/**

186

* Creates a streaming HTTP batch link that handles responses as JSONL

187

* @param opts - HTTP batch stream link configuration options

188

* @returns Streaming HTTP batch transport link

189

*/

190

function httpBatchStreamLink<TRouter extends AnyRouter>(

191

opts: HTTPBatchStreamLinkOptions<TRouter['_def']['_config']['$types']>

192

): TRPCLink<TRouter>;

193

194

interface HTTPBatchStreamLinkOptions<TRoot extends AnyClientTypes> extends HTTPBatchLinkOptions<TRoot> {

195

/** Additional streaming configuration options */

196

}

197

```

198

199

**Usage Examples:**

200

201

```typescript

202

import { createTRPCClient, httpBatchStreamLink } from "@trpc/client";

203

204

// Streaming batch link for large responses

205

const client = createTRPCClient<AppRouter>({

206

links: [

207

httpBatchStreamLink({

208

url: "http://localhost:3000/trpc",

209

maxItems: 50, // Handle larger batches with streaming

210

}),

211

],

212

});

213

214

// Efficient for operations returning large datasets

215

const results = await Promise.all([

216

client.analytics.getUserMetrics.query({ range: "30d" }),

217

client.analytics.getPostMetrics.query({ range: "30d" }),

218

client.analytics.getEngagementData.query({ range: "30d" }),

219

]);

220

```

221

222

### httpSubscriptionLink

223

224

HTTP-based subscriptions using Server-Sent Events (SSE) for real-time communication without WebSocket connections.

225

226

```typescript { .api }

227

/**

228

* Creates an HTTP subscription link using Server-Sent Events

229

* @param opts - HTTP subscription link configuration options

230

* @returns HTTP subscription transport link

231

*/

232

function httpSubscriptionLink<TRouter extends AnyRouter>(

233

opts: HTTPSubscriptionLinkOptions<TRouter['_def']['_config']['$types']>

234

): TRPCLink<TRouter>;

235

236

interface HTTPSubscriptionLinkOptions<TRoot extends AnyClientTypes> extends HTTPLinkOptions<TRoot> {

237

/** Additional SSE-specific configuration */

238

}

239

```

240

241

**Usage Examples:**

242

243

```typescript

244

import { createTRPCClient, httpBatchLink, httpSubscriptionLink, splitLink } from "@trpc/client";

245

246

// Combined HTTP links for queries/mutations and subscriptions

247

const client = createTRPCClient<AppRouter>({

248

links: [

249

splitLink({

250

condition: (op) => op.type === 'subscription',

251

true: httpSubscriptionLink({

252

url: "http://localhost:3000/trpc",

253

}),

254

false: httpBatchLink({

255

url: "http://localhost:3000/trpc",

256

}),

257

}),

258

],

259

});

260

261

// Subscribe using HTTP SSE

262

const unsubscribe = client.posts.onUpdate.subscribe(undefined, {

263

onData: (post) => console.log("Post updated:", post),

264

onError: (err) => console.error("SSE error:", err),

265

});

266

```

267

268

### Content Type Support

269

270

HTTP links automatically detect and handle different content types for mutation inputs.

271

272

```typescript { .api }

273

/** Detect if value is FormData for file uploads */

274

function isFormData(value: unknown): boolean;

275

276

/** Detect if value is binary octet stream data */

277

function isOctetType(value: unknown): boolean;

278

279

/** Detect if value requires non-JSON serialization */

280

function isNonJsonSerializable(value: unknown): boolean;

281

```

282

283

**Content Type Examples:**

284

285

```typescript

286

// JSON payload (default)

287

await client.posts.create.mutate({

288

title: "Hello World",

289

content: "This is a post",

290

});

291

292

// FormData for file uploads

293

const formData = new FormData();

294

formData.append("file", fileInput.files[0]);

295

formData.append("title", "Image Upload");

296

297

await client.media.upload.mutate(formData);

298

299

// Binary octet stream

300

const binaryData = new Uint8Array([1, 2, 3, 4]);

301

await client.files.uploadBinary.mutate(binaryData);

302

303

// Automatically detects content type and sets appropriate headers

304

```

305

306

### Error Handling

307

308

HTTP links provide detailed error information including response metadata.

309

310

```typescript { .api }

311

interface HTTPResult {

312

/** HTTP response metadata */

313

meta: {

314

response: Response;

315

responseJSON?: any;

316

};

317

/** Parsed response data */

318

json: any;

319

}

320

```

321

322

**Error Handling Examples:**

323

324

```typescript

325

try {

326

const result = await client.user.getById.query({ id: 999 });

327

} catch (error) {

328

if (error instanceof TRPCClientError) {

329

// Access HTTP response details

330

const response = error.meta?.response;

331

const status = response?.status;

332

333

if (status === 404) {

334

console.log("User not found");

335

} else if (status === 401) {

336

redirectToLogin();

337

}

338

339

// Structured error data from server

340

console.log("Error code:", error.data?.code);

341

console.log("Error details:", error.data?.details);

342

}

343

}

344

```

345

346

### Configuration Options

347

348

Advanced configuration options for HTTP transport behavior.

349

350

```typescript { .api }

351

/** Custom fetch function interface */

352

type FetchEsque = (input: RequestInfo, init?: RequestInit) => Promise<Response>;

353

354

/** Base HTTP link configuration shared across HTTP transports */

355

interface HTTPLinkBaseOptions<TRoot extends AnyClientTypes> {

356

/** Server endpoint URL */

357

url: string | URL;

358

359

/** Custom fetch implementation */

360

fetch?: FetchEsque;

361

362

/** Force all requests to use POST method */

363

methodOverride?: 'POST';

364

365

/** Data transformation configuration */

366

transformer?: TransformerOptions<TRoot>;

367

}

368

369

/** Data transformation options */

370

interface TransformerOptions<TRoot> {

371

transformer?: TRoot['transformer'];

372

}

373

```

374

375

**Advanced Configuration Examples:**

376

377

```typescript

378

import { createTRPCClient, httpBatchLink } from "@trpc/client";

379

import fetch from "node-fetch";

380

381

// Node.js environment with custom fetch

382

const client = createTRPCClient<AppRouter>({

383

links: [

384

httpBatchLink({

385

url: "http://localhost:3000/trpc",

386

fetch: fetch as any,

387

methodOverride: "POST", // Force all requests to POST

388

}),

389

],

390

});

391

392

// Custom transformer (superjson example)

393

import superjson from "superjson";

394

395

const client = createTRPCClient<AppRouter>({

396

links: [

397

httpBatchLink({

398

url: "http://localhost:3000/trpc",

399

transformer: superjson,

400

}),

401

],

402

});

403

```