[Spring] WebFlux로 FastAPI 프록시 구현하기 — MultipartBodyBuilder, FilePart, WebClient
by 우와한개발자
1. 개요
- Spring Boot가 클라이언트 요청을 받아 FastAPI 서버로 중계하는 프록시 구조다
- 파일과 텍스트를 함께 전달해야 하기 때문에 멀티파트 요청을 구성해서 전송한다
- 클라이언트가 FastAPI 서버에 직접 접근하지 않고 Spring Boot를 통해서만 통신하게 해서 보안, 인증, 라우팅을 중앙에서 관리할 수 있다
클라이언트 → Spring Boot (프록시) → FastAPI
인증/라우팅 담당 AI 처리 담당
2. 멀티파트 (Multipart)
- 파일과 텍스트를 함께 전송할 때 사용하는 HTTP 전송 방식
Content-Type: multipart/form-data
------boundary
Content-Disposition: form-data; name="message"
안녕하세요
------boundary
Content-Disposition: form-data; name="file"; filename="photo.png"
Content-Type: image/png
(바이너리 데이터...)
------boundary--
| 항목 | 설명 |
| MultipartBodyBuilder | 멀티파트 바디를 조립하는 빌더 |
| .part() | 텍스트 파트 추가 |
| .asyncPart() | 파일을 스트림으로 추가 (메모리 효율적) |
| .filename() | 서버가 파일명을 알 수 있도록 지정 |
| .contentType() | 파일 형식 지정 (image/png 등) |
2. 구현
1) ObjectDetectionProxyController
- 클라이언트 요청을 받아 FastAPI 서버로 중계하는 프록시
클라이언트
↓ POST /api/detect/proxy
↓ (message + file + responseType)
SpringBoot (프록시)
↓ POST /detect
↓ 멀티파트 재조립해서 전달
FastAPI (객체 감지)
↓ 결과 반환
클라이언트
@RestController
@RequiredArgsConstructor
public class ObjectDetectionProxyController {
private final WebClient webClient;
@PostMapping("/api/detect/proxy")
public Mono<String> service(
@RequestPart("message") String message, // 텍스트
@RequestPart("file") FilePart file, // 파일 (WebFlux 전용)
@RequestPart("responseType") String responseType) {
// 멀티파트 바디 조립
MultipartBodyBuilder bodyBuilder = new MultipartBodyBuilder();
bodyBuilder.part("message", message);
bodyBuilder.part("responseType", responseType);
bodyBuilder.asyncPart("file", file.content(), DataBuffer.class)
.filename(file.filename())
.contentType(
file.headers().getContentType() != null
? file.headers().getContentType() // 원본 Content-Type 유지
: MediaType.APPLICATION_OCTET_STREAM // 없으면 기본값
);
// FastAPI 서버로 전송
return webClient.post()
.uri("/detect")
.contentType(MediaType.MULTIPART_FORM_DATA)
.body(BodyInserters.fromMultipartData(bodyBuilder.build()))
.retrieve()
.bodyToMono(String.class)
.timeout(Duration.ofSeconds(30)); // 30초 초과 시 에러
}
}
2) build.gradle
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-webflux'
compileOnly 'org.projectlombok:lombok'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'io.projectreactor:reactor-test'
testCompileOnly 'org.projectlombok:lombok'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
testAnnotationProcessor 'org.projectlombok:lombok'
}
- spring-boot-starter-webflux 만 사용
- webmvc 관련 의존성 혼용 금지 → MVC가 활성화되면 FilePart 바인딩 오류가 발생한다.
'AI > Spring AI' 카테고리의 다른 글
| [Spring] WebClient로 OpenAI API 연동하기 (0) | 2026.06.01 |
|---|---|
| [Spring AI] MQTT로 실시간 객체탐지 구현하기 — Mosquitto, paho-mqtt, YOLO, WebSocket (0) | 2026.06.01 |
| [Spring] Spring WebFlux란? — 동기/비동기, 블로킹/논블로킹, Mono/Flux, WebClient (0) | 2026.06.01 |
| [Spring AI] Spring Boot와 FastAPI로 AI 객체탐지 서비스 구현하기 (0) | 2026.05.30 |
| [Spring AI] Spring Boot 기반 AI 서비스 아키텍처 — FastAPI, MQTT, Spring AI (0) | 2026.05.29 |
블로그의 정보
우와한개발자 님의 블로그
우와한개발자