π[Backend Development] Java Spring νλ μμν¬μ κ³μΈ΅ 1οΈβ£
β Presentation Layer(νν κ³μΈ΅)
-
μ£Όμ μ»΄ν¬λνΈ :
@Controller
,@RestController
- μν : μ¬μ©μμ HTTP μμ²(Request)μ λ°κ³ , κ·Έ κ²°κ³Όλ₯Ό μλ΅(Response)μΌλ‘ 보λ΄μ£Όλ μ ν리μΌμ΄μ μ μ§μ μ μ λλ€.
- μ€λͺ : μ¬μ©μμ μ λ ₯μ λ°μ μ ν¨μ±μ κ²μ¬νκ³ , λΉμ¦λμ€ κ³μΈ΅μΌλ‘ λ°μ΄ν° μ²λ¦¬λ₯Ό μμν©λλ€. λΉμ¦λμ€ κ³μΈ΅μμ μ²λ¦¬λ κ²°κ³Όλ λ€μ μ΄ κ³μΈ΅μμ μ¬μ©μμκ² λ³΄μ¬μ€ νμ(HTML, JSON λ±)μΌλ‘ λ³νλμ΄ μ λ¬λ©λλ€.
β 1. Presentation Layerλ μΈμ μ¬μ©νλμ?
μΈλΆ ν΄λΌμ΄μΈνΈ(μΉ λΈλΌμ°μ , λͺ¨λ°μΌ μ± λ±)κ° μ ν리μΌμ΄μ
μ κΈ°λ₯μ μ κ·Όν΄μΌ ν λ νμ μ¬μ©ν©λλ€.
μ¬μ©μκ° μΉμ¬μ΄νΈμ λ²νΌμ ν΄λ¦νκ±°λ, μ±μ΄ μλ²λ‘λΆν° λ°μ΄ν°λ₯Ό κ°μ Έμ€λ λͺ¨λ μκ°μ μ΄ κ³μΈ΅μ΄ κ°μ₯ λ¨Όμ λμν©λλ€.
β 2. Presentation Layerλ μ΄λμ μ¬μ©νλμ?
μ ν리μΌμ΄μ
μν€ν
μ²μ κ°μ₯ λ°κΉ₯μͺ½ κ³μΈ΅μ μμΉν©λλ€.
μΈλΆ ν΄λΌμ΄μΈνΈμ λ΄λΆ λΉμ¦λμ€ κ³μΈ΅(Service Layer) μ¬μ΄μ μ€κ° λ€λ¦¬ μν μ νλ©°, μμ€ν
μ βνκ΄β λλ βμλ΄ λ°μ€ν¬βλΌκ³ μκ°ν μ μμ΅λλ€.
β 3. Presentation Layerλ μ΄λ»κ² μ¬μ©νλμ?
μ£Όλ‘ μ΄λ Έν μ΄μ κΈ°λ°μΌλ‘ μ¬μ©νλ©°, μμ²μ μ²λ¦¬νκ³ μλ΅μ λ°ννλ λ°©μμΌλ‘ λμν©λλ€.
-
@RestController
,@Controller
μ΄λ Έν μ΄μ μΌλ‘ ν΄λμ€λ₯Ό μ§μ ν΄ μμ²μ λ°μ μ μλ μνλ‘ λ§λλλ€. -
@GetMapping
,@PostMapping
λ±μΌλ‘ νΉμ URLκ³Ό HTTP Methodμ λ§λ μ²λ¦¬ λ©μλλ₯Ό μ°κ²°ν©λλ€. - λ©μλ λ΄μμλ ν΄λΌμ΄μΈνΈκ° λ³΄λΈ λ°μ΄ν°λ₯Ό λ°μ μ ν¨μ±μ κ²μ¬ν ν, μ²λ¦¬λ₯Ό μλΉμ€ κ³μΈ΅(Service Layer)μ μμν©λλ€.
- μλΉμ€λ‘λΆν° λ°μ κ²°κ³Όλ₯Ό ν΄λΌμ΄μΈνΈμκ² JSON λ°μ΄ν°λ HTML νλ©΄μ ννλ‘ λ°νν©λλ€.
β 4. Presentation Layerλ μ μ¬μ©νλμ?
κ°μ₯ μ€μν μ΄μ λ κ΄μ¬μ¬μ λΆλ¦¬(Separation of Concerns, SoC) λ₯Ό ν΅ν΄ μμ€ν μ λ 체κ³μ μ΄κ³ μ μ°νκ² λ§λ€κΈ° μν¨μ λλ€.
- μν κ³Ό μ± μ λͺ νν : μ΄ κ³μΈ΅μ βμΉ μμ²κ³Ό μ²λ¦¬βλΌλ μ± μλ§ κ°μ§λλ€. λλΆμ λΉμ¦λμ€ κ³μΈ΅μ βν΅μ¬ λ‘μ§ μ²λ¦¬βμλ§ μ§μ€ν μ μμ΄ μ½λ μ΄ν΄κ° μ¬μμ§λλ€.
- μ μ§λ³΄μ μ©μ΄μ± : νλ‘ νΈμνΈμ 보μ¬μ£Όλ λ°μ΄ν° νμμ λ³κ²½ν΄μΌ ν λ, λ€λ₯Έ λΉμ¦λμ€ λ‘μ§μ 건λλ¦¬μ§ μκ³ Presentation Layerλ§ μμ νλ©΄ λλ―λ‘ κ΄λ¦¬κ° νΈν©λλ€.
- μ μ°μ± λ° νμ₯μ± : μΉ(HTML)μΌλ‘ μλΉμ€λ₯Ό μ 곡νλ€κ° λͺ¨λ°μΌ μ±μ μν APIκ° μΆκ°λ‘ νμν΄μ Έλ, κΈ°μ‘΄ λΉμ¦λμ€ λ‘μ§μ κ·Έλλ‘ λκ³ μλ‘μ΄ Controllerλ§ μΆκ°νλ©΄ λλ―λ‘ νμ₯μ΄ μ©μ΄ν©λλ€.
β Controllerμ μν μ 무μμκ°μ?
Controllerμ ν΅μ¬ μν μ HTTP μμ²μ λ°μ, κ·Έμ λ§λ μλΉμ€(κΈ°λ₯)λ₯Ό νΈμΆνκ³ , μ²λ¦¬λ κ²°κ³Όλ₯Ό λ€μ μ¬μ©μμκ² μλ΅(Response)νλ κ²μ λλ€.
μ‘°κΈ λ ꡬ체μ μΌλ‘λ λ€μκ³Ό κ°μ μν μ λ΄λΉν©λλ€.
- μμ² μ μ (Endpoint Mapping) : μ¬μ©μκ° λ³΄λΈ URLκ³Ό HTTP Method(GET, POST λ±)λ₯Ό λ³΄κ³ , μ΄λ€ λ©μλκ° μ΄ μμ²μ μ²λ¦¬ν΄μΌ ν μ§ κ²°μ ν©λλ€.
- λ°μ΄ν° μμ λ° κ²μ¦ (Data Binding & Validation) : μ¬μ©μκ° λ³΄λΈ λ°μ΄ν°(μ: νμκ°μ μ 보)λ₯Ό μλ° κ°μ²΄λ‘ λ³ννκ³ , λ°μ΄ν°κ° μ ν¨νμ§(μ: μ΄λ©μΌ νμμ΄ λ§λμ§) κ²μ¬ν©λλ€.
- μλΉμ€μ μμ μμ (Delegate to Service) : Controllerλ λΉμ¦λμ€ λ‘μ§μ μ§μ μ²λ¦¬νμ§ μμ΅λλ€. λ°μ΄ν° μ²λ¦¬κ° νμν μ€μ μμ μ μλΉμ€(Service) κ³μΈ΅μ μμν©λλ€.
- κ²°κ³Ό λ°ν (Return Response) : μλΉμ€λ‘λΆν° λ°μ μ²λ¦¬ κ²°κ³Όλ₯Ό μ¬μ©μμκ² μ μ ν ννλ‘(μ£Όλ‘ JSON λλ HTML) λ³ννμ¬ λ°νν©λλ€.
π λΉμ : λ μ€ν λμ βμ¨μ΄ν°βμ κ°μ΅λλ€. μλ(Client)μ μ£Όλ¬Έ(Request)μ λ°μ μ£Όλ°©(Service)μ μ λ¬νκ³ , μμ±λ μ리(Data)λ₯Ό μλμκ² λ€μ μλΉ(Response)νλ μν μ ν©λλ€.
μ¨μ΄ν°κ° μ§μ μ리νμ§ μλ κ²μ²λΌ, Controllerλ μ§μ λΉμ¦λμ€ λ‘μ§μ μ²λ¦¬νμ§ μμ΅λλ€.
β Controllerλ μΈμ μ¬μ©νλμ?
μΉμ ν΅ν΄ μΈλΆμμ μ ν리μΌμ΄μ μ νΉμ κΈ°λ₯μ μ κ·Όν΄μΌ ν λ νμ μ¬μ©ν©λλ€.
- μ¬μ©μκ° μΉμ¬μ΄νΈμμ λ²νΌμ ν΄λ¦νκ±°λ νμ΄μ§λ₯Ό μμ²ν λ
- λͺ¨λ°μΌ μ±μμ μλ²μ λ°μ΄ν°λ₯Ό λΆλ¬μ€κ±°λ μ μ₯ν λ
- λ€λ₯Έ μλ²(μμ€ν )κ° μ°λ¦¬ μ ν리μΌμ΄μ μ APIλ₯Ό νΈμΆν λ
μ¦, ν΄λΌμ΄μΈνΈ(λΈλΌμ°μ , μ± λ±)μ μλ²μ λΉμ¦λμ€ λ‘μ§μ μ°κ²°νλ λͺ¨λ μ μ μμ Controllerκ° μ¬μ©λ©λλ€.
β Controllerλ μ΄λ»κ² μ¬μ©νλμ?
μ£Όλ‘ μ΄λ
Έν
μ΄μ
(@
)μ μ¬μ©νμ¬ ν΄λμ€μ λ©μλμ μν μ μ§μ νλ λ°©μμΌλ‘ μ¬μ©ν©λλ€.
μλλ κ°λ¨ν μ¬μ©μ μ 보 μ‘°ν APIμ Controller μμ μ½λμ λλ€.
// μ΄ ν΄λμ€κ° API μμ²μ μ²λ¦¬νλ Controllerμμ μ μΈν©λλ€.
// @RestControllerλ κ° λ©μλμ λ°ν κ°μ μλμΌλ‘ JSON ννλ‘ λ³νν΄μ€λλ€.
@RestController
public class UserController {
// λΉμ¦λμ€ λ‘μ§μ μ²λ¦¬ν UserServiceλ₯Ό μ°κ²°ν©λλ€. (μμ‘΄μ± μ£Όμ
)
private final UserService userService;
public UserController(UserService userService) {
this.userService = userService;
}
/**
* λͺ¨λ μ¬μ©μ λͺ©λ‘μ μ‘°ννλ API
* HTTPGET μμ² & URL "/api/users"μ λ§€νλ©λλ€.
*/
@GetMapping("/api/users")
public List<User> getAllUsers() {
// μ€μ λ°μ΄ν° μ‘°νλ Serviceμκ² μμν©λλ€.
return userService.findAllUsers();
}
/**
* νΉμ IDμ μ¬μ©μ ν λͺ
μ μ‘°ννλ API
* URL κ²½λ‘μ {id} λΆλΆμ νλΌλ―Έν°λ‘ λ°μ΅λλ€.
* μ: /api/users/1 -> id λ³μμ 1μ΄ λ΄κΉλλ€.
*/
@GetMapping("/api/users/{id}")
public User getUserById(@PathVariable Long id) {
// Serviceμκ² idλ₯Ό μ λ¬νμ¬ λ°μ΄ν° μ‘°νλ₯Ό μμν©λλ€.
return userService.findUserById(id);
}
}
μ½λ μ¬μ©λ² μμ½:
- ν΄λμ€ μμ
@RestController
λ₯Ό λΆμ¬ Controllerμμ λͺ μν©λλ€. - μμ²μ μ²λ¦¬ν λ©μλ μμ
@GetMapping
,@PostMapping
λ±μΌλ‘ μ΄λ€ HTTP μμ²κ³Ό URLμ μλ΅ν μ§ μ§μ ν©λλ€. - URLμ ν¬ν¨λ κ°μ
@PathVariable
λ‘, μμ² λ³Έλ¬Έμ λ΄κΈ΄ λ°μ΄ν°λ@RequestBody
λ‘ λ°μ΅λλ€. - μ²λ¦¬ν λ‘μ§μ
Service
κ°μ²΄μ λ©μλλ₯Ό νΈμΆνμ¬ μμν©λλ€. - λ©μλμ λ°ν κ°μ Springμ΄ μλμΌλ‘ ν΄λΌμ΄μΈνΈμκ² λ³΄λΌ μλ΅ λ°μ΄ν°(μ£Όλ‘ JSON)λ‘ λ§λ€μ΄ μ€λλ€.
β Controllerμ RestControllerμ μ°¨μ΄μ μ?
@RestController
λ @Controller
μ @ResponseBody
κ° μΆκ°λ κ²μΌλ‘, APIλ₯Ό λ§λ€ λ μ¬μ©ν©λλ€.
@Controller
μ @RestController
μ κ°μ₯ ν° μ°¨μ΄μ μ λ°ννλ κ°μ μ’
λ₯μ μμ΅λλ€.
-
@Controller : μ£Όλ‘ View(HTML νμ΄μ§) λ₯Ό λ°ννκΈ° μν΄ μ¬μ©ν©λλ€.
- λ©μλκ° λ¬Έμμ΄μ λ°ννλ©΄, Springμ κ·Έ λ¬Έμμ΄μ Viewμ μ΄λ¦μΌλ‘ ν΄μνμ¬ ν΄λΉ νλ©΄μ λ λλ§ν©λλ€.
- λ§μ½
@Controller
μμ JSON κ°μ λ°μ΄ν°λ₯Ό λ°ννλ €λ©΄, λ©μλμ@ResponseBody
μ΄λ Έν μ΄μ μ λ³λλ‘ λΆμ¬μ€μΌ ν©λλ€.
-
@RestController : λ°μ΄ν°(μ£Όλ‘ JSON, XML) λ₯Ό λ°ννκΈ° μν΄ μ¬μ©ν©λλ€.
- μ΄ μ΄λ
Έν
μ΄μ
μ
@Controller
+@ResponseBody
λ₯Ό ν©μ³ λμ κ² μ λλ€. - ν΄λμ€μ
@RestController
λ₯Ό λΆμ΄λ©΄, κ·Έ μμ λͺ¨λ λ©μλλ Viewκ° μλ λ°μ΄ν° μ체λ₯Ό λ°ννλ κ²μ΄ κΈ°λ³Έ λμμ΄ λ©λλ€. RESTful APIλ₯Ό λ§λ€ λ μ¬μ©λ©λλ€.
- μ΄ μ΄λ
Έν
μ΄μ
μ
κ΅¬λΆ | @Controller |
@RestController |
---|---|---|
μ£Όμ λͺ©μ | MVC ν¨ν΄μ View(νλ©΄) λ°ν | REST APIμ λ°μ΄ν°(JSON λ±) λ°ν |
λ©μλ λ°ν κ° | View μ΄λ¦ (String) | κ°μ²΄, λ°μ΄ν° (μλμΌλ‘ JSONμΌλ‘ λ³ν) |
@ResponseBody |
λ°μ΄ν° λ°ν μ, λ©μλμ λ³λ μΆκ° νμ | ν΄λμ€μ μλμΌλ‘ ν¬ν¨λμ΄ μμ΄ λΆνμ |
μ¬μ© μ¬λ‘ | μλ² μ¬μ΄λ λ λλ§ (JSP, Thymeleaf) μΉ νμ΄μ§ κ°λ° | λͺ¨λ°μΌ μ±, νλ‘ νΈμλ(React, Vue)μ μ°λνλ API κ°λ° |
β κ·Έ μΈ Presentation Layerμ μ»΄ν¬λνΈ
Controller μΈμλ Presentation Layerμμλ μμ²μ μ²λ¦¬νκ³ μμΈλ₯Ό κ΄λ¦¬νκΈ° μν μ¬λ¬ μ»΄ν¬λνΈλ₯Ό μ¬μ©ν©λλ€.
- @ControllerAdvice / @RestControllerAdvice : μ μ μμΈ μ²λ¦¬λ₯Ό λ΄λΉν©λλ€. μ¬λ¬ Controllerμμ λ°μνλ νΉμ μμΈ(Exception)λ€μ ν κ³³μμ 곡ν΅μΌλ‘ μ²λ¦¬ν μ μκ² ν΄μ€λλ€. μ½λ μ€λ³΅μ μ€μ΄κ³ μμΈ κ΄λ¦¬λ₯Ό μ€μννλ λ° νμμ μ λλ€.
-
@ExceptionHandler :
@Controller
λ@ControllerAdvice
ν΄λμ€ λ΄μμ νΉμ μμΈκ° λ°μνμ λ μ€νλ λ©μλλ₯Ό μ§μ νλ μ΄λ Έν μ΄μ μ λλ€. μλ₯Ό λ€μ΄,NullPointException
μ΄ λ°μνλ©΄ νΉμ μλ¬ νμ΄μ§λ JSON μλ΅μ 보λ΄λλ‘ μ²λ¦¬ν μ μμ΅λλ€. -
Filter / Interceptor : Controllerμ μμ²μ΄ λλ¬νκΈ° μ νμ 곡ν΅λ μμ
μ μ²λ¦¬νκΈ° μν΄ μ¬μ©λ©λλ€.
- Filter: μ¬μ©μμ μμ²/μλ΅ λ΄μ©μ λ³κ²½νκ±°λ, μΈμ½λ© λ³ν, μΈμ½λ© λ³ν, 보μ κ²μ¬ λ±μ μνν©λλ€. Spring νλ μμν¬ λ°κΉ₯μΈ Servlet λ¨κ³μμ λμν©λλ€.
- Interceptor: Filterμ μ μ¬νμ§λ§ Spring MVCμ μΌλΆμ λλ€. μ¬μ©μ μΈμ¦(λ‘κ·ΈμΈ) μ¬λΆλ₯Ό νμΈνκ±°λ, Controllerλ‘ λμ΄κ°λ λ°μ΄ν°μ μΆκ° μ 보λ₯Ό λνλ λ± λΉμ¦λμ€ λ‘μ§μ λ κ°κΉμ΄ μμ μ μ²λ¦¬ν λ μ¬μ©λ©λλ€.