# 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 ``` ### File Upload with Progress ```vue ``` ## 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 ``` ## 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