1. 들어가며: 엔진에 핸들을 달자
지난 포스팅에서 거래소의 핵심 엔진인 OrderService(매수/매도 로직)를 구현했습니다. 엔진은 강력하지만, 운전자(사용자)가 직접 엔진을 만질 수는 없습니다.
이번 포스팅에서는 외부(프론트엔드)에서 보내는 주문 요청을 받아서 서비스로 연결해 주는 **핸들(Controller)**을 구현합니다. 특히 화면이 깜빡이지 않고 데이터를 주고받기 위해 REST API 방식으로 설계했습니다.
2. Controller 구현: OrderController
주문 요청은 단순히 화면을 보여주는 것이 아니라 데이터를 서버로 보라(Create)는 요청이므로 POST 방식을 사용합니다.
controller/OrderController.java
@RestController // (1) View(HTML)가 아니라 데이터(JSON/String)를 반환
@RequiredArgsConstructor
@RequestMapping("/orders") // 공통 URL: localhost:8080/orders/...
public class OrderController {
private final OrderService orderService;
// 매수 요청 (POST /orders/buy)
@PostMapping("/buy")
public ResponseEntity<String> buyStock(@RequestBody OrderRequestDto requestDto) {
// (2) @RequestBody: JSON 데이터를 자바 객체(DTO)로 변환
orderService.buy(requestDto.getUserId(), requestDto.getCode(), requestDto.getQuantity());
// (3) ResponseEntity: 잘 처리됐다는 신호(200 OK)와 메시지 반환
return ResponseEntity.ok("매수 주문 성공!");
}
// 매도 요청 (POST /orders/sell)
@PostMapping("/sell")
public ResponseEntity<String> sellStock(@RequestBody OrderRequestDto requestDto) {
orderService.sell(requestDto.getUserId(), requestDto.getCode(), requestDto.getQuantity());
return ResponseEntity.ok("매도 주문 성공!");
}
}
3. 기술적 회고 (Deep Dive) 💡
Q1. 왜 @Controller가 아니라 @RestController인가?
6편에서 StockViewController를 만들 때는 @Controller를 썼습니다. HTML 화면을 보여줘야 했기 때문입니다. 하지만 주문(Order)은 버튼을 눌렀을 때 페이지가 이동하는 것이 아니라, "주문이 완료되었습니다"라는 알림만 뜨길 원했습니다.
- @Controller: 페이지 이동(HTML 반환)에 적합.
- @RestController: 데이터 교환(JSON/Text 반환)에 적합. 따라서 프론트엔드 자바스크립트(Fetch API)와 통신하기 위해 @RestController를 사용했습니다.
Q2. @RequestBody의 역할은?
사용자가 보내는 데이터는 JSON 형태({"userId":1, "code":"BTC", "quantity":5})로 날아옵니다. 자바는 이 JSON을 알아듣지 못합니다. @RequestBody 어노테이션은 **HTTP 요청 본문(Body)에 있는 JSON 데이터를 자바 객체(OrderRequestDto)로 쏙 넣어주는 역할(매핑)**을 합니다. 만약 이 어노테이션을 빼먹으면 모든 값이 null로 들어오게 되니 주의해야 합니다.
Q3. ResponseEntity를 꼭 써야 하나?
그냥 String을 반환해도 되지만, ResponseEntity를 쓰면 **HTTP 상태 코드(Status Code)**를 명확하게 제어할 수 있습니다.
- 성공 시: 200 OK
- 실패 시: 400 Bad Request 이렇게 상태 코드를 명확히 주면 프론트엔드에서 "성공했는지 실패했는지" 판단하기가 훨씬 쉬워집니다. ResponseEntity.ok(...)는 200번 상태 코드와 함께 데이터를 보낸다는 뜻입니다.
4. 마치며
이제 **[화면 -> 컨트롤러 -> 서비스 -> DB]**로 이어지는 모든 길(Path)이 뚫렸습니다. 백엔드 개발은 사실상 끝났습니다!
하지만 아직 화면에 "매수/매도 버튼"만 있고, 그 버튼을 눌렀을 때 실제로 이 API를 호출하는 자바스크립트 코드가 없습니다. 다음 포스팅에서는 마지막 퍼즐인 **프론트엔드 연동 (JavaScript Fetch API)**을 구현하여 프로젝트를 완성해 보겠습니다.
'개발 공부 > 프로젝트' 카테고리의 다른 글
| [사이드 프로젝트] 가상 주식 거래소 만들기 (11) - 내 자산 조회 API 설계와 RESTful 리팩토링 (1) | 2026.01.07 |
|---|---|
| [사이드 프로젝트] 가상 주식 거래소 만들기 (10) - 마침내 첫 거래 성사! (HTML/JS 연동과 디버깅) (0) | 2026.01.03 |
| [사이드 프로젝트] 가상 주식 거래소 만들기 (8) - 핵심 비즈니스 로직 구현 (매수/매도와 트랜잭션) (0) | 2025.12.09 |
| [사이드 프로젝트] 가상 주식 거래소 만들기 (7) - 거래를 위한 도메인 설계와 JPA Entity (0) | 2025.12.09 |
| [사이드 프로젝트] 가상 주식 거래소 만들기 (6) - Thymeleaf를 활용한 시세 화면 구현과 SSR (0) | 2025.12.08 |