update readme.md
This commit is contained in:
299
readme.md
299
readme.md
@@ -1,9 +1,7 @@
|
|||||||
# @push.rocks/smartrequest
|
# @push.rocks/smartrequest
|
||||||
A modern HTTP/HTTPS request library for Node.js with support for form data, file uploads, JSON, binary data, streams, and unix sockets. Features both a legacy API for backward compatibility and a modern fetch-like API for new projects.
|
A modern HTTP/HTTPS request library for Node.js with a fetch-like API, supporting form data, file uploads, JSON, binary data, streams, and unix sockets.
|
||||||
|
|
||||||
## Install
|
## Install
|
||||||
To install `@push.rocks/smartrequest`, use one of the following commands:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Using npm
|
# Using npm
|
||||||
npm install @push.rocks/smartrequest --save
|
npm install @push.rocks/smartrequest --save
|
||||||
@@ -15,12 +13,9 @@ pnpm add @push.rocks/smartrequest
|
|||||||
yarn add @push.rocks/smartrequest
|
yarn add @push.rocks/smartrequest
|
||||||
```
|
```
|
||||||
|
|
||||||
This will add `@push.rocks/smartrequest` to your project's dependencies.
|
|
||||||
|
|
||||||
## Key Features
|
## Key Features
|
||||||
|
|
||||||
- 🚀 **Modern Fetch-like API** - Familiar response methods (`.json()`, `.text()`, `.arrayBuffer()`, `.stream()`)
|
- 🚀 **Modern Fetch-like API** - Familiar response methods (`.json()`, `.text()`, `.arrayBuffer()`, `.stream()`)
|
||||||
- 🔄 **Two API Styles** - Legacy function-based API and modern fluent chainable API
|
|
||||||
- 🌐 **Unix Socket Support** - Connect to local services like Docker
|
- 🌐 **Unix Socket Support** - Connect to local services like Docker
|
||||||
- 📦 **Form Data & File Uploads** - Built-in support for multipart/form-data
|
- 📦 **Form Data & File Uploads** - Built-in support for multipart/form-data
|
||||||
- 🔁 **Pagination Support** - Multiple strategies (offset, cursor, Link headers)
|
- 🔁 **Pagination Support** - Multiple strategies (offset, cursor, Link headers)
|
||||||
@@ -29,135 +24,13 @@ This will add `@push.rocks/smartrequest` to your project's dependencies.
|
|||||||
- 🎯 **Zero Magic Defaults** - Explicit configuration following fetch API principles
|
- 🎯 **Zero Magic Defaults** - Explicit configuration following fetch API principles
|
||||||
- 🔌 **Streaming Support** - Handle large files and real-time data
|
- 🔌 **Streaming Support** - Handle large files and real-time data
|
||||||
- 🔧 **Highly Configurable** - Timeouts, retries, headers, and more
|
- 🔧 **Highly Configurable** - Timeouts, retries, headers, and more
|
||||||
|
- 🔄 **Legacy API Available** - For backward compatibility
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
`@push.rocks/smartrequest` is designed as a versatile, modern HTTP client library for making HTTP/HTTPS requests in Node.js environments. It provides a clean, type-safe API inspired by the native fetch API but with additional features needed for server-side applications.
|
`@push.rocks/smartrequest` provides a clean, type-safe API inspired by the native fetch API but with additional features needed for server-side applications.
|
||||||
|
|
||||||
The library provides two distinct APIs:
|
### Basic Usage
|
||||||
|
|
||||||
1. **Legacy API** - Simple function-based API for quick requests and backward compatibility
|
|
||||||
2. **Modern Fluent API** - A chainable, fetch-like API for more complex scenarios
|
|
||||||
|
|
||||||
Below we will cover key usage scenarios of `@push.rocks/smartrequest`, showcasing its capabilities and providing you with a solid starting point to integrate it into your projects.
|
|
||||||
|
|
||||||
### Import Guide
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
// Modern API (recommended for new projects)
|
|
||||||
import { SmartRequestClient } from '@push.rocks/smartrequest';
|
|
||||||
|
|
||||||
// Legacy API (for backward compatibility)
|
|
||||||
import { getJson, postJson, request } from '@push.rocks/smartrequest/legacy';
|
|
||||||
```
|
|
||||||
|
|
||||||
### Simple GET Request
|
|
||||||
|
|
||||||
For fetching data from a REST API or any web service that returns JSON:
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
import { getJson } from '@push.rocks/smartrequest/legacy';
|
|
||||||
|
|
||||||
async function fetchGitHubUserInfo(username: string) {
|
|
||||||
const response = await getJson(`https://api.github.com/users/${username}`);
|
|
||||||
console.log(response.body); // The body contains the JSON response
|
|
||||||
}
|
|
||||||
|
|
||||||
fetchGitHubUserInfo('octocat');
|
|
||||||
```
|
|
||||||
|
|
||||||
The `getJson` function simplifies the process of sending a GET request and parsing the JSON response.
|
|
||||||
|
|
||||||
### POST Requests with JSON
|
|
||||||
|
|
||||||
When you need to send JSON data to a server, for example, creating a new resource:
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
import { postJson } from '@push.rocks/smartrequest/legacy';
|
|
||||||
|
|
||||||
async function createTodoItem(todoDetails: { title: string; completed: boolean }) {
|
|
||||||
const response = await postJson('https://jsonplaceholder.typicode.com/todos', {
|
|
||||||
requestBody: todoDetails
|
|
||||||
});
|
|
||||||
console.log(response.body); // Log the created todo item
|
|
||||||
}
|
|
||||||
|
|
||||||
createTodoItem({ title: 'Implement smartrequest', completed: false });
|
|
||||||
```
|
|
||||||
|
|
||||||
`postJson` handles setting the appropriate content-type header and stringifies the JSON body.
|
|
||||||
|
|
||||||
### Handling Form Data and File Uploads
|
|
||||||
|
|
||||||
`@push.rocks/smartrequest` simplifies the process of uploading files and submitting form data to a server:
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
import { postFormData, IFormField } from '@push.rocks/smartrequest/legacy';
|
|
||||||
|
|
||||||
async function uploadProfilePicture(formDataFields: IFormField[]) {
|
|
||||||
await postFormData('https://api.example.com/upload', {}, formDataFields);
|
|
||||||
}
|
|
||||||
|
|
||||||
uploadProfilePicture([
|
|
||||||
{ name: 'avatar', type: 'filePath', payload: './path/to/avatar.jpg', fileName: 'avatar.jpg', contentType: 'image/jpeg' },
|
|
||||||
{ name: 'user_id', type: 'string', payload: '12345' }
|
|
||||||
]);
|
|
||||||
```
|
|
||||||
|
|
||||||
### Streaming Support
|
|
||||||
|
|
||||||
For cases when dealing with large datasets or streaming APIs, `@push.rocks/smartrequest` provides streaming capabilities:
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
import { getStream } from '@push.rocks/smartrequest/legacy';
|
|
||||||
|
|
||||||
async function streamLargeFile(url: string) {
|
|
||||||
const stream = await getStream(url);
|
|
||||||
|
|
||||||
stream.on('data', (chunk) => {
|
|
||||||
console.log('Received chunk of data.');
|
|
||||||
});
|
|
||||||
|
|
||||||
stream.on('end', () => {
|
|
||||||
console.log('Stream ended.');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
streamLargeFile('https://example.com/largefile');
|
|
||||||
```
|
|
||||||
|
|
||||||
`getStream` allows you to handle data as it's received, which can be beneficial for performance and scalability.
|
|
||||||
|
|
||||||
### Advanced Options and Customization
|
|
||||||
|
|
||||||
`@push.rocks/smartrequest` is built to be flexible, allowing you to specify additional options to tailor requests to your needs:
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
import { request, ISmartRequestOptions } from '@push.rocks/smartrequest/legacy';
|
|
||||||
|
|
||||||
async function customRequestExample() {
|
|
||||||
const options: ISmartRequestOptions = {
|
|
||||||
method: 'GET',
|
|
||||||
headers: {
|
|
||||||
'Custom-Header': 'Value'
|
|
||||||
},
|
|
||||||
keepAlive: true // Enables connection keep-alive
|
|
||||||
};
|
|
||||||
|
|
||||||
const response = await request('https://example.com/data', options);
|
|
||||||
console.log(response.body);
|
|
||||||
}
|
|
||||||
|
|
||||||
customRequestExample();
|
|
||||||
```
|
|
||||||
|
|
||||||
`request` is the underlying function that powers the simpler `getJson`, `postJson`, etc., and provides you with full control over the HTTP request.
|
|
||||||
|
|
||||||
## Modern Fluent API
|
|
||||||
|
|
||||||
In addition to the legacy API shown above, `@push.rocks/smartrequest` provides a modern, fluent API with a fetch-like response interface that offers a more chainable and TypeScript-friendly approach to making HTTP requests.
|
|
||||||
|
|
||||||
### Basic Usage with the Modern API
|
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
import { SmartRequestClient } from '@push.rocks/smartrequest';
|
import { SmartRequestClient } from '@push.rocks/smartrequest';
|
||||||
@@ -223,7 +96,7 @@ async function fetchWithRetry(url: string) {
|
|||||||
|
|
||||||
### Working with Different Response Types
|
### Working with Different Response Types
|
||||||
|
|
||||||
The modern API provides a fetch-like interface for handling different response types:
|
The API provides a fetch-like interface for handling different response types:
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
import { SmartRequestClient } from '@push.rocks/smartrequest';
|
import { SmartRequestClient } from '@push.rocks/smartrequest';
|
||||||
@@ -277,12 +150,64 @@ async function streamLargeFile(url: string) {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Pagination Support
|
### Response Object Methods
|
||||||
|
|
||||||
The modern API includes built-in support for various pagination strategies:
|
The `SmartResponse` object provides these methods:
|
||||||
|
|
||||||
|
- `json<T>(): Promise<T>` - Parse response as JSON
|
||||||
|
- `text(): Promise<string>` - Get response as text
|
||||||
|
- `arrayBuffer(): Promise<ArrayBuffer>` - Get response as ArrayBuffer
|
||||||
|
- `stream(): NodeJS.ReadableStream` - Get the underlying Node.js stream
|
||||||
|
- `raw(): http.IncomingMessage` - Get the raw http.IncomingMessage
|
||||||
|
|
||||||
|
Each body method can only be called once per response, similar to the fetch API.
|
||||||
|
|
||||||
|
## Advanced Features
|
||||||
|
|
||||||
|
### Form Data with File Uploads
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
import { SmartRequestClient, PaginationStrategy } from '@push.rocks/smartrequest';
|
import { SmartRequestClient } from '@push.rocks/smartrequest';
|
||||||
|
import * as fs from 'fs';
|
||||||
|
|
||||||
|
async function uploadMultipleFiles(files: Array<{name: string, path: string}>) {
|
||||||
|
const formFields = files.map(file => ({
|
||||||
|
name: 'files',
|
||||||
|
value: fs.readFileSync(file.path),
|
||||||
|
filename: file.name,
|
||||||
|
contentType: 'application/octet-stream'
|
||||||
|
}));
|
||||||
|
|
||||||
|
const response = await SmartRequestClient.create()
|
||||||
|
.url('https://api.example.com/upload')
|
||||||
|
.formData(formFields)
|
||||||
|
.post();
|
||||||
|
|
||||||
|
return await response.json();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Unix Socket Support
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { SmartRequestClient } from '@push.rocks/smartrequest';
|
||||||
|
|
||||||
|
// Connect to a service via Unix socket
|
||||||
|
async function queryViaUnixSocket() {
|
||||||
|
const response = await SmartRequestClient.create()
|
||||||
|
.url('http://unix:/var/run/docker.sock:/v1.24/containers/json')
|
||||||
|
.get();
|
||||||
|
|
||||||
|
return await response.json();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Pagination Support
|
||||||
|
|
||||||
|
The library includes built-in support for various pagination strategies:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { SmartRequestClient } from '@push.rocks/smartrequest';
|
||||||
|
|
||||||
// Offset-based pagination (page & limit)
|
// Offset-based pagination (page & limit)
|
||||||
async function fetchAllUsers() {
|
async function fetchAllUsers() {
|
||||||
@@ -338,46 +263,7 @@ async function fetchAllIssues(repo: string) {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Advanced Features
|
### Keep-Alive Connections
|
||||||
|
|
||||||
#### Unix Socket Support
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
import { SmartRequestClient } from '@push.rocks/smartrequest';
|
|
||||||
|
|
||||||
// Connect to a service via Unix socket
|
|
||||||
async function queryViaUnixSocket() {
|
|
||||||
const response = await SmartRequestClient.create()
|
|
||||||
.url('http://unix:/var/run/docker.sock:/v1.24/containers/json')
|
|
||||||
.get();
|
|
||||||
|
|
||||||
return await response.json();
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Form Data with File Uploads
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
import { SmartRequestClient } from '@push.rocks/smartrequest';
|
|
||||||
|
|
||||||
async function uploadMultipleFiles(files: Array<{name: string, path: string}>) {
|
|
||||||
const formFields = files.map(file => ({
|
|
||||||
name: 'files',
|
|
||||||
value: fs.readFileSync(file.path),
|
|
||||||
filename: file.name,
|
|
||||||
contentType: 'application/octet-stream'
|
|
||||||
}));
|
|
||||||
|
|
||||||
const response = await SmartRequestClient.create()
|
|
||||||
.url('https://api.example.com/upload')
|
|
||||||
.formData(formFields)
|
|
||||||
.post();
|
|
||||||
|
|
||||||
return await response.json();
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Keep-Alive Connections
|
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
import { SmartRequestClient } from '@push.rocks/smartrequest';
|
import { SmartRequestClient } from '@push.rocks/smartrequest';
|
||||||
@@ -398,41 +284,9 @@ async function performMultipleRequests() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Response Object Methods
|
## Complete Example: Building a REST API Client
|
||||||
|
|
||||||
The modern API returns a `SmartResponse` object with the following methods:
|
Here's a complete example of building a typed API client:
|
||||||
|
|
||||||
- `json<T>(): Promise<T>` - Parse response as JSON
|
|
||||||
- `text(): Promise<string>` - Get response as text
|
|
||||||
- `arrayBuffer(): Promise<ArrayBuffer>` - Get response as ArrayBuffer
|
|
||||||
- `stream(): NodeJS.ReadableStream` - Get the underlying Node.js stream
|
|
||||||
- `raw(): http.IncomingMessage` - Get the raw http.IncomingMessage
|
|
||||||
|
|
||||||
Each body method can only be called once per response, similar to the fetch API.
|
|
||||||
|
|
||||||
Through its comprehensive set of features tailored for modern web development, `@push.rocks/smartrequest` aims to provide developers with a powerful tool for handling HTTP/HTTPS requests efficiently. Whether it's a simple API call, handling form data, processing streams, or working with paginated APIs, `@push.rocks/smartrequest` delivers a robust, type-safe solution to fit your project's requirements.
|
|
||||||
|
|
||||||
## Migration Guide: Legacy API to Modern API
|
|
||||||
|
|
||||||
If you're currently using the legacy API and want to migrate to the modern fluent API, here's a quick reference guide:
|
|
||||||
|
|
||||||
| Legacy API | Modern API |
|
|
||||||
|------------|------------|
|
|
||||||
| `getJson(url)` | `SmartRequestClient.create().url(url).get()` |
|
|
||||||
| `postJson(url, { requestBody: data })` | `SmartRequestClient.create().url(url).json(data).post()` |
|
|
||||||
| `putJson(url, { requestBody: data })` | `SmartRequestClient.create().url(url).json(data).put()` |
|
|
||||||
| `delJson(url)` | `SmartRequestClient.create().url(url).delete()` |
|
|
||||||
| `postFormData(url, {}, fields)` | `SmartRequestClient.create().url(url).formData(fields).post()` |
|
|
||||||
| `getStream(url)` | `SmartRequestClient.create().url(url).accept('stream').get()` |
|
|
||||||
| `request(url, options)` | `SmartRequestClient.create().url(url).[...configure options...].get()` |
|
|
||||||
|
|
||||||
The modern API provides more flexibility and better TypeScript integration, making it the recommended approach for new projects.
|
|
||||||
|
|
||||||
## Complete Examples
|
|
||||||
|
|
||||||
### Building a REST API Client
|
|
||||||
|
|
||||||
Here's a complete example of building a typed API client using smartrequest:
|
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
import { SmartRequestClient, type SmartResponse } from '@push.rocks/smartrequest';
|
import { SmartRequestClient, type SmartResponse } from '@push.rocks/smartrequest';
|
||||||
@@ -497,7 +351,7 @@ const user = await api.getUser(1);
|
|||||||
const posts = await api.getAllPosts(user.id);
|
const posts = await api.getAllPosts(user.id);
|
||||||
```
|
```
|
||||||
|
|
||||||
### Error Handling
|
## Error Handling
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
import { SmartRequestClient } from '@push.rocks/smartrequest';
|
import { SmartRequestClient } from '@push.rocks/smartrequest';
|
||||||
@@ -538,6 +392,31 @@ async function fetchWithErrorHandling(url: string) {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Legacy API
|
||||||
|
|
||||||
|
For backward compatibility, the original function-based API is still available via a separate import:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { getJson, postJson, request } from '@push.rocks/smartrequest/legacy';
|
||||||
|
|
||||||
|
// Simple GET request
|
||||||
|
const response = await getJson('https://api.example.com/data');
|
||||||
|
console.log(response.body);
|
||||||
|
|
||||||
|
// POST request
|
||||||
|
const result = await postJson('https://api.example.com/users', {
|
||||||
|
requestBody: { name: 'John', email: 'john@example.com' }
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
For migration from the legacy API to the modern API, here's a quick reference:
|
||||||
|
|
||||||
|
| Legacy API | Modern API |
|
||||||
|
|------------|------------|
|
||||||
|
| `getJson(url)` | `SmartRequestClient.create().url(url).get()` |
|
||||||
|
| `postJson(url, { requestBody: data })` | `SmartRequestClient.create().url(url).json(data).post()` |
|
||||||
|
| `request(url, options)` | `SmartRequestClient.create().url(url).[...configure].get()` |
|
||||||
|
|
||||||
## License and Legal Information
|
## License and Legal Information
|
||||||
|
|
||||||
This repository contains open-source code that is licensed under the MIT License. A copy of the MIT License can be found in the [license](license) file within this repository.
|
This repository contains open-source code that is licensed under the MIT License. A copy of the MIT License can be found in the [license](license) file within this repository.
|
||||||
|
Reference in New Issue
Block a user