본문으로 건너뛰기

시리즈

Spring Boot와 FastAPI 연동

Spring Boot에서 FastAPI와 통신하는 방법

· 약 9분
dev-burnern
Developer

Spring Boot로 백엔드 서버를 만들다 보면 모든 기능을 하나의 서버에서 처리할 수도 있다. 하지만 AI 기능이 들어가면 이야기가 조금 달라진다.

예를 들어 회원 관리, 로그인, 결제, 게시글, 템플릿 관리는 Spring Boot가 담당하고, RAG 검색, LLM 응답 생성, 코드 분석, 문서 요약 같은 AI 기능은 FastAPI가 담당하도록 나눌 수 있다.

Frontend

Spring Boot

FastAPI

이 구조에서 중요한 질문은 하나다.

Spring Boot와 FastAPI는 어떤 방식으로 통신해야 할까?


1. Spring Boot와 FastAPI를 함께 사용하는 이유

Spring Boot는 Java 기반 백엔드 서버를 만들 때 많이 사용된다.

회원, 인증, 권한, 결제, 게시글, 관리자 기능처럼 서비스의 핵심 기능을 안정적으로 처리하기 좋다.

반면 FastAPI는 Python 기반 웹 프레임워크이다.

Python은 AI, 머신러닝, 데이터 처리, RAG, LLM 관련 라이브러리와 잘 어울린다. 그래서 AI 기능을 구현할 때는 FastAPI를 따로 두는 것이 편하다.

예를 들어 다음과 같이 역할을 나눌 수 있다.

서버주요 역할
Spring Boot회원, 인증, 결제, 템플릿 관리, API Gateway 역할
FastAPIAI 응답 생성, RAG 검색, 코드 분석, 문서 요약

정리하면 Spring Boot와 FastAPI를 함께 사용하는 이유는 다음과 같다.

Spring Boot는 서비스의 핵심 로직을 담당하고, FastAPI는 AI 기능을 담당하도록 책임을 분리하기 위해서이다.


2. 가장 기본적인 방식은 REST API 통신이다

Spring Boot와 FastAPI가 통신하는 가장 기본적인 방법은 REST API 방식이다.

쉽게 말하면 Spring Boot가 FastAPI의 API 주소로 HTTP 요청을 보내고, FastAPI는 그 요청을 처리한 뒤 JSON 형태로 응답을 돌려준다.

예를 들어 사용자가 AI 질문을 보냈다고 하자.

사용자 질문 입력

Spring Boot 서버

FastAPI 서버 호출

FastAPI가 AI 응답 생성

Spring Boot가 결과를 받아 사용자에게 반환

이때 Spring Boot는 FastAPI의 API 주소로 요청을 보낸다.

POST http://fastapi-server/api/v1/ai/ask

요청 데이터는 보통 JSON 형태로 보낸다.

{
"question": "JWT와 세션의 차이가 뭐야?"
}

FastAPI는 이 요청을 처리하고 다시 JSON으로 응답한다.

{
"answer": "JWT는 토큰 기반 인증 방식이고, 세션은 서버에 인증 상태를 저장하는 방식입니다.",
"references": ["JWT 문서", "Spring Security 문서"]
}

정리하면 REST API 통신은 다음과 같다.

Spring Boot가 FastAPI의 API를 HTTP로 호출하고, JSON 데이터를 주고받는 방식이다.


3. Spring Boot에서 FastAPI를 호출하는 선택지

Spring Boot에서 FastAPI를 호출하려면 HTTP Client가 필요하다.

대표적인 선택지는 다음과 같다.

선택지특징추천 상황
RestClient동기식 HTTP Client일반적인 요청/응답
WebClient비동기, 논블로킹 HTTP ClientAI 스트리밍, 오래 걸리는 요청
HTTP Interface인터페이스 기반 HTTP Client호출 API가 많을 때
OpenFeign선언형 REST Client기존 프로젝트에서 Feign 사용 중일 때
Message Queue비동기 작업 처리AI 작업이 오래 걸릴 때

4. RestClient

가장 먼저 추천할 수 있는 방식은 RestClient이다.

RestClient는 Spring Boot에서 외부 API를 호출할 때 사용할 수 있는 동기식 HTTP Client이다.

쉽게 말하면 다음과 같은 구조에 잘 맞는다.

Spring Boot가 FastAPI에 요청
→ FastAPI가 응답
→ Spring Boot가 결과를 받아 처리

예를 들어 AI 질문에 대한 답변을 한 번에 받아오는 기능이라면 RestClient로 충분하다.

Spring Boot 예시

package com.example.ai;

import org.springframework.stereotype.Component;
import org.springframework.web.client.RestClient;

@Component
public class FastApiClient {

private final RestClient restClient;

public FastApiClient(RestClient.Builder builder) {
this.restClient = builder
.baseUrl("http://localhost:8000")
.build();
}

public AiAnswerResponse ask(AiAnswerRequest request) {
return restClient.post()
.uri("/api/v1/ai/ask")
.body(request)
.retrieve()
.body(AiAnswerResponse.class);
}
}

요청 DTO는 다음과 같이 만들 수 있다.

package com.example.ai;

public record AiAnswerRequest(
String question
) {
}

응답 DTO는 다음과 같이 만들 수 있다.

package com.example.ai;

import java.util.List;

public record AiAnswerResponse(
String answer,
List<String> references
) {
}

FastAPI 예시

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()


class AiAnswerRequest(BaseModel):
question: str


class AiAnswerResponse(BaseModel):
answer: str
references: list[str]


@app.post("/api/v1/ai/ask", response_model=AiAnswerResponse)
def ask_ai(request: AiAnswerRequest) -> AiAnswerResponse:
return AiAnswerResponse(
answer=f"질문에 대한 AI 응답: {request.question}",
references=["문서 A", "문서 B"]
)

정리하면 RestClient는 다음과 같다.

Spring Boot에서 FastAPI를 가장 단순하게 호출할 수 있는 동기식 HTTP Client이다.


5. WebClient

WebClient는 비동기, 논블로킹 방식의 HTTP Client이다.

RestClient와 가장 큰 차이는 처리 방식이다.

구분RestClientWebClient
처리 방식동기식비동기, 논블로킹
사용 난이도쉬움조금 어려움
추천 상황일반 API 호출스트리밍, 많은 외부 API 호출
AI 응답 스트리밍부적합적합

예를 들어 ChatGPT처럼 답변이 한 번에 나오는 것이 아니라 조금씩 출력되는 기능을 만들고 싶다면 WebClient가 더 적합하다.

사용자 질문

Spring Boot

FastAPI

AI 응답을 조금씩 스트리밍

Frontend에 실시간 출력

WebClient 예시는 다음과 같다.

package com.example.ai;

import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

@Component
public class FastApiWebClient {

private final WebClient webClient;

public FastApiWebClient(WebClient.Builder builder) {
this.webClient = builder
.baseUrl("http://localhost:8000")
.build();
}

public Mono<AiAnswerResponse> ask(AiAnswerRequest request) {
return webClient.post()
.uri("/api/v1/ai/ask")
.bodyValue(request)
.retrieve()
.bodyToMono(AiAnswerResponse.class);
}
}

다만 일반적인 요청/응답만 필요하다면 처음부터 WebClient를 사용할 필요는 없다. 구조가 단순한 프로젝트에서는 RestClient가 더 읽기 쉽고 관리하기 편하다.

정리하면 WebClient는 다음과 같다.

AI 응답 스트리밍이나 비동기 처리가 필요할 때 사용하는 Spring의 HTTP Client이다.


6. HTTP Interface

FastAPI에 호출해야 하는 API가 많아지면 HTTP Interface도 고려할 수 있다.

HTTP Interface는 Java 인터페이스에 API 호출 메서드를 정의하고, Spring이 실제 HTTP 호출 객체를 만들어주는 방식이다.

예를 들어 다음과 같이 작성할 수 있다.

package com.example.ai;

import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.service.annotation.HttpExchange;
import org.springframework.web.service.annotation.PostExchange;

@HttpExchange("/api/v1/ai")
public interface FastApiHttpClient {

@PostExchange("/ask")
AiAnswerResponse ask(@RequestBody AiAnswerRequest request);
}

이 방식은 FastAPI에 호출할 API가 많을 때 유용하다.

예를 들어 AI 서버에 다음과 같은 API가 있다고 하자.

/api/v1/ai/ask
/api/v1/ai/summary
/api/v1/ai/code-review
/api/v1/ai/rag/search

이런 API 호출을 Service 코드 안에 전부 작성하면 코드가 지저분해질 수 있다.

이때 HTTP Interface를 사용하면 API 호출 코드를 인터페이스 중심으로 정리할 수 있다.

정리하면 HTTP Interface는 다음과 같다.

FastAPI 호출 API가 많아졌을 때, 인터페이스 기반으로 HTTP 호출 코드를 깔끔하게 관리하는 방식이다.


7. OpenFeign

OpenFeign도 Spring Boot에서 외부 API를 호출할 때 사용할 수 있는 방식이다.

OpenFeign은 인터페이스를 정의하면 HTTP Client 구현체를 자동으로 만들어주는 선언형 REST Client이다.

예시는 다음과 같다.

@FeignClient(name = "fastApiClient", url = "http://localhost:8000")
public interface FastApiFeignClient {

@PostMapping("/api/v1/ai/ask")
AiAnswerResponse ask(@RequestBody AiAnswerRequest request);
}

OpenFeign은 코드가 깔끔하고 사용하기 편하다.

하지만 새 프로젝트라면 우선순위를 조금 낮게 봐도 된다. Spring Boot 3.x 프로젝트에서는 RestClient, WebClient, HTTP Interface를 먼저 고려하는 것이 좋다.

즉, 기존 프로젝트에서 이미 OpenFeign을 쓰고 있다면 계속 사용해도 된다. 하지만 새로 시작하는 프로젝트라면 다음 순서가 더 적절하다.

RestClient
→ WebClient
→ HTTP Interface
→ OpenFeign

정리하면 OpenFeign은 다음과 같다.

선언형 REST Client이지만, 새 프로젝트에서는 Spring 기본 HTTP Client를 먼저 고려하는 것이 좋다.


8. 오래 걸리는 작업은 메시지 큐를 고려해야 한다

REST API 방식은 단순하고 좋지만, 모든 상황에 적합한 것은 아니다.

예를 들어 다음과 같은 AI 작업은 시간이 오래 걸릴 수 있다.

AI 템플릿 생성
PDF 문서 분석
코드 전체 분석
RAG 문서 임베딩
대량 데이터 요약

이런 작업을 단순 REST API로 처리하면 문제가 생길 수 있다.

Spring Boot가 FastAPI 호출
→ FastAPI 작업이 오래 걸림
→ Spring Boot 요청 대기
→ 타임아웃 발생 가능
→ 사용자 경험 저하

이런 경우에는 메시지 큐를 사용할 수 있다.

Spring Boot
↓ 작업 요청 메시지 발행
RabbitMQ 또는 Kafka

FastAPI Worker
↓ AI 작업 수행
DB 또는 Redis에 결과 저장

Spring Boot가 결과 조회

메시지 큐를 사용하면 Spring Boot는 작업 요청만 보내고 바로 응답할 수 있다. FastAPI Worker는 큐에 쌓인 작업을 하나씩 꺼내서 처리한다.

예를 들어 사용자가 AI 템플릿 생성을 요청했다고 하자.

1. 사용자가 템플릿 생성 요청
2. Spring Boot가 작업 상태를 PENDING으로 저장
3. Spring Boot가 RabbitMQ에 작업 메시지 발행
4. FastAPI Worker가 메시지를 가져와 AI 작업 수행
5. 결과를 DB 또는 Redis에 저장
6. 사용자는 작업 상태 API로 결과 확인

이 구조는 오래 걸리는 작업을 처리할 때 안정적이다.


9. RabbitMQ와 Kafka 비교

메시지 큐를 사용할 때 대표적인 선택지는 RabbitMQ와 Kafka이다.

간단히 비교하면 다음과 같다.

구분RabbitMQKafka
주요 목적작업 큐, 메시지 전달이벤트 스트리밍, 대용량 로그
난이도상대적으로 쉬움상대적으로 어려움
추천 상황AI 작업 요청 처리대량 이벤트 처리
캡스톤 프로젝트 적합도높음과할 수 있음

RabbitMQ는 작업 큐 구조를 만들 때 이해하기 쉽다. 예를 들어 “AI 작업 요청을 큐에 넣고, FastAPI Worker가 하나씩 처리한다”는 식으로 설명하기 좋다.

Kafka는 대량 이벤트 처리나 로그 스트리밍에 강하다. 하지만 설정과 운영 난이도가 RabbitMQ보다 높다.

개인 프로젝트나 캡스톤 프로젝트에서는 Kafka보다 RabbitMQ가 더 현실적인 선택일 수 있다.

정리하면 메시지 큐는 다음과 같다.

오래 걸리는 AI 작업을 바로 처리하지 않고, 작업 요청을 큐에 넣어 비동기로 처리하는 방식이다.


10. 어떤 방식을 선택해야 할까?

Spring Boot와 FastAPI 통신 방식은 작업 성격에 따라 선택하면 된다.

상황추천 방식
일반적인 AI 질문/응답REST API + RestClient
단순 RAG 검색 결과 반환REST API + RestClient
AI 답변을 실시간으로 출력WebClient
FastAPI 호출 API가 많음HTTP Interface
AI 작업이 오래 걸림RabbitMQ
대량 이벤트/로그 처리Kafka
기존 프로젝트에서 Feign 사용 중OpenFeign

개인 프로젝트나 캡스톤 프로젝트라면 처음부터 복잡하게 시작할 필요는 없다.

가장 현실적인 순서는 다음과 같다.

1단계: RestClient로 REST API 통신 구현
2단계: AI 스트리밍이 필요하면 WebClient 도입
3단계: 오래 걸리는 작업이 생기면 RabbitMQ 도입
4단계: API 호출 코드가 많아지면 HTTP Interface로 정리

정리하면 선택 기준은 다음과 같다.

짧은 요청은 REST API로 처리하고, 실시간 응답은 WebClient로 처리하며, 오래 걸리는 작업은 메시지 큐로 분리하는 것이 좋다.


마무리

Spring Boot와 FastAPI를 함께 사용할 때 중요한 것은 무조건 복잡한 기술을 선택하는 것이 아니다.

가장 먼저 생각해야 할 것은 작업의 성격이다.

간단히 정리하면 다음과 같다.

구분추천 방식
일반 요청/응답REST API + RestClient
AI 실시간 응답WebClient
호출 API 정리HTTP Interface
오래 걸리는 AI 작업RabbitMQ
대량 이벤트 처리Kafka
기존 Feign 프로젝트OpenFeign 유지 가능

결국 처음에는 RestClient로 시작하는 것이 가장 현실적이다.

이후 프로젝트가 커지면서 AI 응답을 실시간으로 보여줘야 한다면 WebClient를 도입하고, 오래 걸리는 AI 작업이 많아지면 RabbitMQ 같은 메시지 큐를 추가하면 된다.

즉, Spring Boot와 FastAPI 통신 구조는 다음 흐름으로 발전시키면 된다.

RestClient 기반 REST 통신
→ WebClient 기반 스트리밍
→ RabbitMQ 기반 비동기 작업 처리

이렇게 설계하면 Spring Boot는 서비스의 중심 역할을 유지하고, FastAPI는 AI 기능에 집중할 수 있다.

결과적으로 각 서버의 책임이 명확해지고, 유지보수와 확장도 쉬워진다.


참고자료

Spring Boot / Spring Framework

FastAPI

Message Queue