or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.md

index.mddocs/

0

# @smithy/fetch-http-handler

1

2

@smithy/fetch-http-handler is a TypeScript library that provides a fetch-based HTTP request handler specifically designed for browser applications as part of the Smithy TypeScript ecosystem. It implements the default `requestHandler` used in browser environments, leveraging the modern Fetch API to handle HTTP requests with support for request timeouts, streaming responses, and proper error handling.

3

4

## Package Information

5

6

- **Package Name**: @smithy/fetch-http-handler

7

- **Package Type**: npm

8

- **Language**: TypeScript

9

- **Installation**: `npm install @smithy/fetch-http-handler`

10

11

## Core Imports

12

13

```typescript

14

import { FetchHttpHandler, streamCollector } from "@smithy/fetch-http-handler";

15

import type { FetchHttpHandlerOptions } from "@smithy/fetch-http-handler";

16

```

17

18

For CommonJS:

19

20

```javascript

21

const { FetchHttpHandler, streamCollector } = require("@smithy/fetch-http-handler");

22

```

23

24

## Basic Usage

25

26

```typescript

27

import { FetchHttpHandler } from "@smithy/fetch-http-handler";

28

import { HttpRequest } from "@smithy/protocol-http";

29

30

// Create handler with options

31

const handler = new FetchHttpHandler({

32

requestTimeout: 5000,

33

keepAlive: true,

34

credentials: 'same-origin'

35

});

36

37

// Handle an HTTP request

38

const request = new HttpRequest({

39

method: "GET",

40

hostname: "api.example.com",

41

path: "/users",

42

headers: { "Accept": "application/json" }

43

});

44

45

const { response } = await handler.handle(request);

46

console.log(response.statusCode, response.headers);

47

48

// Use static create method

49

const handler2 = FetchHttpHandler.create({

50

requestTimeout: 10000

51

});

52

```

53

54

## Architecture

55

56

The package is built around several key components:

57

58

- **FetchHttpHandler Class**: Main HTTP handler implementing the Smithy HttpHandler interface

59

- **Stream Collection**: Utilities for collecting data from Blob and ReadableStream objects

60

- **Request Construction**: Internal utilities for creating fetch-compatible Request objects

61

- **Timeout Management**: Promise-based timeout handling for request lifecycle

62

- **Configuration Management**: Dynamic configuration updates and provider pattern support

63

64

## Capabilities

65

66

### HTTP Request Handling

67

68

Core HTTP request handling using the Fetch API with comprehensive configuration options and error handling.

69

70

```typescript { .api }

71

class FetchHttpHandler implements HttpHandler<FetchHttpHandlerOptions> {

72

constructor(options?: FetchHttpHandlerOptions | Provider<FetchHttpHandlerOptions | void>);

73

74

static create(

75

instanceOrOptions?: HttpHandler<any> | FetchHttpHandlerOptions | Provider<FetchHttpHandlerOptions | void>

76

): HttpHandler<any> | FetchHttpHandler;

77

78

handle(request: HttpRequest, options?: HttpHandlerOptions): Promise<{ response: HttpResponse }>;

79

80

destroy(): void;

81

82

updateHttpClientConfig(key: keyof FetchHttpHandlerOptions, value: FetchHttpHandlerOptions[typeof key]): void;

83

84

httpHandlerConfigs(): FetchHttpHandlerOptions;

85

}

86

```

87

88

**Usage Examples:**

89

90

```typescript

91

import { FetchHttpHandler } from "@smithy/fetch-http-handler";

92

import { HttpRequest } from "@smithy/protocol-http";

93

94

// Basic handler with timeout

95

const handler = new FetchHttpHandler({

96

requestTimeout: 5000

97

});

98

99

// Handle POST request with body

100

const postRequest = new HttpRequest({

101

method: "POST",

102

hostname: "api.example.com",

103

path: "/data",

104

headers: { "Content-Type": "application/json" },

105

body: JSON.stringify({ key: "value" })

106

});

107

108

const { response } = await handler.handle(postRequest);

109

110

// Handle request with abort signal

111

const controller = new AbortController();

112

const { response: abortableResponse } = await handler.handle(

113

postRequest,

114

{ abortSignal: controller.signal }

115

);

116

117

// Update configuration dynamically

118

handler.updateHttpClientConfig("requestTimeout", 10000);

119

```

120

121

### Stream Collection

122

123

Utilities for collecting data from Blob or ReadableStream objects into Uint8Array format.

124

125

```typescript { .api }

126

/**

127

* Collects data from a Blob or ReadableStream into a Uint8Array

128

* @param stream - Blob or ReadableStream to collect data from

129

* @returns Promise resolving to collected data as Uint8Array

130

*/

131

const streamCollector: StreamCollector = (stream: Blob | ReadableStream): Promise<Uint8Array>;

132

133

type StreamCollector = (stream: Blob | ReadableStream) => Promise<Uint8Array>;

134

```

135

136

**Usage Examples:**

137

138

```typescript

139

import { streamCollector } from "@smithy/fetch-http-handler";

140

141

// Collect from ReadableStream

142

const response = await fetch('/api/data');

143

if (response.body) {

144

const data = await streamCollector(response.body);

145

console.log('Collected bytes:', data.length);

146

}

147

148

// Collect from Blob

149

const blob = new Blob(['Hello, world!']);

150

const uint8Array = await streamCollector(blob);

151

console.log('Blob as bytes:', uint8Array);

152

```

153

154

### Configuration Options

155

156

Comprehensive configuration interface for customizing HTTP request behavior.

157

158

```typescript { .api }

159

interface FetchHttpHandlerOptions {

160

/**

161

* The number of milliseconds a request can take before being automatically

162

* terminated.

163

*/

164

requestTimeout?: number;

165

166

/**

167

* Whether to allow the request to outlive the page. Default value is false.

168

*

169

* There may be limitations to the payload size, number of concurrent requests,

170

* request duration etc. when using keepalive in browsers.

171

*

172

* These may change over time, so look for up to date information about

173

* these limitations before enabling keepalive.

174

*/

175

keepAlive?: boolean;

176

177

/**

178

* A string indicating whether credentials will be sent with the request always, never, or

179

* only when sent to a same-origin URL.

180

* @see https://developer.mozilla.org/en-US/docs/Web/API/Request/credentials

181

*/

182

credentials?: "include" | "omit" | "same-origin" | undefined | string;

183

184

/**

185

* Cache settings for fetch.

186

* @see https://developer.mozilla.org/en-US/docs/Web/API/Request/cache

187

*/

188

cache?: "default" | "force-cache" | "no-cache" | "no-store" | "only-if-cached" | "reload";

189

190

/**

191

* An optional function that produces additional RequestInit

192

* parameters for each httpRequest.

193

*

194

* This is applied last via merging with Object.assign() and overwrites other values

195

* set from other sources.

196

*

197

* @example

198

* ```js

199

* new Client({

200

* requestHandler: {

201

* requestInit(httpRequest) {

202

* return { cache: "no-store" };

203

* }

204

* }

205

* });

206

* ```

207

*/

208

requestInit?: (httpRequest: HttpRequest) => RequestInit;

209

}

210

211

interface HttpHandlerOptions {

212

/** AbortSignal to cancel the request */

213

abortSignal?: AbortSignal;

214

}

215

216

type Provider<T> = () => Promise<T>;

217

```

218

219

### Internal Utilities

220

221

Internal utilities used by the FetchHttpHandler for request creation and timeout management.

222

223

```typescript { .api }

224

/**

225

* Creates a Request object for mocking/interception support

226

* @param url - Target URL for the request

227

* @param requestOptions - Optional RequestInit options

228

* @returns New Request object

229

*/

230

function createRequest(

231

url: string,

232

requestOptions?: RequestInit & AdditionalRequestParameters

233

): Request;

234

235

/**

236

* Creates a timeout promise that rejects after specified milliseconds

237

* @param timeoutInMs - Timeout duration in milliseconds (0 disables timeout)

238

* @returns Promise that rejects with TimeoutError

239

*/

240

function requestTimeout(timeoutInMs?: number): Promise<never>;

241

242

type AdditionalRequestParameters = {

243

/** Required in Node.js when Request has a body */

244

duplex?: "half";

245

};

246

247

const keepAliveSupport: {

248

supported: undefined | boolean;

249

};

250

```

251

252

## Types

253

254

### Core Types

255

256

```typescript { .api }

257

interface HttpRequest {

258

method: string;

259

protocol: string;

260

hostname: string;

261

port?: number;

262

path: string;

263

query?: Record<string, string>;

264

fragment?: string;

265

headers: HeaderBag;

266

username?: string;

267

password?: string;

268

body?: any;

269

}

270

271

interface HttpResponse {

272

statusCode: number;

273

reason?: string;

274

headers: HeaderBag;

275

body: any;

276

}

277

278

type HeaderBag = Record<string, string>;

279

280

interface HttpHandler<T> {

281

handle(request: HttpRequest, options?: HttpHandlerOptions): Promise<{ response: HttpResponse }>;

282

}

283

```

284

285

## Error Handling

286

287

The library handles several types of errors:

288

289

- **AbortError**: Thrown when a request is aborted via AbortSignal

290

- **TimeoutError**: Thrown when a request exceeds the specified timeout

291

- **Standard Fetch Errors**: Network errors, HTTP errors, and other fetch-related errors are propagated as-is

292

293

```typescript

294

try {

295

const { response } = await handler.handle(request);

296

} catch (error) {

297

if (error.name === 'AbortError') {

298

console.log('Request was aborted');

299

} else if (error.name === 'TimeoutError') {

300

console.log('Request timed out');

301

} else {

302

console.log('Other error:', error.message);

303

}

304

}

305

```

306

307

## Browser Compatibility

308

309

- **Primary Target**: Modern browsers with Fetch API support

310

- **Node.js Compatibility**: Requires Node.js 16.5.0+ with Web Streams API support

311

- **Features**: Automatic keepalive detection, AbortController support, streaming response handling

312

- **Recommendations**: Use @smithy/node-http-handler for dedicated Node.js applications