Make synchronous web requests with cross-platform support
npx @tessl/cli install tessl/npm-sync-request@6.1.00
# sync-request
1
2
Synchronous HTTP request library with cross-platform support for Node.js and browsers. Provides an API similar to then-request but with synchronous execution, supporting all major HTTP methods and comprehensive request configuration options.
3
4
## Package Information
5
6
- **Package Name**: sync-request
7
- **Package Type**: npm
8
- **Language**: TypeScript/JavaScript
9
- **Installation**: `npm install sync-request`
10
11
## Core Imports
12
13
```typescript
14
import request, { HttpVerb, Response, Options, FormData } from "sync-request";
15
```
16
17
For CommonJS:
18
19
```javascript
20
const request = require("sync-request");
21
const { FormData } = request;
22
```
23
24
For browser usage (when built):
25
26
```javascript
27
// Available as window.syncRequest when included via script tag
28
const response = syncRequest('GET', 'https://api.example.com/data');
29
```
30
31
**Note**: The package re-exports `HttpVerb`, `Response`, and `Options` types from its dependencies for TypeScript users:
32
33
```typescript
34
// All types are available via named imports
35
import request, { HttpVerb, Response, Options, FormData } from "sync-request";
36
37
// Use type inference (also works)
38
const response = request('GET', 'https://api.example.com'); // response is automatically typed as Response
39
```
40
41
## Basic Usage
42
43
```javascript
44
const request = require("sync-request");
45
46
// Simple GET request
47
const response = request('GET', 'https://jsonplaceholder.typicode.com/posts/1');
48
console.log(response.getBody('utf8'));
49
50
// POST request with JSON data
51
const postResponse = request('POST', 'https://jsonplaceholder.typicode.com/posts', {
52
json: { title: 'New Post', body: 'Post content', userId: 1 },
53
headers: { 'Content-Type': 'application/json' }
54
});
55
56
// Handle response
57
if (postResponse.statusCode === 201) {
58
console.log('Post created:', postResponse.getBody('utf8'));
59
}
60
```
61
62
## Architecture
63
64
sync-request provides cross-platform synchronous HTTP requests through different mechanisms:
65
66
- **Node.js**: Uses `sync-rpc` with worker processes to execute `then-request` asynchronously while providing a synchronous interface
67
- **Browser**: Leverages XMLHttpRequest's synchronous mode (deprecated but supported for compatibility)
68
- **Common Interface**: Both platforms expose identical API for consistent usage across environments
69
70
**Important**: This library is not recommended for production use as synchronous requests can block the event loop in Node.js and freeze browsers. Use `then-request` for production applications.
71
72
## Capabilities
73
74
### HTTP Request Function
75
76
Make synchronous HTTP requests with comprehensive options support.
77
78
```typescript { .api }
79
/**
80
* Make a synchronous HTTP request
81
* @param method - HTTP method (GET, POST, PUT, DELETE, HEAD, etc.)
82
* @param url - Request URL as string or URL object
83
* @param options - Request configuration options
84
* @returns Response object with status, headers, and body
85
*/
86
function request(method: HttpVerb, url: string | URL, options?: Options): Response;
87
```
88
89
**Usage Examples:**
90
91
```javascript
92
// GET with headers
93
const response = request('GET', 'https://api.example.com/users', {
94
headers: {
95
'Authorization': 'Bearer token123',
96
'User-Agent': 'MyApp/1.0'
97
}
98
});
99
100
// POST with form data
101
const form = new FormData();
102
form.append('username', 'john_doe');
103
form.append('email', 'john@example.com');
104
105
const response = request('POST', 'https://api.example.com/users', {
106
form: form
107
});
108
109
// Request with query parameters
110
const response = request('GET', 'https://api.example.com/search', {
111
qs: { q: 'javascript', limit: 10, offset: 0 }
112
});
113
114
// Request with timeout and retry
115
const response = request('GET', 'https://api.example.com/data', {
116
timeout: 5000,
117
retry: true,
118
maxRetries: 3,
119
retryDelay: 1000
120
});
121
```
122
123
### Form Data Handling
124
125
Custom FormData implementation for multipart/form-data requests.
126
127
```typescript { .api }
128
/**
129
* FormData class for handling multipart/form-data
130
*/
131
class FormData {
132
/**
133
* Append a field to the form
134
* @param key - Field name
135
* @param value - Field value (string, Blob, or Buffer)
136
* @param fileName - Optional filename for file uploads
137
*/
138
append(key: string, value: string | Blob | Buffer, fileName?: string): void;
139
}
140
```
141
142
**Usage Example:**
143
144
```javascript
145
const request = require('sync-request');
146
const { FormData } = request;
147
148
const form = new FormData();
149
form.append('text_field', 'Hello World');
150
form.append('file', fileBuffer, 'document.pdf');
151
152
const response = request('POST', 'https://api.example.com/upload', {
153
form: form
154
});
155
```
156
157
## Types
158
159
```typescript { .api }
160
/**
161
* HTTP methods supported by sync-request (re-exported from 'then-request')
162
* Standard HTTP methods as string literals
163
*/
164
type HttpVerb = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'HEAD' | 'PATCH' | 'OPTIONS' | string;
165
166
/**
167
* Request configuration options
168
*/
169
interface Options {
170
/** Query string parameters as object */
171
qs?: { [key: string]: any };
172
/** HTTP headers */
173
headers?: { [key: string]: string | string[] };
174
/** Request body for POST/PUT requests */
175
body?: string | Buffer;
176
/** JSON data - automatically stringified and sets Content-Type */
177
json?: any;
178
/** FormData for multipart/form-data requests */
179
form?: FormData;
180
/** Enable file caching (Node.js only) */
181
cache?: 'file';
182
/** Follow HTTP redirects (default: true) */
183
followRedirects?: boolean;
184
/** Maximum number of redirects (default: Infinity) */
185
maxRedirects?: number;
186
/** Headers allowed during redirects */
187
allowRedirectHeaders?: string[];
188
/** Enable gzip compression (default: true) */
189
gzip?: boolean;
190
/** Request timeout in milliseconds */
191
timeout?: number;
192
/** Socket timeout in milliseconds (Node.js only) */
193
socketTimeout?: number;
194
/** Retry failed requests */
195
retry?: boolean;
196
/** Delay between retries in milliseconds (default: 200) */
197
retryDelay?: number;
198
/** Maximum number of retries (default: 5) */
199
maxRetries?: number;
200
/** Custom agent configuration */
201
agent?: boolean;
202
}
203
204
/**
205
* HTTP response object (re-exported from 'then-request' via 'http-response-object')
206
* The actual Response implementation provides these key properties and methods
207
*/
208
interface Response {
209
/** HTTP status code */
210
statusCode: number;
211
/** Response headers */
212
headers: { [key: string]: string | string[] };
213
/** Response body (string in browser, Buffer in Node.js) */
214
body: string | Buffer;
215
/** Final URL after redirects */
216
url: string;
217
218
/**
219
* Get response body with optional encoding
220
* Throws error if status code >= 300
221
* @param encoding - Text encoding (e.g., 'utf8')
222
* @returns Response body as string or Buffer
223
*/
224
getBody(encoding?: string): string | Buffer;
225
}
226
```
227
228
## Error Handling
229
230
sync-request handles errors in several ways:
231
232
### HTTP Error Status Codes
233
234
The `getBody()` method throws an error for HTTP status codes >= 300:
235
236
```javascript
237
try {
238
const response = request('GET', 'https://api.example.com/not-found');
239
const body = response.getBody('utf8'); // Throws error for 404
240
} catch (error) {
241
console.error('HTTP Error:', error.statusCode, error.message);
242
console.error('Response body:', error.body.toString());
243
}
244
```
245
246
### Network and Request Errors
247
248
Network failures, timeouts, and other request errors are thrown as exceptions:
249
250
```javascript
251
try {
252
const response = request('GET', 'https://invalid-domain.example', {
253
timeout: 1000
254
});
255
} catch (error) {
256
console.error('Request failed:', error.message);
257
}
258
```
259
260
### Checking Status Without Throwing
261
262
To handle status codes manually without exceptions:
263
264
```javascript
265
const response = request('GET', 'https://api.example.com/data');
266
267
if (response.statusCode >= 200 && response.statusCode < 300) {
268
// Success
269
const data = response.getBody('utf8');
270
} else if (response.statusCode === 404) {
271
// Handle not found
272
console.log('Resource not found');
273
} else {
274
// Handle other errors
275
console.error('HTTP Error:', response.statusCode);
276
}
277
```
278
279
## Platform-Specific Behavior
280
281
### Node.js Environment
282
283
- Uses worker processes via `sync-rpc` for true synchronous behavior
284
- Supports all request options including `socketTimeout`, `cache`, and `agent`
285
- Requires `nc` (netcat) utility for optimal performance; falls back to slower method if unavailable
286
- Response body is a Buffer by default
287
288
### Browser Environment
289
290
- Uses synchronous XMLHttpRequest (not recommended for production)
291
- Some options like `socketTimeout`, `cache`, and `agent` are ignored
292
- Response body is always a string
293
- Cross-domain requests follow browser CORS policies
294
295
### Common Limitations
296
297
- **Performance Impact**: Blocks the event loop/main thread during request execution
298
- **Scalability Issues**: Cannot handle concurrent requests efficiently
299
- **Browser Compatibility**: Synchronous XHR is deprecated and may cause browser freezing
300
- **Production Warning**: Not suitable for production applications - use `then-request` instead