#1
When building modern web or mobile apps, video uploads are a common requirement—whether it’s for user-generated content, tutorials, or internal assets. Storing large video files securely and efficiently is key, and MinIO, a lightweight, high-performance object storage system, is a perfect solution.
In this guide, you’ll learn how to upload video files to MinIO using Spring Boot. We’ll set up a simple API endpoint that allows users to upload .mp4, .mov, and other video formats directly to a MinIO bucket.

What You’ll Learn

  • How to integrate MinIO with a Spring Boot application
  • How to validate and upload video files using a REST API
  • How to organize videos in MinIO buckets
  • How to return a video identifier or path after upload
Note: This guide assumes you already have MinIO up and running locally or remotely and can connect to it from your Spring Boot project.

Step 1: Add MinIO Java SDK to Your Project

Add the MinIO dependency in your pom.xml:
<dependency>
  <groupId>io.minio</groupId>
  <artifactId>minio</artifactId>
  <version>8.5.3</version> <!-- Replace with the latest version -->
</dependency>
This gives your application the ability to interact with MinIO buckets and objects.

Step 2: Configure MinIO Connection

Add the connection settings to your application.properties:
minio.url=http://localhost:9000
minio.accessKey=minioadmin
minio.secretKey=minioadmin
minio.bucketName=videos
You’ll use these values to initialize the MinIO client.

Step 3: Create a MinIO Configuration Bean

Set up a configuration class to create a MinIO client instance:
@Configuration
public class MinioConfig {

    @Value("${minio.url}")
    private String url;

    @Value("${minio.accessKey}")
    private String accessKey;

    @Value("${minio.secretKey}")
    private String secretKey;

    @Bean
    public MinioClient minioClient() {
        return MinioClient.builder()
                .endpoint(url)
                .credentials(accessKey, secretKey)
                .build();
    }
}

Step 4: Create a Video Upload Service

This service handles the logic for uploading video files:
@Service
public class VideoUploadService {

    @Value("${minio.bucketName}")
    private String bucketName;

    private final MinioClient minioClient;

    public VideoUploadService(MinioClient minioClient) {
        this.minioClient = minioClient;
    }

    public String uploadVideo(MultipartFile file) throws Exception {
        // Validate video MIME type
        String contentType = file.getContentType();
        if (contentType == null || !contentType.startsWith("video/")) {
            throw new IllegalArgumentException("Only video files are allowed.");
        }

        // Ensure bucket exists
        boolean exists = minioClient.bucketExists(BucketExistsArgs.builder()
                .bucket(bucketName)
                .build());

        if (!exists) {
            minioClient.makeBucket(MakeBucketArgs.builder()
                    .bucket(bucketName)
                    .build());
        }

        // Generate unique filename
        String fileName = UUID.randomUUID() + "_" + file.getOriginalFilename();

        // Upload to MinIO
        minioClient.putObject(PutObjectArgs.builder()
                .bucket(bucketName)
                .object(fileName)
                .stream(file.getInputStream(), file.getSize(), -1)
                .contentType(contentType)
                .build());

        return fileName;
    }
}

Step 5: Create a REST API Controller

Now expose the video upload feature through a REST endpoint:
@RestController
@RequestMapping("/api/videos")
public class VideoUploadController {

    private final VideoUploadService videoUploadService;

    public VideoUploadController(VideoUploadService videoUploadService) {
        this.videoUploadService = videoUploadService;
    }

    @PostMapping("/upload")
    public ResponseEntity<String> uploadVideo(@RequestParam("file") MultipartFile file) {
        try {
            String fileName = videoUploadService.uploadVideo(file);
            return ResponseEntity.ok("Video uploaded successfully: " + fileName);
        } catch (IllegalArgumentException e) {
            return ResponseEntity.badRequest().body("Invalid file type: " + e.getMessage());
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body("Upload failed: " + e.getMessage());
        }
    }
}

Step 6: Test the Video Upload API

Use Postman, curl, or your frontend to test the upload.

Example with curl:

curl -X POST http://localhost:8080/api/videos/upload \
  -F "file=@/path/to/video.mp4"
If everything is working, you’ll get a response with the stored file name in MinIO.

Best Practices

  • Validate video MIME types to prevent unsupported file uploads
  • Limit maximum upload file size in your app settings
  • Use UUIDs or timestamped names to avoid filename collisions
  • Store metadata (like uploader, duration) in a database if needed
  • Secure MinIO access with proper credentials and environment configs

image quote pre code