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