Ultimate Receiving Framework
Production-ready skill that handles receiving, code, review, feedback. Includes structured workflows, validation checks, and reusable patterns for development.
Ultimate Receiving Framework
A comprehensive skill for implementing robust request handling and response processing in web applications. Covers API response parsing, streaming data consumption, webhook receivers, Server-Sent Events, and WebSocket message handling with proper error recovery.
When to Use This Skill
Choose this skill when:
- Building API clients that need robust response parsing and error handling
- Implementing webhook endpoints that receive and process external events
- Consuming streaming responses (SSE, chunked transfer, ReadableStream)
- Handling WebSocket message protocols with reconnection logic
- Processing file uploads and multipart form data on the server
Consider alternatives when:
- Sending requests rather than receiving → use an HTTP client or API skill
- Building REST API endpoints → use an API design skill
- Working with GraphQL subscriptions → use a GraphQL skill
- Need database query result handling → use a database skill
Quick Start
// Robust API response handler with type validation async function receiveJSON<T>( response: Response, schema: z.ZodType<T> ): Promise<T> { if (!response.ok) { const body = await response.text().catch(() => ''); throw new APIError(response.status, body); } const contentType = response.headers.get('content-type'); if (!contentType?.includes('application/json')) { throw new Error(`Expected JSON, received ${contentType}`); } const raw = await response.json(); return schema.parse(raw); // runtime type validation }
Core Concepts
Response Handling Strategies
| Source | Pattern | Error Recovery |
|---|---|---|
| REST API | Parse JSON, validate schema | Retry with backoff on 5xx |
| Streaming API | ReadableStream + TextDecoder | Resume from last chunk offset |
| WebSocket | Message event handler | Auto-reconnect with backoff |
| Server-Sent Events | EventSource API | Built-in reconnection |
| Webhooks | Verify signature, parse body | Return 200, retry idempotently |
| File uploads | Multipart parser, stream to disk | Chunked upload with resume |
Streaming Response Consumer
async function* receiveStream(response: Response): AsyncGenerator<string> { const reader = response.body?.getReader(); if (!reader) throw new Error('No response body'); const decoder = new TextDecoder(); let buffer = ''; try { while (true) { const { done, value } = await reader.read(); if (done) break; buffer += decoder.decode(value, { stream: true }); const lines = buffer.split('\n'); buffer = lines.pop() || ''; for (const line of lines) { if (line.trim()) yield line; } } if (buffer.trim()) yield buffer; } finally { reader.releaseLock(); } } // Usage for await (const chunk of receiveStream(response)) { const data = JSON.parse(chunk); handleChunk(data); }
Webhook Receiver with Signature Verification
import crypto from 'crypto'; function verifyWebhookSignature( payload: string, signature: string, secret: string ): boolean { const expected = crypto .createHmac('sha256', secret) .update(payload, 'utf8') .digest('hex'); return crypto.timingSafeEqual( Buffer.from(signature), Buffer.from(expected) ); } app.post('/webhooks/stripe', express.raw({ type: '*/*' }), (req, res) => { const sig = req.headers['stripe-signature'] as string; if (!verifyWebhookSignature(req.body.toString(), sig, WEBHOOK_SECRET)) { return res.status(401).send('Invalid signature'); } const event = JSON.parse(req.body.toString()); // Process idempotently — check if event.id was already handled queue.add('process-webhook', { event }); res.status(200).json({ received: true }); });
Configuration
| Parameter | Type | Default | Description |
|---|---|---|---|
responseTimeout | number | 30000 | Maximum wait time for response body (ms) |
maxRetries | number | 3 | Retry count for failed requests on 5xx |
retryBackoff | string | 'exponential' | Backoff strategy: linear, exponential, or jitter |
validateSchema | boolean | true | Validate responses against Zod/JSON schemas |
streamBufferSize | number | 65536 | Maximum buffer size for streaming responses (bytes) |
webhookIdempotency | boolean | true | Deduplicate webhook events by event ID |
Best Practices
-
Always validate response data at runtime — TypeScript types are erased at runtime. Use Zod, io-ts, or similar libraries to validate API responses match expected shapes. External data is untrusted data regardless of API documentation.
-
Implement idempotent webhook processing — Webhook providers retry on timeout, so your endpoint may receive the same event multiple times. Store processed event IDs and skip duplicates. Return 200 immediately, then process asynchronously.
-
Use streaming for large payloads — Don't buffer entire response bodies into memory. Use
ReadableStream,AsyncGenerator, or Node.js streams to process data incrementally. This prevents memory spikes with large files or long-running streams. -
Handle partial failure in batch responses — When receiving arrays of results, some items may succeed while others fail. Process each item independently and report per-item errors rather than treating the entire batch as failed.
-
Set explicit timeouts on all network receivers — Without timeouts, connections can hang indefinitely. Set response timeouts, read timeouts, and idle timeouts. AbortController with setTimeout provides reliable timeout behavior in fetch-based code.
Common Issues
Streaming responses missing final chunk — When using line-based parsing, the last chunk may not end with a newline. Always flush the buffer after the stream ends to capture the final data. Check for remaining buffer content in the finally block.
Webhook endpoint returning 500 causes retry storms — If webhook processing throws an error before sending a response, the provider retries aggressively. Always return 200 immediately after signature verification, then process the event asynchronously in a job queue.
Response body consumed twice error — response.json() and response.text() can only be called once on a Response object. If you need the body in multiple formats, read it as text first, then parse. Clone the response with response.clone() if you need to read the body multiple times.
Reviews
No reviews yet. Be the first to review this template!
Similar Templates
Full-Stack Code Reviewer
Comprehensive code review skill that checks for security vulnerabilities, performance issues, accessibility, and best practices across frontend and backend code.
Test Suite Generator
Generates comprehensive test suites with unit tests, integration tests, and edge cases. Supports Jest, Vitest, Pytest, and Go testing.
Pro Architecture Workspace
Battle-tested skill for architectural, decision, making, framework. Includes structured workflows, validation checks, and reusable patterns for development.