프로젝트

Open AI 를 활용한 면접 문제 생성 프로그램-4. OpenFeign 설정

dlxortmd123 2023. 5. 1. 02:02

OpenFeign

선택 이유

위의 요청을 이제 스프링 부트 코드에서 하기 위해 Open Feign 을 사용하려고 한다.

RestTemplate 와 달리 어노테이션과 인터페이스 기반이어서 Feign 을 선택했다.

 

참고

Spring 공식 문서망나니 개발자님 블로그를 참고했다.

build.gradle

해당 링크로 가면 build.gradle 에 설정하는 법이 나와있다. 필자는 다음과 같이 설정했다.

ext {
	set('springCloudVersion', "2022.0.2")
}

dependencies {
	// ...
    
	implementation 'org.springframework.cloud:spring-cloud-starter-openfeign'
    
	// ...
}

dependencyManagement {
	imports {
		mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
	}
}

 

Feign Config

SpringBoot 테스트 시 해당 설정이 활성화되지 않도록 따로 Configuration 파일로 설정한다. (따로 파일로 설정 시 feign 인터페이스의 위치를 명시해야 한다!)

@Configuration
@EnableFeignClients(basePackages = "com.project.interview_generate.infra.feign")
public class OpenFeignConfig {

}

Feign Client

OpenFeign 으로 보낼 API 는 Chat 을 사용할 예정이다. 해당 API 레퍼렌스를 보면 헤더에 키를 넣고 바디에 필수 값인 모델과 메시지만 넣으면 된다.

해당 정보를 바탕으로 다음과 같이 코드를 작성했다. Configuration 파일을 통해 헤더 설정을 하였고, url 은 yml 파일로 부터 읽어온다.

@FeignClient(name = "OpenAIQuestion", url = "${openai.url}", configuration = HeaderConfig.class)
public interface OpenAIQuestionGenerator extends QuestionGenerator {

	@PostMapping
	OpenAIQuestionResponse question(
		@RequestBody OpenAIQuestionRequest request
	);
}

Header Config

헤더에서는 api 키 값을 넣는다.

설정 파일로 따로 뺀 이유는 키 값을 yml 을 해당 코드로 넣음으로써 호출하는 코드에서 키 값을 신경쓰지 않아도 되고 파라미터보다 한번에 관리하는 것이 좋기 때문이다.

@Configuration
public class HeaderConfig {

	@Bean
	public RequestInterceptor requestInterceptor(
		@Value("${openai.key}")
		String key
	) {
		return requestTemplate -> requestTemplate.header("Authorization", key);
	}
}

DTO

응답과 요청 DTO 는 API 문서에 나와있는 것중 사용하는 것만 필드로 넣어주었다.  

요청 DTO 를 만들 때 요청하는 코드에서 모델이나 형식을 알 필요가 없기 때문에 컨텐츠만 받아서 내부적으로 모델과 형식에 맞게 변경했다.

public record OpenAIQuestionResponse(
	List<ResponseMessage> choices
) {
	public record ResponseMessageContent(
		String content
	) {
	}

	public record ResponseMessage(
		ResponseMessageContent message
	) {
	}
}
public record OpenAIQuestionRequest(
	String model,
	List<MessageContent> messages
) {

	private static final String QUESTION_MODEL = "gpt-3.5-turbo";

	public OpenAIQuestionRequest(String content) {
		this(QUESTION_MODEL, List.of(new MessageContent("user", content)));
	}

	public record MessageContent(
		String role,
		String content
	) {
	}
}

테스트 코드

먼저 OpenFeign 은 JPA 테스트의 @DataJpa 같이 편의 어노테이션을 제공하지 않기 때문에 테스트 어노테이션을 만들었다. (깃헙 참조)

해당 어노테이션을 바탕으로 다음과 같이 테스트 코드를 작성할 수 있다.

 

@FeignTest
class OpenAIQuestionGeneratorTest {

	private final Logger log = LoggerFactory.getLogger(OpenAIQuestionGeneratorTest.class);

	@Autowired
	private OpenAIQuestionGenerator questionGenerator;

	@DisplayName("Open AI 를 통해 질문을 생성할 수 있다.")
	@Test
	void question() {
		// given
		OpenAIQuestionRequest request = new OpenAIQuestionRequest("DB 관련 개발자 면접 질문 3개 알려줘.");

		// when
		OpenAIQuestionResponse actual = questionGenerator.question(request);

		// then
		Assertions.assertThat(actual)
			.isNotNull();
		log.info("result: {}", actual);
	}
}

결과는 정상적으로 나온다.

 

깃헙

https://github.com/dlxortmd987/chat-bot-gpt