Open AI 를 활용한 면접 문제 생성 프로그램-4. OpenFeign 설정
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);
}
}
결과는 정상적으로 나온다.