## ChatGPT 컨트롤러
### DTO
#### Request DTO
```java
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@ToString
@Builder
public class PromptTemplateRequest {
private String id;
private String content;
public PromptTemplate toEntity(){
return PromptTemplate.builder()
.id(id)
.content(content)
.build();
}
}
```
- `ModelMapper`를 이용하는 방법도 있다. 나는 선호하지 않는다.
#### Response DTO
```java
@Getter
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode
@ToString
public class PromptTemplateResponse{
private String id;
private String content;
private LocalDateTime modifiedTime;
public PromptTemplateResponse(PromptTemplate promptTemplate){
id = promptTemplate.getId();
content = promptTemplate.getContent();
modifiedTime = promptTemplate.getModifiedTime();
}
}
```
- `ModelMapper`를 이용하는 방법도 있다. 나는 선호하지 않는다.
### 컨트롤러
#### `ChatGPTController`
##### 클래스 생성 및 의존성 주입
```java
@RestController
@Slf4j
public class ChatGPTController {
@Autowired
private PromptTemplateService promptTemplateService;
@Autowired
private ChatGPTClient chatGPTClient;
}
```
- 서비스와 클라이언트를 동시에 사용하니 둘 다 주입 받는다.
##### 기본 CRUD API
```java
@PostMapping("/prompt-template")
public ResponseEntity<PromptTemplateResponse> createPromptTemplate(
@RequestBody PromptTemplateRequest promptTemplateRequest) {
PromptTemplate promptTemplate = promptTemplateRequest.toEntity();
promptTemplate = promptTemplateService.create(promptTemplate);
PromptTemplateResponse templateResponse = new PromptTemplateResponse(promptTemplate);
return ResponseEntity
.status(HttpStatus.CREATED)
.body(templateResponse);
}
@GetMapping("/prompt-template/{id}")
public ResponseEntity<PromptTemplateResponse> readPromptTemplateById(
@PathVariable("id") String id) {
PromptTemplate promptTemplate = promptTemplateService.readById(id);
PromptTemplateResponse templateResponse = new PromptTemplateResponse(promptTemplate);
return ResponseEntity
.status(HttpStatus.OK)
.body(templateResponse);
}
@PutMapping("/prompt-template/{id}")
public ResponseEntity<PromptTemplateResponse> updatePromptTemplateById(
@PathVariable("id") String id,
@RequestBody PromptTemplateRequest promptTemplateRequest) {
PromptTemplate promptTemplate = promptTemplateRequest.toEntity();
promptTemplate = promptTemplateService.updateById(id, promptTemplate);
PromptTemplateResponse templateResponse = new PromptTemplateResponse(promptTemplate);
return ResponseEntity
.status(HttpStatus.CREATED)
.body(templateResponse);
}
@DeleteMapping("/prompt-template/{id}")
public ResponseEntity<?> deletePromptTemplateById(
@PathVariable("id") String id) {
promptTemplateService.deleteById(id);
return ResponseEntity
.status(HttpStatus.OK)
.body(null);
}
```
- 예외 처리는 ExceptionHandler를 통해 한 번에 할 생각이기 때문에 따로 처리하지 않는다.
##### ChatGPT API 프록시
```java
@PostMapping("/prompt")
public ResponseEntity<String> sendPrompt(
@RequestBody String prompt) throws JsonProcessingException {
return ResponseEntity
.status(HttpStatus.OK)
.body(chatGPTClient.chat(prompt));
}
@PostMapping("/prompt/generated-by/prompt-template/{id}")
public ResponseEntity<String> sendPromptByTemplate(
@PathVariable("id") String id,
@RequestBody HashMap<String, String> hashMap) throws TemplateException, IOException {
return ResponseEntity
.status(HttpStatus.OK)
.body(chatGPTClient.chatByTemplate(id, hashMap));
}
```
- 컨트롤러에서 예외 처리를 하지 않고 `JsonProcessingException`를 `throws`하는 이유는 `@ControllerAdvice`에서 예외를 일괄적으로 처리하기 때문이다.
## [[4-3 컨트롤러 테스트 코드(API)|테스트 코드]]
![[4-3 컨트롤러 테스트 코드(API)#`ChatGPTControllerTest` 작성]]