diff options
Diffstat (limited to 'js/scripting-lang/design/HTTP_ADAPTER_GUIDE.md')
-rw-r--r-- | js/scripting-lang/design/HTTP_ADAPTER_GUIDE.md | 409 |
1 files changed, 409 insertions, 0 deletions
diff --git a/js/scripting-lang/design/HTTP_ADAPTER_GUIDE.md b/js/scripting-lang/design/HTTP_ADAPTER_GUIDE.md new file mode 100644 index 0000000..74dee68 --- /dev/null +++ b/js/scripting-lang/design/HTTP_ADAPTER_GUIDE.md @@ -0,0 +1,409 @@ +# HTTP Adapter Guide + +## Overview + +The HTTP Adapter in the Baba Yaga REPL demonstrates how to implement a real-world adapter that makes actual HTTP requests. This guide shows how the adapter works, how to use it, and how to implement your own adapters following the same pattern. + +## How the HTTP Adapter Works + +### 1. Adapter Registration + +The HTTP adapter is registered in the REPL's adapter registry: + +```javascript +network: { + name: 'Network Adapter', + description: 'Handles HTTP requests with real network calls', + process: async (command) => { + // Adapter logic here + } +} +``` + +### 2. Command Processing + +The adapter processes commands emitted by scripts: + +```javascript +if (command.type === 'emit' && command.value.action === 'http_request') { + // Process HTTP request +} +``` + +### 3. HTTP Request Execution + +The adapter makes actual HTTP requests using Node.js `fetch`: + +```javascript +const response = await fetch(url, options); +const responseText = await response.text(); +let responseData = JSON.parse(responseText); +``` + +### 4. Response Handling + +The adapter displays results and handles errors: + +```javascript +console.log(`✅ ${method} ${url} - Status: ${response.status}`); +console.log(`Response Data:`, JSON.stringify(responseData, null, 2)); +``` + +## Usage Examples + +### Basic GET Request + +```javascript +// Script +..emit { + action: "http_request", + method: "GET", + url: "https://jsonplaceholder.typicode.com/posts/1" +}; +``` + +### POST Request with JSON Body + +```javascript +// Script +post_data : { + title: "Test Post", + body: "This is a test", + userId: 1 +}; + +..emit { + action: "http_request", + method: "POST", + url: "https://jsonplaceholder.typicode.com/posts", + headers: { + "Content-Type": "application/json" + }, + body: post_data +}; +``` + +### Request with Custom Headers + +```javascript +// Script +..emit { + action: "http_request", + method: "GET", + url: "https://api.example.com/data", + headers: { + "Authorization": "Bearer YOUR_TOKEN", + "Accept": "application/json" + }, + timeout: 10000 +}; +``` + +## Adapter Implementation Pattern + +### 1. Adapter Structure + +```javascript +const myAdapter = { + name: 'My Adapter', + description: 'Handles specific functionality', + process: async (command) => { + // Adapter logic + } +}; +``` + +### 2. Command Pattern + +```javascript +// Script emits commands +..emit { + action: "my_action", + // ... action-specific data +}; + +// Adapter processes commands +if (command.type === 'emit' && command.value.action === 'my_action') { + // Process the action +} +``` + +### 3. Error Handling + +```javascript +try { + // Perform action + const result = await performAction(command.value); + console.log(`✅ Success: ${result}`); +} catch (error) { + console.log(`❌ Error: ${error.message}`); +} +``` + +### 4. Response Processing + +```javascript +// Parse and display responses +let responseData; +try { + responseData = JSON.parse(responseText); +} catch { + responseData = responseText; +} + +console.log(`Response:`, responseData); +``` + +## Supported HTTP Features + +### HTTP Methods +- **GET**: Fetch data from server +- **POST**: Create new resources +- **PUT**: Update existing resources +- **PATCH**: Partial updates +- **DELETE**: Remove resources + +### Request Options +- **url**: Target endpoint +- **method**: HTTP method (default: GET) +- **headers**: Request headers +- **body**: Request body (for POST/PUT/PATCH) +- **timeout**: Request timeout in milliseconds (default: 5000) + +### Response Handling +- **Status codes**: Displayed in console +- **Headers**: Shown for debugging +- **Body**: Parsed as JSON or displayed as text +- **Errors**: Graceful error handling with helpful messages + +## Built-in Examples + +### 1. HTTP GET Example +```bash +:example http-get +``` +Makes a GET request to JSONPlaceholder API to fetch a sample post. + +### 2. HTTP POST Example +```bash +:example http-post +``` +Creates a new post via JSONPlaceholder API with JSON body. + +### 3. Weather API Example +```bash +:example http-weather +``` +Demonstrates integration with OpenWeatherMap API (requires API key). + +### 4. Pokémon API Example +```bash +:example network +``` +Fetches Pokémon data from PokéAPI. + +## Creating Your Own Adapter + +### Step 1: Define Adapter Structure + +```javascript +const myCustomAdapter = { + name: 'Custom Adapter', + description: 'Handles custom functionality', + process: async (command) => { + // Your adapter logic + } +}; +``` + +### Step 2: Implement Command Processing + +```javascript +process: async (command) => { + if (command.type === 'emit' && command.value.action === 'my_custom_action') { + const { param1, param2 } = command.value; + + try { + // Perform your custom action + const result = await performCustomAction(param1, param2); + + // Display results + console.log(`[Custom Adapter] ✅ Success: ${result}`); + + } catch (error) { + console.log(`[Custom Adapter] ❌ Error: ${error.message}`); + } + } +} +``` + +### Step 3: Register with REPL + +```javascript +// In REPL constructor +this.adapters = { + // ... existing adapters + custom: myCustomAdapter +}; +``` + +### Step 4: Use in Scripts + +```javascript +// Script +..emit { + action: "my_custom_action", + param1: "value1", + param2: "value2" +}; +``` + +## Adapter Best Practices + +### 1. Clear Naming +- Use descriptive adapter names +- Provide clear descriptions +- Use consistent naming conventions + +### 2. Error Handling +- Always wrap operations in try-catch +- Provide helpful error messages +- Handle different error types appropriately + +### 3. Logging +- Use colored console output for clarity +- Include adapter name in logs +- Show success/failure status + +### 4. Response Processing +- Handle different response formats +- Parse JSON when appropriate +- Display results in readable format + +### 5. Configuration +- Support timeout configuration +- Allow custom headers +- Provide sensible defaults + +## Integration Patterns + +### 1. State-Driven Requests +```javascript +// Script uses current state to determine request +state : ..listen; +pokemon_name : when state is + { pokemon: name } then name + _ then "ditto"; + +..emit { + action: "http_request", + method: "GET", + url: "https://pokeapi.co/api/v2/pokemon/" + pokemon_name +}; +``` + +### 2. Conditional Requests +```javascript +// Script makes conditional requests +state : ..listen; +when state.action is + "fetch_user" then ..emit { + action: "http_request", + method: "GET", + url: "https://api.example.com/users/" + state.userId + } + "create_user" then ..emit { + action: "http_request", + method: "POST", + url: "https://api.example.com/users", + body: state.userData + }; +``` + +### 3. Batch Requests +```javascript +// Script makes multiple requests +..emit { + action: "http_request", + method: "GET", + url: "https://api.example.com/users" +}; + +..emit { + action: "http_request", + method: "GET", + url: "https://api.example.com/posts" +}; +``` + +## Troubleshooting + +### Common Issues + +1. **Node.js Version**: `fetch` requires Node.js 18+ or a polyfill +2. **Network Errors**: Check internet connection and URL validity +3. **API Keys**: Some APIs require authentication +4. **CORS**: Browser-based requests may have CORS restrictions +5. **Rate Limiting**: APIs may limit request frequency + +### Debug Tips + +1. **Check Adapters**: Use `:adapters` to see available adapters +2. **Test URLs**: Verify URLs work in browser/curl first +3. **Check Headers**: Ensure required headers are included +4. **Monitor Logs**: Watch console output for detailed information +5. **Use Examples**: Start with built-in examples as templates + +## Advanced Features + +### Custom Headers +```javascript +..emit { + action: "http_request", + method: "GET", + url: "https://api.example.com/data", + headers: { + "Authorization": "Bearer YOUR_TOKEN", + "X-Custom-Header": "custom-value" + } +}; +``` + +### Request Timeout +```javascript +..emit { + action: "http_request", + method: "GET", + url: "https://api.example.com/data", + timeout: 10000 // 10 seconds +}; +``` + +### JSON Body +```javascript +..emit { + action: "http_request", + method: "POST", + url: "https://api.example.com/data", + body: { + key: "value", + nested: { + data: "example" + } + } +}; +``` + +## Conclusion + +The HTTP Adapter demonstrates how to build real-world adapters that integrate external services with the Baba Yaga scripting language. By following the patterns shown in this guide, you can create adapters for: + +- Database operations +- File system access +- Message queues +- WebSocket connections +- Email services +- Payment processing +- And much more + +The key is maintaining the functional, side-effect-free nature of scripts while providing powerful integration capabilities through well-designed adapters. \ No newline at end of file |