Spring Boot์ Next.js๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๋ฐฑ์๋์ ํ๋ก ํธ์๋ ๋ชจ๋ ๋ค๋ฃฐ ์ ์์ผ๋ฉฐ,
RESTful API ์ค๊ณ, ๋ฐฐ์น ์ฒ๋ฆฌ, ๊ด๋ฆฌ์ ํ์ด์ง ๊ฐ๋ฐ, ์ฌ์ฉ์ ์๋น์ค ํ์ด์ง ๊ฐ๋ฐ, AWS ํด๋ผ์ฐ๋ ์ธํ๋ผ ์ด์๊น์ง
์ค๋ฌด ์ค์ฌ์ ๋ค์ํ ๊ฒฝํ์ ํตํด ์๋น์ค์ ์์๋ถํฐ ์ด์๊น์ง ์ฑ
์์ง๋ ๊ฐ๋ฐ์์
๋๋ค.
์๋น์ค๊ฐ๋ฐํ ยท ๋๋ฆฌ/๋งค๋์
๊ฐ๋ฐํ ยท ๋๋ฆฌ
๊ธฐ์ ์ง์ํ ยท ์ฃผ์
์ปค๋ฎค๋ํฐ ๊ธฐ๋ฐ ์ ๋ณด ๊ณต์ ํ๋ซํผ. Next.js์ Spring Boot๋ฅผ ํ์ฉํด ์์ ๊ฒ์ํ, ์ํ ์์, ์ง๋ ๊ฒ์ ๋ฑ ๋ค์ํ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ฉฐ, ์ฌ์ฉ์ ์ธ์ฆ ๋ฐ ๊ฒ์ํ CRUD, ์ด๋ฏธ์ง ์ ๋ก๋, ๊ฒ์๊ธ ์ถ์ฒ, ๋๊ธ ์์คํ ์ ๊ตฌํํ์ต๋๋ค.
ํค์๋ ๊ธฐ๋ฐ ๋ง์ง ์ง๋ ๊ฒ์ ๊ธฐ๋ฅ
TMDB API ๊ธฐ๋ฐ ์ํ ๋ชฉ๋ก ์กฐํ ๋ฐ ์ฅ๋ฅด ํํฐ๋ง
์ต์ ์ ์ ๋ ฌ ๋ฐ ์ข์์ ๊ธฐ๋ฅ ํฌํจ ๊ฒ์ํ ๋ชฉ๋ก
์์ ๊ฒ์ํ ๊ฒ์๊ธ ์์ธ ๋ฐ ๋๊ธ ์์ฑ UI
์๋ํฐ๋ฅผ ํ์ฉํ ๊ฒ์๊ธ ์์ฑ ๋ฐ ๋ฏธ๋ฆฌ๋ณด๊ธฐ
์ ํจ์ฑ ๊ฒ์ฌ ๋ฐ ํผ๋๋ฐฑ์ด ํฌํจ๋ ํ์๊ฐ์ ํ๋ฉด
๋ก๊ทธ์ธ ์คํจ ์ ์ฌ์ฉ์ ์๋ฆผ ์ฒ๋ฆฌ
์ฌ์ฉ์ ํ๋กํ ์กฐํ ๋ฐ ์ ๋ณด ์์ ๊ธฐ๋ฅ
NEXT.JS ๊ธฐ๋ฐ Frontend ํด๋ ๊ตฌ์กฐ์ ๋๋ค.
SPRING BOOT ๊ธฐ๋ฐ Backend ํด๋ ๊ตฌ์กฐ์ ๋๋ค.
// React Query๋ก ์์ ๊ฒ์ํ ๋ฆฌ์คํธ ์กฐํ
export function useFreeNoticeListQuery(page: number, sort: string, keyword: string) {
return useQuery({
queryKey: ['freeNotice', page, sort, keyword],
queryFn: () => getFreeNoticeList(page, sort, keyword),
})
}
// API ์์ฒญ ํจ์
async function getFreeNoticeList(page: number, sort: string, keyword: string) {
const query = new URLSearchParams({ page: page, sortType: sort, searchText: keyword })
const res = await fetch('API_URL/notice?query')
if (res.ok) return res.json()
if (res.status === 401) {
localStorage.clear()
window.location.href = '/account/login'
}
const error = await res.json()
throw new Error(error.message || 'Fetch error')
}
React Query๋ฅผ ํ์ฉํด ๊ฒ์ํ ๋ฆฌ์คํธ๋ฅผ ๋ถ๋ฌ์ค๋ฉฐ, ์ฟผ๋ฆฌ ํ๋ผ๋ฏธํฐ์ ๋ฐ๋ฅธ ๋ฐ์ดํฐ ์บ์ฑ ์ ๋ต์ ๊ตฌํํ์ต๋๋ค.
// Controller
@GetMapping("/list")
public ResSuccess<ResCommonList<List<ResFreeNotice>>> getFreeNoticeList(
@RequestParam int page,
@RequestParam String sortType,
@RequestParam String searchText) {
ResCommonList<List<ResFreeNotice>> list = freeNoticeService.getFreeNoticeList(page, sortType, searchText);
return new ResSuccess<>(list);
}
// Service
public ResCommonList<List<ResFreeNotice>> getFreeNoticeList(int page, String sortType, String searchText) {
Pageable pageable = PageRequest.of((page - 1), 10, getSort(sortType));
return selectFreeNoticeList(pageable, searchText);
}
// ์ค์ ๋ฐ์ดํฐ ์กฐํ
public ResCommonList<List<ResFreeNotice>> selectFreeNoticeList(Pageable pageable, String searchText) {
long count = freeNoticeRepository.countAllByTitleContains(searchText);
List<FreeNotice> list = freeNoticeRepository.findAllByTitleContains(searchText, pageable);
List<ResFreeNotice> dtoList = list.stream().map(freeNotice -> {
int recommendCount = noticeRecommendRepository.countByFreeNoticeIdx(freeNotice.getFreeNoticeIdx());
ResFreeNotice dto = NoticeConverter.toResFreeNotice(freeNotice);
dto.setRecommendCount(recommendCount);
return dto;
}).collect(Collectors.toList());
return new ResCommonList<>(count, dtoList);
}
๊ฒ์ํ ๋ฐ์ดํฐ๋ฅผ ๊ฒ์ ์กฐ๊ฑด๊ณผ ํ์ด์ง๋ค์ด์ ์ ๊ณ ๋ คํด ํจ์จ์ ์ผ๋ก ์กฐํํ๊ณ , DTO ๋ณํ๊ณผ ์ถ์ฒ ์๋ฅผ ํฌํจํ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํฉ๋๋ค.
๋ ๋์ ์ฑ์ฅ์ ๊ธฐํ๋ฅผ ํฅํด ๋์ ํ๊ณ ์์ต๋๋ค.
ํ์
๊ณผ ๊ธฐ์ ์ ์ง์ฌ์ธ ํ๊ณผ ํจ๊ปํ๊ณ ์ถ์ต๋๋ค.
๐ง Email: doo_style@naver.com
๐ฑ Phone: 010-2487-3788