File Uploads
@t-req/core supports file uploads through the @./path syntax in form data.
Basic File Upload
Section titled “Basic File Upload”POST https://api.example.com/upload
file = @./documents/report.pdfThe file path is relative to the .http file location. @t-req/core automatically:
- Reads the file content
- Detects the MIME type from the extension
- Sets
Content-Type: multipart/form-data
Custom Filename
Section titled “Custom Filename”Override the filename sent to the server:
POST https://api.example.com/upload
document = @./temp/abc123.pdf | quarterly-report.pdfThe server receives the file as quarterly-report.pdf instead of abc123.pdf.
Multiple Files
Section titled “Multiple Files”Upload multiple files in one request:
POST https://api.example.com/upload
avatar = @./images/photo.jpgresume = @./documents/cv.pdfcover_letter = @./documents/cover.docxFiles with Form Fields
Section titled “Files with Form Fields”Combine file uploads with text fields:
POST https://api.example.com/documents
title = Quarterly Reportdescription = Q4 2025 financial summarycategory = financedocument = @./reports/q4-2025.pdfUsing Variables in Paths
Section titled “Using Variables in Paths”File paths support variable interpolation:
POST https://api.example.com/upload
document = @./{{uploadDir}}/{{filename}}const client = createClient({ io: createNodeIO(), variables: { uploadDir: 'reports/2025', filename: 'q4-summary.pdf', },});Binary File Upload (Raw Body)
Section titled “Binary File Upload (Raw Body)”For APIs expecting raw binary data, use the file reference syntax:
PUT https://api.example.com/files/image.pngContent-Type: image/png
< ./images/photo.pngThis sends the raw file content as the request body.
Programmatic File Uploads
Section titled “Programmatic File Uploads”For dynamic file handling, prepare the form data yourself:
const client = createClient();
// Build FormData manuallyconst formData = new FormData();formData.append('title', 'My Document');formData.append('file', new Blob([fileContent]), 'document.pdf');
// Use runString with interpolated bodyconst httpContent = `POST https://api.example.com/uploadContent-Type: multipart/form-data
`;
// For complex scenarios, you might need to use fetch directlyconst response = await fetch('https://api.example.com/upload', { method: 'POST', body: formData,});File Type Detection
Section titled “File Type Detection”@t-req/core infers MIME types from file extensions:
| Extension | MIME Type |
|---|---|
.pdf | application/pdf |
.json | application/json |
.xml | application/xml |
.jpg, .jpeg | image/jpeg |
.png | image/png |
.gif | image/gif |
.txt | text/plain |
.html | text/html |
.css | text/css |
.js | application/javascript |
.zip | application/zip |
For unknown extensions, application/octet-stream is used.
Large File Considerations
Section titled “Large File Considerations”For very large files:
- Memory: The entire file is loaded into memory. For huge files, consider streaming APIs.
- Timeout: Increase the timeout for slow uploads:
const response = await client.run('./upload.http', { timeout: 300000, // 5 minutes});- Progress: @t-req/core doesn’t currently support upload progress events. For progress tracking, use
fetchdirectly withReadableStream.
Error Handling
Section titled “Error Handling”Handle file-related errors:
try { await client.run('./upload.http');} catch (error) { if (error.code === 'ENOENT') { console.error('File not found'); } else if (error.code === 'EACCES') { console.error('Permission denied'); } else { throw error; }}