# File Uploads
This guide covers how to handle file uploads using `multipart/form-data` with `@qualisero/openapi-endpoint`.
## File Upload Overview
File uploads use the `multipart/form-data` content type, which allows sending binary files along with other form data. This library supports both:
- **FormData objects** - Directly upload browser `FormData` instances
- **Binary strings** - Upload binary data as string (for some APIs)
## Basic File Upload with FormData
### Simple Single File Upload
```typescript
import { api } from './api/init'
async function uploadAvatar(userId: string, file: File) {
const formData = new FormData()
formData.append('avatar', file)
const uploadMutation = api.uploadUserAvatar.useMutation({ userId })
return uploadMutation.mutateAsync({
data: formData,
})
}
// Usage
const fileInput = document.querySelector('input[type="file"]')
const file = fileInput.files[0]
await uploadAvatar('123', file)
```
### File Upload with Additional Fields
```typescript
import { api } from './api/init'
async function uploadDocument(userId: string, file: File, description: string) {
const formData = new FormData()
formData.append('document', file)
formData.append('description', description)
const uploadMutation = api.uploadUserDocument.useMutation({ userId })
return uploadMutation.mutateAsync({
data: formData,
})
}
await uploadDocument('123', file, 'Contract document')
```
## Vue Component File Upload
### Complete File Upload Component
```vue
Uploading...
{{ uploadError }}
```
### File Upload with Progress
```vue
(file = e.target.files[0])" />
{{ uploadProgress }}%
```
## Multiple File Uploads
### Upload Multiple Files
```typescript
import { api } from './api/init'
async function uploadMultipleFiles(userId: string, files: File[]) {
const formData = new FormData()
files.forEach((file, index) => {
formData.append(`files[${index}]`, file)
// Or use same field name:
// formData.append('files', file)
})
const uploadMutation = api.uploadUserFiles.useMutation({ userId })
return uploadMutation.mutateAsync({
data: formData,
})
}
// Usage
const fileInput = document.querySelector('input[type="file"][multiple]')
const files = Array.from(fileInput.files)
await uploadMultipleFiles('123', files)
```
## Binary String Upload
Some APIs accept binary data as string instead of FormData:
```typescript
import { api } from './api/init'
async function uploadBinaryData(userId: string, binaryString: string) {
const uploadMutation = api.uploadUserAvatar.useMutation({ userId })
return uploadMutation.mutateAsync({
data: {
file: binaryString, // Binary data as string
},
})
}
// Convert File to binary string
const file = fileInput.files[0]
const reader = new FileReader()
reader.onload = async () => {
const binaryString = reader.result as string
await uploadBinaryData('123', binaryString)
}
reader.readAsBinaryString(file)
```
## File Upload with Cache Invalidation
```typescript
import { api } from './api/init'
const { data: userProfile } = api.getUserProfile.useQuery({ userId: '123' })
const uploadAvatar = async (userId: string, file: File) => {
const formData = new FormData()
formData.append('avatar', file)
const uploadMutation = api.uploadUserAvatar.useMutation(
{ userId },
{
// Automatically invalidate related queries after upload
invalidateOperations: ['getUserProfile'],
onSuccess: (data) => {
console.log('Avatar uploaded:', data)
// userProfile will automatically refetch
},
onError: (error) => {
console.error('Upload failed:', error)
},
},
)
return uploadMutation.mutateAsync({
data: formData,
})
}
```
## File Type Validation
### Validate File Type Before Upload
```vue
{{ error }}
```
## Image Preview Before Upload
```vue
```
## Best Practices
1. **Validate files on client** - Check file type and size before uploading to save bandwidth
2. **Show upload progress** - Use axios's `onUploadProgress` to show feedback to users
3. **Invalidate cache on success** - Automatically refresh related queries after upload
4. **Handle errors gracefully** - Show clear error messages when uploads fail
5. **Clean up resources** - Use `URL.revokeObjectURL()` for preview URLs
6. **Use FormData for uploads** - It's the standard way to upload files in browsers
7. **Test with real files** - File uploads can have issues that don't appear with small test data
## What's Next?
- [Axios Configuration](./08-axios-configuration.md) - Learn about advanced Axios configuration for uploads and more
- [Cache Management](./06-cache-management.md) - Learn about advanced cache control strategies