# r6-rs/http

TypeScript definitions and runtime HTTP client for [r6-rs](https://github.com/jaehafe/r6-rs), a Rust-based k6 clone for HTTP load testing.

## Features

- 🔥 **k6 Compatible**: Drop-in replacement for k6 HTTP module
- 🦀 **Rust Performance**: Backed by high-performance Rust runtime
- 📝 **TypeScript Support**: Full type safety and IDE autocomplete
- 🚀 **Dual Runtime**: Works in both Node.js and r6-rs environments
- ⚡ **Modern APIs**: Promise-based async/await interface

## Installation

```bash
npm install r6-rs/http
```

## Quick Start

### Basic Usage

```typescript
import http from 'r6-rs/http';

async function defaultTest() {
  const response = await http.get('https://api.example.com/health');

  console.log(`Status: ${response.status}`);
  console.log(`Response: ${response.body}`);

  return response.ok;
}

export default defaultTest;
```

### k6 Migration

Migrating from k6? Just change the import path:

```typescript
// Before (k6)
import http from 'k6/http';

// After (r6-rs) - same code!
import http from 'r6-rs/http/k6';

// Everything else stays the same!
async function defaultTest() {
  const response = await http.get('https://api.example.com');
  return response.ok;
}
```

## API Reference

### HTTP Methods

```typescript
// GET request
const response = await http.get(url, options?);

// POST request
const response = await http.post(url, body?, options?);

// PUT request
const response = await http.put(url, body?, options?);

// PATCH request
const response = await http.patch(url, body?, options?);

// DELETE request
const response = await http.del(url, options?);

// HEAD request
const response = await http.head(url, options?);

// OPTIONS request
const response = await http.options(url, options?);

// Generic request
const response = await http.request(method, url, body?, options?);
```

### Request Options

```typescript
interface HTTPOptions {
  headers?: Record<string, string>;
  timeout?: number; // in seconds
  redirects?: number;
  auth?: {
    username: string;
    password: string;
  };
}
```

### Response Object

```typescript
interface HTTPResponse {
  status: number; // HTTP status code
  ok: boolean; // true for 2xx status codes
  body?: string; // response body
  headers?: Record<string, string>;
  url?: string; // final URL after redirects
  error?: string; // error message if failed
  timings?: {
    // performance timings
    duration: number;
    blocked: number;
    connecting: number;
    // ... more timing details
  };
}
```

### Batch Requests

```typescript
const responses = await http.batch([
  { method: 'GET', url: 'https://api.example.com/users' },
  {
    method: 'POST',
    url: 'https://api.example.com/users',
    body: { name: 'John' },
  },
  { method: 'GET', url: 'https://api.example.com/posts' },
]);

responses.forEach((response, index) => {
  console.log(`Request ${index}: ${response.status}`);
});
```

## Environment Support

### r6-rs Runtime

When running in r6-rs, this package uses native Rust HTTP operations for maximum performance:

```bash
r6 my-test.ts --vus 100 --duration 30s
```

### Node.js Development

For development and testing, the package falls back to `fetch()` API:

```bash
node my-test.js
# or
npx tsx my-test.ts
```

## Examples

### Load Testing with Authentication

```typescript
import http from 'r6-rs/http';

async function authTest() {
  const loginResponse = await http.post('https://api.example.com/login', {
    username: 'testuser',
    password: 'password123',
  });

  if (!loginResponse.ok) {
    throw new Error('Login failed');
  }

  const token = JSON.parse(loginResponse.body).token;

  const apiResponse = await http.get('https://api.example.com/protected', {
    headers: {
      Authorization: `Bearer ${token}`,
      'Content-Type': 'application/json',
    },
  });

  return apiResponse.ok;
}

export default authTest;
```

### Performance Testing

```typescript
import http from 'r6-rs/http';

async function performanceTest() {
  const startTime = Date.now();

  const response = await http.get('https://api.example.com/heavy-endpoint', {
    timeout: 10, // 10 second timeout
  });

  const duration = Date.now() - startTime;

  console.log(`Request took ${duration}ms`);
  console.log(`Server response time: ${response.timings?.duration}ms`);

  return response.status < 400 && duration < 5000; // Pass if < 5s
}

export default performanceTest;
```

## TypeScript Configuration

Add this to your `tsconfig.json` for the best experience:

```json
{
  "compilerOptions": {
    "moduleResolution": "node",
    "allowSyntheticDefaultImports": true,
    "esModuleInterop": true,
    "target": "ES2020",
    "module": "ESNext",
    "lib": ["ES2020", "DOM"]
  }
}
```

## License

MIT

## Contributing

See the main [r6-rs repository](https://github.com/jaehafe/r6-rs) for contribution guidelines.
