[TIL] MVC : ์๋น์ค ๊ณ์ธต
๐๐ป Spring MVC : ์๋น์ค ๊ณ์ธต
๐ ์๋น์ค ๊ณ์ธต
- API ๊ณ์ธต์์ ์ ๋ฌ ๋ฐ์ ํด๋ผ์ด์ธํธ์ ์์ฒญ ๋ฐ์ดํฐ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์ค์ง์ ์ธ ๋น์ฆ๋์ค ์๊ตฌ์ฌํญ์ ์ฒ๋ฆฌํ๋ ๊ณ์ธต
- Spring DI๋ฅผ ํตํด API ๊ณ์ธต๊ณผ ๋น์ฆ๋์ค ๊ณ์ธต ์ฐ๋
- API ๊ณ์ธต์์ ์ ๋ฌ๋ฐ์ DTO ๊ฐ์ฒด๋ฅผ ๋น์ฆ๋์ค ๊ณ์ธต์ ๋๋ฉ์ธ ๋ชจ๋ธ ๊ฐ์ฒด๋ก ๋ณํํด์ ์ ๋ฌ
๐ก Spring MVC
- ์น ๊ณ์ธต์ ๋ด๋นํ๋ ๋ชจ๋๋ก ์๋ธ๋ฆฟ API๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํด๋ผ์ด์ธํธ ์ฒ๋ฆฌํ๋ ๋ชจ๋
- ํด๋ผ์ด์ธํธ ์์ฒญ์ ํธ๋ฆฌํ๊ฒ ์ฒ๋ฆฌํด์ฃผ๋ ํ๋ ์์ํฌ
- Model : ํด๋ผ์ด์ธํธ์ ์์ฒญ์ ์ฒ๋ฆฌํ ๊ฒฐ๊ณผ ๋ฐ์ดํฐ
- View : Model ๋ฐ์ดํฐ๋ฅผ ์ด์ฉํด ์น ๋ธ๋ผ์ฐ์ ๊ฐ์ ํด๋ผ์ด์ธํธ ํ๋ฉด์ ๋ณด์ฌ์ง๋ ๋ฆฌ์์ค ์ ๊ณต
- Controller : ํด๋ผ์ด์ธํธ ์ธก ์์ฒญ์ ์ง์ ๋ฐ๋ ์๋ํฌ์ธํธ๋ก Model๊ณผ View์ ์ํธ์์ฉ ์ญํ
โช๏ธโช๏ธ Spring MVC ๋์ ํ๋ฆ โช๏ธโช๏ธ
: ํด๋ผ์ด์ธํธ๊ฐ ์์ฒญ ๋ฐ์ดํฐ ์ ์ก → Controller๊ฐ ์์ฒญ ๋ฐ์ดํฐ ์์ → ๋น์ฆ๋์ค ๋ก์ง ์ฒ๋ฆฌ → Model ๋ฐ์ดํฐ ์์ฑ
→ Controller์๊ฒ Model ๋ฐ์ดํฐ ์ ๋ฌ → Controller๊ฐ View์๊ฒ Model ๋ฐ์ดํฐ ์ ๋ฌ → View๊ฐ ์๋ต ๋ฐ์ดํฐ ์์ฑ
๐ก 3-Tier Architeure
โ API ๊ณ์ธต (Controller, DTO)
โก ๋น์ฆ๋์ค ๊ณ์ธต (Model, Service)
โข ๋ฐ์ดํฐ ์์ธ์ค ๊ณ์ธต (Repository)
๐ DI๋ฅผ ํตํ API ๊ณ์ธต๊ณผ ์๋น์ค ๊ณ์ธต ์ฐ๋
- API ๊ณ์ธต์์ ๊ตฌํํ Controller ํด๋์ค๊ฐ ์๋น์ค ๊ณ์ธต์ Service ํด๋์ค์ ๋ฉ์๋ ํธ์ถ์ ํตํด ์ํธ์์ฉ ํ๋ค๋ ์๋ฏธ
- DTO๋ API ๊ณ์ธต์์ ํด๋ผ์ด์ธํธ์ ์์ฒญ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌ ๋ฐ๊ณ ํด๋ผ์ด์ธํธ์๊ฒ ๋๋๋ ค ์ค ์๋ต ๋ฐ์ดํฐ๋ฅผ ๋ด๋ ์ญํ
- ๋๋ฉ์ธ ์ํฐํฐ ํด๋์ค๋ API ๊ณ์ธต์์ ์ ๋ฌ ๋ฐ์ ์์ฒญ ๋ฐ์ดํฐ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์๋น์ค ๊ณ์ธต์์ ๋น์ฆ๋์ค ๋ก์ง์ ์ฒ๋ฆฌํ๊ธฐ ์ํด
ํ์ํ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌ ๋ฐ๊ณ ๋น์ฆ๋์ค ๋ก์ง ์ฒ๋ฆฌํ ๊ฒฐ๊ณผ ๊ฐ์ ๋ค์ API ๊ณ์ธต์ผ๋ก ์ ๋ฌ
๐ก Service
- ์ ํ๋ฆฌ์ผ์ด์ ์ ๋น์ฆ๋์ค ๋ก์ง์ ์ฒ๋ฆฌํ๊ธฐ ์ํ ์๋น์ค ๊ณ์ธต์ ๋๋ถ๋ถ ๋๋ฉ์ธ ๋ชจ๋ธ์ ํฌํจ
- ๋๋ฉ์ธ ์ ๋ฌด ์์ญ์ ๊ตฌํํ๋ ๋น์ฆ๋์ค ๋ก์ง ์ฒ๋ฆฌ
- ํด๋ผ์ด์ธํธ์ ์๊ตฌ์ฌํญ์ ์ ๋ง์กฑํ๋ Controllerํด๋์ค๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์ด์ ์ฐ๋ํ๋ Service ํด๋์ค๋ฅผ ๋ง๋๋ ๊ฒ
- Controller์ ํธ๋ค๋ฌ ๋ฉ์๋๊ฐ ์ ๋ฌ ๋ฐ์ ์์ฒญ์ ์ฒ๋ฆฌํ๋ ๋ฉ์๋๋ฅผ Service ํด๋์ค์ ์์ฑ
โช๏ธ ๋๋ฉ์ธ ๋ชจ๋ธ
- ๋น์ฝํ ๋๋ฉ์ธ ๋ชจ๋ธ + ํ๋ถํ ๋๋ฉ์ธ ๋ชจ๋ธ
- DDD(Domain Driven Design : ๋๋ฉ์ธ ์ฃผ๋ ์ค๊ณ)์ ๊ด๋ จ
โช๏ธ ๋๋ฉ์ธ ์ํฐํฐ ํด๋์ค
- ์๋น์ค ๊ณ์ธต์์ ๋ฐ์ดํฐ ์์ธ์ค ๊ณ์ธต๊ณผ ์ฐ๋ ํ๋ฉด์ ๋น์ฆ๋์ค ๋ก์ง์ ์ฒ๋ฆฌํ๊ธฐ ์ํด ํ์ํ ๋ฐ์ดํฐ๋ฅผ ๋ด๋ ์ญํ
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class Member {
private long memberId;
private String email;
private String name;
private String phone;
}
โธ @Getter, @Setter
: lombok ๋ผ์ด๋ธ๋ฌ๋ฆฌ์์ ์ ๊ณตํ๋ getter/setter ๋ฉ์๋๋ฅผ ์๋์ผ๋ก ์์ฑํด์ค
โธ @AllArgsConstructor
: ํ์ฌ Member ํด๋์ค์ ๋ชจ๋ ๋ฉค๋ฒ ๋ณ์๋ฅผ ํ๋ผ๋ฏธํฐ๋ก ๊ฐ๋ Member ์์ฑ์๋ฅผ ์๋ ์์ฑ
โธ @NoArgsConstructor
: ํ๋ผ๋ฏธํฐ๊ฐ ์๋ ๊ธฐ๋ณธ ์์ฑ์๋ฅผ ์๋ ์์ฑ
๐ก Spring Bean ๋ฑ๋ก
- Controller ํด๋์ค์ @RestController์ ์ถ๊ฐํ๋ฉด ์๋ ๋ฑ๋ก
- Service ํด๋์ค์ @Service๋ฅผ ์ถ๊ฐํ๋ฉด ์๋ ๋ฑ๋ก
- ์์ฑ์ ๋ฐฉ์์ DI๋ ์์ฑ์๊ฐ ํ๋์ผ ๊ฒฝ์ฐ @Autowired๋ฅผ ์ถ๊ฐํ์ง ์์๋ DI ์ ์ฉ
๐ Mapper๋ฅผ ํตํ DTO ํด๋์ค์ Entity ํด๋์ค ๋งคํ
โ๐ป Controller์ ํธ๋ค๋ฌ ๋ฉ์๋๊ฐ 'DTOํด๋์ค๋ฅผ ์ํฐํฐ ํด๋์ค๋ก ๋ณํํ๋ ์์ '
→ ๋ค๋ฅธ ํด๋์ค์๊ฒ ๋ณํํด ๋ฌ๋ผ๊ณ ์์ฒญํ๊ธฐ
โ๐ป ์ํฐํฐ ํด๋์ค ๊ฐ์ฒด ์์ฒด๋ฅผ ์๋ต์ ์ ์กํ์ฌ '๊ณ์ธต ๊ฐ ์ญํ ๋ถ๋ฆฌ X'
→ ์ํฐํฐ ํด๋์ค ๊ฐ์ฒด๋ฅผ DTO ํด๋์ค ๊ฐ์ฒด๋ก ๋ณํ
์ฆ, DTO ํด๋์ค์ ์ํฐํฐ ํด๋์ค๋ฅผ ๋ณํํด์ฃผ๋ ๋งคํผ(Mapper)๊ฐ ํ์ !
โช๏ธ MapStruct
- ๋งคํผ ๊ตฌํ ํด๋์ค๋ฅผ ์๋์ผ๋ก ์์ฑํด์ฃผ๋ ์ฝ๋ ์๋ ์์ฑ๊ธฐ
- ๋งคํผ๋ฅผ ์ง์ ๊ตฌํํ ์๋ ์์ง๋ง MapStrut ๊ฐ์ ๋งคํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ์์ฐ์ฑ ์ธก๋ฉด์์ ๋ ์ฐ์
- ๋งคํผ๋ฅผ ์๋์ผ๋ก ์์ฑํ๊ธฐ ์ํด์๋ ๋งคํผ ์ธํฐํ์ด์ค ์ ์๊ฐ ํ์ํจ
@Mapper(componentModel = "spring")
public interface MemberMapper{
Mapperํด๋์ค์์
์์์
์ผ๋ก ๊ตฌํํ๋ ๋ฉ์๋๋ค ๊ตฌํ
}
โธ @Mapper
- ์ ๋ํ ์ด์ ์ ์ถ๊ฐํ๋ฉด MapStruct์ ๋งคํผ ์ธํฐํ์ด์ค๋ก ์ ์๋จ
- componentModel = "spring" ์ ์ง์ ํด์ฃผ์ด์ผ ์คํ๋ง์ ๋น์ผ๋ก ๋ฑ๋ก๋จ
- ์ธํฐํ์ด์ค๋ฅผ ์ ์ํ๋ฉด ์ธํฐํ์ด์ค์ ๊ตฌํ ํด๋์ค๋ MapStruct๊ฐ MemberMapper ์ธํฐํ์ด์ค ๊ธฐ๋ฐ์ผ๋ก
๋งคํผ ๊ตฌํ ํด๋์ค ์๋ ์์ฑํด์ค
→ ์๋ ์์ฑ๋ Mapper ์ธํฐํ์ด์ค ๊ตฌํ ํด๋์ค ํ์ธ : Gradle์ build task ์คํ
๐ก DTO ํด๋์ค์ ์ํฐํฐ ํด๋์ค ์ญํ ๋ถ๋ฆฌ ํ์ ์ด์
โ ๊ณ์ธต๋ณ ๊ด์ฌ์ฌ์ ๋ถ๋ฆฌ
- ๊ธฐ๋ฅ์ ๋ํ ๊ด์ฌ์ฌ๊ฐ ๋ค๋ฆ
- DTO ํด๋์ค๋ API ๊ณ์ธต์์ ์์ฒญ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌ๋ฐ๊ณ ์๋ต ๋ฐ์ดํฐ๋ฅผ ์ ์กํ๋ ๊ฒ์ด ์ฃผ๋ ๋ชฉ์
- Entitiy ํด๋์ค๋ ์๋น์ค ๊ณ์ธต์์ ๋ฐ์ดํฐ ์์ธ์ค ๊ณ์ธต๊ณผ ์ฐ๋ํ์ฌ ๋น์ฆ๋์ค ๋ก์ง์ ๊ฒฐ๊ณผ๋ก ์์ฑ๋ ๋ฐ์ดํฐ ๋ค๋ฃธ์ด ์ฃผ๋ ๋ชฉ์
โก ์ฝ๋ ๊ตฌ์ฑ์ ๋จ์ํ
- DTO ํด๋์ค์ ์ ํจ์ฑ ์ ๋ํ ์ด์ ์ด Entity ํด๋์ค์์ ์ฌ์ฉ๋๋ค๋ฉด JPA์์ ์ฌ์ฉํ๋ ์ ๋ํ ์ด์ ๊ณผ ๋ค์์ฌ ์ ์ง๋ณด์ ์ด๋ ค์
โข REST API ์คํ์ ๋ ๋ฆฝ์ฑ ํ๋ณด
- Entity ํด๋์ค๋ฅผ ๊ทธ๋๋ก ์๋ต์ผ๋ก ์ ๋ฌํ๊ฒ ๋๋ฉด ์์น ์๋ ๋ฐ์ดํฐ๊น์ง ์ ์ก๋ ์ ์์