Vue.js 3 & NodeJS/NodeJS

Node.js 레스트 API 데이터 업데이트(내용, 이미지, 카테고리, 조회 수) - Node.js REST API, Board-API Data Update

carrotweb 2022. 4. 24. 18:24
728x90
반응형

먼저 router.get('/') 라우터에서 페이지네이션 처리 코딩과 정렬 처리 코딩이 있어 복잡해 보입니다. 그래서 페이지네이션 처리 코딩과 정렬 코딩을 분리하여 함수로 생성하고 적용하겠습니다.

C:\workspaces\nodeserver\testrestapi\boardapi.js 파일을 오픈하여  페이지네이션 처리 코딩을 분리하여 함수로 생성합니다.

// 게시물 페이지네이션
function pagination(totalCount, countPerPage, pageSize, pageNo) {
	// 페이지네이션 정보
	var paginationInfo = {};
	
	// 마지막 페이지 번호(전체 페이지 크기)
	var lastPageNo = Math.floor(totalCount / countPerPage) + (totalCount % countPerPage== 0 ? 0 : 1);
	// 시작 페이지 번호
	var startPageNo = 1;
	// 페이지 사이즈로 페이지 번호를 나눈 몫만큼 페이지 시작 번호 변경
	var start = Math.floor(pageNo / pageSize);
	if (start >= 1) {
		// 그렇지만 나머지가 없으면 현재 페이지 번호가 마지막 페이지 번호와 같아 감소
		if (pageNo % pageSize == 0){
			start--;
		}
		startPageNo = (start * pageSize) + 1;
	}
	// 종료 페이지 번호
	var endPageNo = (startPageNo - 1) + pageSize;
	// 그렇지만 종료 페이지 번호가 마지막 페이지 번호보다 크면 마지막 페이지 번호로 변경
	if (endPageNo > lastPageNo) {
		endPageNo = lastPageNo;
	}
	// 이전 페이지 번호 활성화 여부
	var enablePrevPageNo = true;
	if ((pageNo - 1) == 0) {
		enablePrevPageNo = false;
	}
	// 다음 페이지 번호 활성화 여부
	var enableNextPageNo = true;
	if ((pageNo + 1) > lastPageNo) {
		enableNextPageNo = false;
	}
	// 이전 페이지 사이즈 번호
	var prevPageSizeNo = startPageNo - 1;
	// 이전 페이지 사이즈 번호 활성화 여부
	var enablePrevPageSizeNO = true;
	if (prevPageSizeNo == 0) {
		enablePrevPageSizeNO = false;
	}
	// 다음 페이지 사이즈 번호
	var nextPageSizeNo = endPageNo + 1;
	// 다음 페이지 사이즈 번호 활성화 여부
	var enableNextPageSizeNO = true;
	if (nextPageSizeNo > lastPageNo) {
		enableNextPageSizeNO = false;
	}
	
	// 페이지네이션 정보
	paginationInfo.totalCount = totalCount;
	paginationInfo.countPerPage = countPerPage;
	paginationInfo.pageSize = pageSize;
	paginationInfo.startPageNo = startPageNo;
	paginationInfo.endPageNo = endPageNo;
	paginationInfo.lastPageNo = lastPageNo;
	paginationInfo.pageNo = pageNo;
	paginationInfo.enablePrevPageNo = enablePrevPageNo;
	paginationInfo.enableNextPageNo = enableNextPageNo;
	paginationInfo.prevPageSizeNo = prevPageSizeNo;
	paginationInfo.enablePrevPageSizeNO = enablePrevPageSizeNO;
	paginationInfo.nextPageSizeNo = nextPageSizeNo;
	paginationInfo.enableNextPageSizeNO = enableNextPageSizeNO;
	
	return paginationInfo;
}

 

그리고 정렬 처리 코딩도 분리하여 함수로 생성합니다.

// 게시물 정렬
function sortBy(boardList, sortby) {
	// 정렬 배열
	var arSortby = null;
	
	if (sortby == undefined || typeof sortby == "undefined" || sortby == null) {
		arSortby = [];
	} else {
		arSortby = sortby.split(",");
	}
	
	if (arSortby.length > 0) {
		boardList.sort(function(comp1, comp2) {
			var result = 0;
			for (var index = 0; index < arSortby.length; index++) {
				if (hashmapSortby[arSortby[index]] != null) {
					result = hashmapSortby[arSortby[index]](comp1, comp2);
					if (result == 0) {
						continue;
					} else {
						break;
					}
				}
			}
			return result;
		});
	}
}

 

페이지네이션 함수와 정렬 함수를 router.get('/') 라우터에 적용합니다. 추가로  전체 게시물을 리턴하지 않게 pageNo를  0이 아닌 1로 기본값 처리하였습니다.

router.get('/', function(req, res, next) {
	console.log("REST API Get Method - Read All");
	
	// 필터된 게시판
	var filteredBoardList = filtering(req, boardList);
	
	// 정렬
	var sortby = req.query.sortby;
	sortBy(filteredBoardList, sortby);
	
	// 페이지 크기
	var countPerPage = req.query.countperpage;
	// 페이지 번호
	var pageNo = req.query.pageno;
	// 페이지 사이즈
	var pageSize = req.query.pagesize;
	
	if (countPerPage == undefined || typeof countPerPage == "undefined" || countPerPage == null) {
		countPerPage = 10;
	} else {
		countPerPage = parseInt(countPerPage);
	}
	if (pageSize == undefined || typeof pageSize == "undefined" || pageSize == null) {
		pageSize = 10;
	} else {
		pageSize = parseInt(pageSize);
	}
	if (pageNo == undefined || typeof pageNo == "undefined" || pageNo == null) {
		pageNo = 1;
	} else {
		pageNo = parseInt(pageNo);
	}
	
	// 전체 크기
	var totalCount = filteredBoardList.length;
	
	// 페이지네이션 정보
	var paginationInfo = pagination(totalCount, countPerPage, pageSize, pageNo);
	
	// 시작 번호
	var startItemNo = ((pageNo - 1) * countPerPage);
	// 종료 번호
	var endItemNo = (pageNo * countPerPage) - 1;
	// 종료 번호가 전체 크기보다 크면 전체 크기로 변경
	if (endItemNo > (totalCount - 1)) {
		endItemNo = totalCount - 1;
	}
	
	var boardPageList = [];
	if (startItemNo < totalCount) {
		for (var index = startItemNo; index <= endItemNo; index++) {
			boardPageList.push(filteredBoardList[index]);
		}
	}
	
	res.json({success:true, data:boardPageList, pagination:paginationInfo});
});

 

 

현재 리턴되는 게시물 리스트에는 게시물 내용 전체가 포함되어 있습니다.

페이스북, 인스타그램처럼 게시물 내용이 적고(입력 문자 수 지정) UI에 게시물 내용이 포함되어 있으면 문제가 없지만 블로그처럼 게시물 내용이 많으면 서버와 네트워크에 부하가 발생합니다. 그래서 게시물 리스트에서는 게시물 전체 내용이 아닌 일부 내용(약 100자 이내)만 전달하는 것이 좋습니다. 그래서 boardPageList를 만들 때 수정 처리하겠습니다.

 

그리고 현재 초기 데이터에는 게시물 제목과 내용에 동일하게 번호를 제외하고는 "테스트 제목", "테스트 내용"으로 되어있습니다. 그래서 Vue에서 화면 처리 시 처리할 내용이 없고 UI를 구성하기에도 내용이 부족합니다.

 

그래서 초기 데이터의 내용을 블로그처럼 제목과 내용을 변경하고 게시물에 이미지와 카테고리, 조회 수를 추가하도록 하겠습니다.

 

 

블로그처럼 초기 데이터 변경

 

1. C:\workspaces\nodeserver\testrestapi\boardapi.js 파일을 오픈하여 배열에 있는 초기 데이터에 내용을 블로그처럼 변경합니다.

블로그처럼 내용을 만들기 위해서는 내용의 분류가 필요합니다. 그래서 카테고리를 생성합니다.

let categoryList = ["전체", "일상", "쇼핑", "노하우", "애견/반려동물"];

 

카테고리는 블로그에서 많이 사용하는 분류 중 일부만 가져왔습니다. "전체"는 분류로 사용되지 않습니다.

그리고 카테고리에 맞게 내용을 변경합니다. 그리고 게시물에 category를 추가합니다.
블로그 내용처럼 만드는데 시간이 좀 걸렸습니다.

let boardList = [
{no:1, subject:"나의 일상 정리", content:"요즘 뭔가 평소보다 이상하게 시간이 더 빠르게 지나간것 같기도 하고 날씨도 좋아진것 같기도 하고 뭐 빠르게 지나가는 것 같습니다.\n아무튼 내 일상을 간만에 끄적여봅니다.", writer:"testid1", writedate:"2021-08-09 13:00:00", category:1},
{no:2, subject:"아이스크림 틀 리뷰~ 집에서 즐겨요.", content:"안녕하세요. 맘입니다.^^\n날씨가 더워지는 요즘 아이들이 시원한 음료수나 아이스크림을 많이 찾습니다.\n그래서 음료수로 간단하게 아이스크림을 만들 수 있는 틀을 리뷰하려고 합니다.", writer:"testid2", writedate:"2021-08-09 13:10:00", category:2},
{no:3, subject:"도배 쉽게 하는 방법", content:"오늘은 도배지의 종류와 도배하는 방법, 부분 도배하는 방법을 알려드리겠습니다.\n도배지 종 및 특징\n실크(PVC) 벽지, 합지(종이) 벽지, 천연 벽지, 뮤럴(벽화) 벽지, 방염 벽지 등이 있습니다.", writer:"testid3", writedate:"2021-08-09 13:20:00", category:3},
{no:4, subject:"2022 반려동물 박람회 후기", content:"2022 팻페어 반려동물 박람회를 다녀온 후기입니다.\n3일간 일산에서 반려동물 박람회가 열렸어요~!!\n구경거리도 많고 저렴하게 간식을 구매할 수 있어 좋았습니다.", writer:"testid1", writedate:"2022-03-26 14:00:00", category:4},
{no:5, subject:"가평 애견펜션 - 아침고요수목원 근처", content:"봄맞이 나들이 겸 댕댕이 퍼피와 함께 아침고요수목원 근처에 있는 애견펜션에 놀러 갔어요.\n아침고요수목원 근처라 찾아가기 쉽고 사장님도 친절하십니다.", writer:"testid2", writedate:"2022-03-26 15:10:00", category:4},
{no:6, subject:"모종심기와 화분 분갈이 방법", content:"예전에 배란다를 보니 화초들이 상태가 말이 아니더라고요.\n이러면 안되겠다는 생각이 들어서 조금씩 관리하기 시작하였습니다.\n저와 같은 분들이 많이 있을 것 같아서 저만의 화초 관리 노하우를 알려드리고 합니다.", writer:"testid3", writedate:"2022-03-26 16:20:00", category:3},
{no:7, subject:"포켓몬 득템", content:"친구한테 받은 편의점 1만원 모바일상품권으로 편의점에 간식 사러 들렸습니다.\n그런데 운이 좋았는지 포켓몬 빵이 하나 남아 있었습니다. 망설임 없이 바로 빵과 과자, 음료수 구매했습니다.", writer:"testid1", writedate:"2022-03-26 17:30:00", category:1},
{no:8, subject:"휴대용 UV 살균기", content:"코로나로 집 받을 나갔다오면 핸드폰부터 가방, 옷까지 혹시나 하는 생각에 찜찜함이 있었다.\n그래서 쇼핑몰을 검색해보니 UV 살균기를 휴대할 수 있는 제품들이 많이 있었다.\n그 중에서 모바일과 연결하여 사용할 수 있는 제품이 있어 구매하였다.", writer:"testid2", writedate:"2022-03-26 18:40:00", category:2},
{no:9, subject:"이케아 광명점에서 폭풍 구매", content:"안녕하세요! ㅎㅎ 오랜만에 일상으로 인사드립니다.\n사실 집에만 있다가 코에 바람도 넣을 겸 드라이브도 할 겸 이케아 광명점에 왔습니다.\n오늘 이케아에서 폭풍 구매한 내역을 공개하고자 합니다.", writer:"testid3", writedate:"2022-03-26 19:50:00", category:1},
{no:10, subject:"통밀과자 만들기 체험", content:"오늘은 강원도에 있는 통밀과자를 만들 수 있는 체험장을 다녀왔습니다.\n아침 9시부터 11시까지 두시간 동안 가족들과 함께 빵 체험과 통밀과자를 만들었습니다.", writer:"testid1", writedate:"2022-03-26 21:00:00", category:1},
{no:11, subject:"애견동반 가능한 카페", content:"이번에는 전주에 갔을 때 반련견과 함께 갈 수 있는 카페를 몇 군데 다녀왔습니다.\n오늘 방문한 곳 중 하나인데요.\n제 마음에 쏙 꽂혀버린 카페입니다.", writer:"testid2", writedate:"2022-03-27 00:30:00", category:4},
{no:12, subject:"혼자하는 에어컨 청소법", content:"에어컨 커버없이 관리되는 에어컨들은 냉기가 나오는 입구에 먼지가 많이 쌓이게 됩니다.\n이런 먼지들을 쉽고 간편하게 청소하는 방법이 있어 알려드립니다.", writer:"testid3", writedate:"2022-03-27 00:30:00", category:3},
{no:13, subject:"푸짐하고 맛이 괜찮았던 국물 라뽁이", content:"안녕하세요. 저는 우리나라에서 파는 모든 국물 라뽁이를 먹고 소개드리고자 하는 라짱입니다.\n저는 주말을 맞아 국물맛 괜찮은 라뽁이를 리뷰해 드리고자 합니다.", writer:"testid1", writedate:"2022-03-27 00:30:00", category:2}
];

 

블로그처럼 내용이 각각 다르니 괜찮아 보입니다.

 

그렇지만 게시물 내용에 대표 이미지가 없으니 허전합니다. 그래서 대표 이지지를 추가하겠습니다.

 

2. C:\workspaces\nodeserver\testrestapi\index.js 파일을 오픈하여 외부에서 접근 가능한 공유 폴더를 추가합니다. 그리고 C:\workspaces\nodeserver\testrestapi 폴더에 public 폴더를 생성합니다.

app.use(express.static('public'));

 

스크립트 파일이나 이미지 파일, HTML 파일, 문서 파일 등 다양한 파일들이 추가될 수 있게 C:\workspaces\nodeserver\testrestapi\public 폴더에 asset 폴더를 생성합니다.

그리고 게시물 내용에 첨부되는 이미지들이 저장되는 폴더를 생성합니다. (향후에 게시판 에디터에서 이미지 파일 업로드 폴더로 사용됩니다.)
C:\workspaces\nodeserver\testrestapi\public\asset 폴더에 board 폴더와 board 폴더 안에 files 폴더를 생성합니다.

C:\workspaces\nodeserver\testrestapi\public\asset\board\files 폴더에 게시물에서 사용할 대표 이미지를 추가합니다.

 

초기 데이터에 대표 이미지를 poster로 추가합니다. 그리고 조회 수를 viewcount로 추가합니다.

let boardList = [
{no:1, subject:"나의 일상 정리", content:"요즘 뭔가 평소보다 이상하게 시간이 더 빠르게 지나간것 같기도 하고 날씨도 좋아진것 같기도 하고 뭐 빠르게 지나가는 것 같습니다.\n아무튼 내 일상을 간만에 끄적여봅니다.", writer:"testid1", writedate:"2021-08-09 13:00:00", poster:"1.png", viewcount: 10, category:1},
{no:2, subject:"아이스크림 틀 리뷰~ 집에서 즐겨요.", content:"안녕하세요. 맘입니다.^^\n날씨가 더워지는 요즘 아이들이 시원한 음료수나 아이스크림을 많이 찾습니다.\n그래서 음료수로 간단하게 아이스크림을 만들 수 있는 틀을 리뷰하려고 합니다.", writer:"testid2", writedate:"2021-08-09 13:10:00", poster:"2.png", viewcount: 10, category:2},
{no:3, subject:"도배 쉽게 하는 방법", content:"오늘은 도배지의 종류와 도배하는 방법, 부분 도배하는 방법을 알려드리겠습니다.\n도배지 종 및 특징\n실크(PVC) 벽지, 합지(종이) 벽지, 천연 벽지, 뮤럴(벽화) 벽지, 방염 벽지 등이 있습니다.", writer:"testid3", writedate:"2021-08-09 13:20:00", poster:"3.png", viewcount: 10, category:3},
{no:4, subject:"2022 반려동물 박람회 후기", content:"2022 팻페어 반려동물 박람회를 다녀온 후기입니다.\n3일간 일산에서 반려동물 박람회가 열렸어요~!!\n구경거리도 많고 저렴하게 간식을 구매할 수 있어 좋았습니다.", writer:"testid1", writedate:"2022-03-26 14:00:00", poster:"4.png", viewcount: 20, category:4},
{no:5, subject:"가평 애견펜션 - 아침고요수목원 근처", content:"봄맞이 나들이 겸 댕댕이 퍼피와 함께 아침고요수목원 근처에 있는 애견펜션에 놀러 갔어요.\n아침고요수목원 근처라 찾아가기 쉽고 사장님도 친절하십니다.", writer:"testid2", writedate:"2022-03-26 15:10:00", poster:"5.png", viewcount: 30, category:4},
{no:6, subject:"모종심기와 화분 분갈이 방법", content:"예전에 배란다를 보니 화초들이 상태가 말이 아니더라고요.\n이러면 안되겠다는 생각이 들어서 조금씩 관리하기 시작하였습니다.\n저와 같은 분들이 많이 있을 것 같아서 저만의 화초 관리 노하우를 알려드리고 합니다.", writer:"testid3", writedate:"2022-03-26 16:20:00", poster:"6.png", viewcount: 40, category:3},
{no:7, subject:"포켓몬 득템", content:"친구한테 받은 편의점 1만원 모바일상품권으로 편의점에 간식 사러 들렸습니다.\n그런데 운이 좋았는지 포켓몬 빵이 하나 남아 있었습니다. 망설임 없이 바로 빵과 과자, 음료수 구매했습니다.", writer:"testid1", writedate:"2022-03-26 17:30:00", poster:"7.png", viewcount: 50, category:1},
{no:8, subject:"휴대용 UV 살균기", content:"코로나로 집 받을 나갔다오면 핸드폰부터 가방, 옷까지 혹시나 하는 생각에 찜찜함이 있었다.\n그래서 쇼핑몰을 검색해보니 UV 살균기를 휴대할 수 있는 제품들이 많이 있었다.\n그 중에서 모바일과 연결하여 사용할 수 있는 제품이 있어 구매하였다.", writer:"testid2", writedate:"2022-03-26 18:40:00", poster:"8.png", viewcount: 60, category:2},
{no:9, subject:"이케아 광명점에서 폭풍 구매", content:"안녕하세요! ㅎㅎ 오랜만에 일상으로 인사드립니다.\n사실 집에만 있다가 코에 바람도 넣을 겸 드라이브도 할 겸 이케아 광명점에 왔습니다.\n오늘 이케아에서 폭풍 구매한 내역을 공개하고자 합니다.", writer:"testid3", writedate:"2022-03-26 19:50:00", poster:"9.png", viewcount: 70, category:1},
{no:10, subject:"통밀과자 만들기 체험", content:"오늘은 강원도에 있는 통밀과자를 만들 수 있는 체험장을 다녀왔습니다.\n아침 9시부터 11시까지 두시간 동안 가족들과 함께 빵 체험과 통밀과자를 만들었습니다.", writer:"testid1", writedate:"2022-03-26 21:00:00", poster:"10.png", viewcount: 80, category:1},
{no:11, subject:"애견동반 가능한 카페", content:"이번에는 전주에 갔을 때 반련견과 함께 갈 수 있는 카페를 몇 군데 다녀왔습니다.\n오늘 방문한 곳 중 하나인데요.\n제 마음에 쏙 꽂혀버린 카페입니다.", writer:"testid2", writedate:"2022-03-27 00:30:00", poster:"11.png", viewcount: 15, category:4},
{no:12, subject:"혼자하는 에어컨 청소법", content:"에어컨 커버없이 관리되는 에어컨들은 냉기가 나오는 입구에 먼지가 많이 쌓이게 됩니다.\n이런 먼지들을 쉽고 간편하게 청소하는 방법이 있어 알려드립니다.", writer:"testid3", writedate:"2022-03-27 00:30:00", poster:"12.png", viewcount: 20, category:3},
{no:13, subject:"푸짐하고 맛이 괜찮았던 국물 라뽁이", content:"안녕하세요. 저는 우리나라에서 파는 모든 국물 라뽁이를 먹고 소개드리고자 하는 라짱입니다.\n저는 주말을 맞아 국물맛 괜찮은 라뽁이를 리뷰해 드리고자 합니다.", writer:"testid1", writedate:"2022-03-27 00:30:00", poster:"13.png", viewcount: 25, category:2}
];

 

 

3. router.get('/') 라우터에 게시물 내용을 전체가 아닌 100자 이내로 줄여서 처리합니다.
게시물 내용이 100자 이상이면 100자까지만 가져오고 100자 미만이면 전체를 가져옵니다.
그리고 게시물 대표 이미지 파일은 위에서 생성한 게시판 파일 폴더 경로(/asset/board/files/)를 결합합니다.
그리고 category를 categoryList 배열을 사용하여 문자열로 변환합니다.

router.get('/', function(req, res, next) {
	console.log("REST API Get Method - Read All");
	
	// 필터된 게시판
	var filteredBoardList = filtering(req, boardList);
	
	// 정렬
	var sortby = req.query.sortby;
	sortBy(filteredBoardList, sortby);
	
	// 페이지 크기
	var countPerPage = req.query.countperpage;
	// 페이지 번호
	var pageNo = req.query.pageno;
	// 페이지 사이즈
	var pageSize = req.query.pagesize;
	
	if (countPerPage == undefined || typeof countPerPage == "undefined" || countPerPage == null) {
		countPerPage = 10;
	} else {
		countPerPage = parseInt(countPerPage);
	}
	if (pageSize == undefined || typeof pageSize == "undefined" || pageSize == null) {
		pageSize = 10;
	} else {
		pageSize = parseInt(pageSize);
	}
	if (pageNo == undefined || typeof pageNo == "undefined" || pageNo == null) {
		pageNo = 1;
	} else {
		pageNo = parseInt(pageNo);
	}
	
	// 전체 크기
	var totalCount = filteredBoardList.length;
	
	// 페이지네이션 정보
	var paginationInfo = pagination(totalCount, countPerPage, pageSize, pageNo);
	
	// 시작 번호
	var startItemNo = ((pageNo - 1) * countPerPage);
	// 종료 번호
	var endItemNo = (pageNo * countPerPage) - 1;
	// 종료 번호가 전체 크기보다 크면 전체 크기로 변경
	if (endItemNo > (totalCount - 1)) {
		endItemNo = totalCount - 1;
	}
	
	var boardPageList = [];
	if (startItemNo < totalCount) {
		for (var index = startItemNo; index <= endItemNo; index++) {
			var filteredBoardItem = filteredBoardList[index];
			
			var boardPageItem = {};
			boardPageItem.no = filteredBoardItem.no;
			boardPageItem.subject = filteredBoardItem.subject;
			if (filteredBoardItem.content.length > 100) {
				boardPageItem.content = filteredBoardItem.content.substr(0, 100);
			} else {
				boardPageItem.content = filteredBoardItem.content;
			}
			boardPageItem.writer = filteredBoardItem.writer;
			boardPageItem.writedate = filteredBoardItem.writedate;
			boardPageItem.poster = "/asset/board/files/" + filteredBoardItem.poster;
			boardPageItem.viewcount = filteredBoardItem.viewcount;
			boardPageItem.categoryText = categoryList[filteredBoardItem.category];

			boardPageList.push(boardPageItem);
		}
	}
	
	res.json({success:true, data:boardPageList, pagination:paginationInfo});
});

 

4. router.get('/') 라우터 위에 정렬 해시맵(HashMap)에 조회 수 정렬을 위한 compareFunction 함수들을 추가합니다.

// 조회 수 오름차순 정렬
hashmapSortby["viewcount.asc"] = function(comp1, comp2) {
	var comp1UC = comp1.viewcount;
	var comp2UC = comp2.viewcount;
	if (comp1UC < comp2UC) {
		return -1;
	} else if (comp1UC > comp2UC) {
		return 1;
	}
	return 0;
};

// 조회 수 내림차순 정렬
hashmapSortby["viewcount.desc"] = function(comp1, comp2) {
	var comp1UC = comp1.viewcount
	var comp2UC = comp2.viewcount
	if (comp1UC < comp2UC) {
		return 1;
	} else if (comp1UC > comp2UC) {
		return -1;
	}
	return 0;
};

 

5. 콘솔을 실행하고 Node.js 레스트 API 서버 프로젝트가 있는 C:\workspaces\nodeserver\testrestapi 폴더로 이동합니다. 그리고 npm run 명령어를 실행합니다.

npm run start

 

6. Postman(포스트맨)를 실행하여 테스트합니다.

 

반응형

 

 

Postman(포스트맨)를 이용하여 REST API 테스트

 

Get Method - 테스트

http://localhost:9000/boards?countperpage=3&pageno=1

변경된 내용으로 처리된 것을 확인할 수 있습니다.

{
    "success": true,
    "data": [
        {
            "no": 1,
            "subject": "나의 일상 정리",
            "content": "요즘 뭔가 평소보다 이상하게 시간이 더 빠르게 지나간것 같기도 하고 날씨도 좋아진것 같기도 하고 뭐 빠르게 지나가는 것 같습니다.\n아무튼 내 일상을 간만에 끄적여봅니다.",
            "writer": "testid1",
            "writedate": "2021-08-09 13:00:00",
            "poster": "/asset/board/files/1.png",
            "viewcount": 10,
            "categoryText": "일상"
        },
        {
            "no": 2,
            "subject": "아이스크림 틀 리뷰~ 집에서 즐겨요.",
            "content": "안녕하세요. 맘입니다.^^\n날씨가 더워지는 요즘 아이들이 시원한 음료수나 아이스크림을 많이 찾습니다.\n그래서 음료수로 간단하게 아이스크림을 만들 수 있는 틀을 리뷰하려고 합니다.",
            "writer": "testid2",
            "writedate": "2021-08-09 13:10:00",
            "poster": "/asset/board/files/2.png",
            "viewcount": 10,
            "categoryText": "쇼핑"
        },
        {
            "no": 3,
            "subject": "도배 쉽게 하는 방법",
            "content": "오늘은 도배지의 종류와 도배하는 방법, 부분 도배하는 방법을 알려드리겠습니다.\n도배지 종 및 특징\n실크(PVC) 벽지, 합지(종이) 벽지, 천연 벽지, 뮤럴(벽화) 벽지, 방염 벽",
            "writer": "testid3",
            "writedate": "2021-08-09 13:20:00",
            "poster": "/asset/board/files/3.png",
            "viewcount": 10,
            "categoryText": "노하우"
        }
    ],
    "pagination": {
        "totalCount": 13,
        "countPerPage": 3,
        "pageSize": 10,
        "startPageNo": 1,
        "endPageNo": 5,
        "lastPageNo": 5,
        "pageNo": 1,
        "enablePrevPageNo": false,
        "enableNextPageNo": true,
        "prevPageSizeNo": 0,
        "enablePrevPageSizeNO": false,
        "nextPageSizeNo": 6,
        "enableNextPageSizeNO": false
    }
}

 

Get Method - viewcount sort 테스트

http://localhost:9000/boards?countperpage=3&pageno=1&sortby=viewcount.desc

조회 수를 기준으로 내림차순으로 정렬되는 것을 확인할 수 있습니다.

{
    "success": true,
    "data": [
        {
            "no": 10,
            "subject": "통밀과자 만들기 체험",
            "content": "오늘은 강원도에 있는 통밀과자를 만들 수 있는 체험장을 다녀왔습니다.\n아침 9시부터 11시까지 두시간 동안 가족들과 함께 빵 체험과 통밀과자를 만들었습니다.",
            "writer": "testid1",
            "writedate": "2022-03-26 21:00:00",
            "poster": "/asset/board/files/10.png",
            "viewcount": 80,
            "categoryText": "일상"
        },
        {
            "no": 9,
            "subject": "이케아 광명점에서 폭풍 구매",
            "content": "안녕하세요! ㅎㅎ 오랜만에 일상으로 인사드립니다.\n사실 집에만 있다가 코에 바람도 넣을 겸 드라이브도 할 겸 이케아 광명점에 왔습니다.\n오늘 이케아에서 폭풍 구매한 내역을 공개하고",
            "writer": "testid3",
            "writedate": "2022-03-26 19:50:00",
            "poster": "/asset/board/files/9.png",
            "viewcount": 70,
            "categoryText": "일상"
        },
        {
            "no": 8,
            "subject": "휴대용 UV 살균기",
            "content": "코로나로 집 받을 나갔다오면 핸드폰부터 가방, 옷까지 혹시나 하는 생각에 찜찜함이 있었다.\n그래서 쇼핑몰을 검색해보니 UV 살균기를 휴대할 수 있는 제품들이 많이 있었다.\n그 중에",
            "writer": "testid2",
            "writedate": "2022-03-26 18:40:00",
            "poster": "/asset/board/files/8.png",
            "viewcount": 60,
            "categoryText": "쇼핑"
        }
    ],
    "pagination": {
        "totalCount": 13,
        "countPerPage": 3,
        "pageSize": 10,
        "startPageNo": 1,
        "endPageNo": 5,
        "lastPageNo": 5,
        "pageNo": 1,
        "enablePrevPageNo": false,
        "enableNextPageNo": true,
        "prevPageSizeNo": 0,
        "enablePrevPageSizeNO": false,
        "nextPageSizeNo": 6,
        "enableNextPageSizeNO": false
    }
}
728x90
반응형