백엔드 개발 끄적끄적 03

kiwi_jelly·2026년 3월 11일

졸프

목록 보기
3/4

완전히 잊고 있던 사실 하나!
사용자의 post/portfolio 업로드가 이루어지면
그에 따라 해당 자연어들의 벡터화 및 벡터 db 저장 또한 이루어져야 했다. 두둥탁

해당 파트를 제가 한번 구현해보겠습니다...

0. 전체 흐름도 (Spring ↔ FastAPI)

  1. 사용자 업로드
  2. PostController /PorfolioController
  3. DB에 해당 자연어 저장
  4. VectorService 호출
  5. 벡터화 요청 : RestTemplate을 사용하여 FastAPI로 전송
  6. Python 서버가 벡터를 생성하고, 해당 벡터를 DB에 저장한다.

User
  ↓
POST /posts
  ↓
PostController
  ↓
PostService
  ↓
DB 저장
  ↓
VectorService.vectorizePost()
  ↓
HTTP 요청
  ↓
FastAPI
  ↓
embedding 생성
  ↓
Vector DB 저장

1. VectorService

Spring에서 FastAPI 벡터화를 요청하는 서비스

package com.union.demo.service;

import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.Map;

@Service
public class VectorService {

    private final RestTemplate restTemplate; // spring에서 다른 서버, 즉 api를 호출하기 위한 http 클라이언트 

    public VectorService(RestTemplate restTemplate){
        this.restTemplate = restTemplate;
    }
	
    // postId와 벡터화할 자연어를 받아와 fastapi 서버에 보내 벡터화하는 메서드 
    public void vectorizePost(Long postId){
    	// 어디로 보낼건데? 이 api 주소로 보낼 것. 
        String url = "http://localhost:8000/vectorize/post";
		// 요청 데이터 생성 : HTTP 요청 body를 만드는 코드로, spring이 자동으로 json으로 바꿔줌
        Map<String, Object> req = Map.of(
                "id", postId
        );
 // HTTP 요청 보내는 부분        restTemplate.postForObject(url,req,Void.class); // void.class : 응답 받을 필요 없음 
    }

    public void vectorizePortfolio(Long portfolioId, String text){
        String url = "http://localhost:8000/vectorize/portfolio";
        Map<String, Object> req = Map.of(
                "id", portfolioId
        );

        restTemplate.postForObject(url,req,Void.class);
    }
}

2. PostService 수정

  1. 생성자 만들고 vectorService 생성
  2. vectorize 요청
    vectorService.vectorizePost(post.getPostId());

3. Endpoint 만들기

여기서 유의할 점: 외부에서 내부 메소드를 빼다 보니, 상대경로로 지정해야 할 부분이 늘었다.
모두 확인하고 상대경로로 수정할것!

4. 문제 발생

@Transactional 메서드 안에 바로 vectorService를 호출하자, DB 저장 커밋 전에 python이 해당 post를 조회하여 postId를 찾지 못하는 문제가 난다.

내가 목표해야 하는 흐름
POST /api/posts
→ createPost()
→ DB 저장
→ PostCreatedEvent 발행
→ 트랜잭션 커밋
→ AFTER_COMMIT 리스너 실행
→ vectorService.vectorizePost(postId)
→ FastAPI 조회 성공

profile
In lapidem

0개의 댓글