node.js (REST api, mongoDB)

Sujin Lee·2021년 5월 9일
0
post-custom-banner

1. REST api란?

  • Representational State Transfer
  • REST라는 규칙을 따르는 API
  • World Wide Web과 같은 분산 하이퍼미디어 시스템을 위한 소프트웨어 아키텍처의 한 형식
  • 웹에 존재하는 모든 자원(이미지, 동영상, DB자원)에 고유한 URI를 부여해 활용하는 것으로, 자원을 정의하고 자원에 대한 주소를 지정하는 방법론을 의미
    (웹에 존재하는 자원들에 접근하는 방법 등을 정의한 것을 REST라고 함)
  • GET / POST / PUT / DELETE

1.1 REST api의 구성

1.1.1 자원 (Resource) - URL

  • 우리가 만들 소프트웨어가 관리하는 모든 것을 자원으로 표현할 수 있다.

1.1.2 행위 - HTTP method (CRUD)

  • GET / POST / PUT / DELETE 로 해당 자원에 대한 행위를 표현할 수 있다.
    GET 메소드는 해당 자원의 조회, POST 메소드는 해당 자원의 생성

  • Create: 생성 (POST)

  • Read: 조회 (GET)

  • Update: 수정 (PUT)

  • Delete: 삭제 (DELETE)

1.1.3 표현

  • 해당 자원을 어떻게 표시할 지에 대한 설명. 보통 JSON, XML과 같은 형식을 이용해서 자원 표현

2. mongoDB 설치

2.1 DB (Database)

데이터를 안전하고 편리하게 보관하고 가져다가 쓸 수 있는 서비스

2.1.1 DB의 두 가지 종류

1) RDBMS(SQL)

  • 행/열의 생김새가 정해진 엑셀에 데이터를 저장하는 것과 유사함
  • 갑자기 중간에 열을 더하는 것은 어렵지만, 데이터의 일관성이나 분석에 용이함
  • Ex) MS-SQL, My-SQL 등

2) No-SQL

  • 딕셔너리 형태로 데이터를 저장해두는 DB
  • 데이터 하나하나마다 같은 값들을 가질 필요가 없다.
  • 자유로운 형태의 데이터 적재에 유리한 대신, 일관성이 부족할 수 있다.
  • Ex) mongoDB

2.1.2 mongoDB 설치

1) c 드라이브에 data라는 폴더를 만들고, 그 안에 db라는 폴더 생성

2) mongoDB 다운로드
https://www.mongodb.com/try/download/community

  • MongoDB Community Server 탭에서 Download 클릭

3) NEXT ~~~ Custom 클릭 > Browse 클릭 > C:\data\db\ 를 찾아 선택하고 OK 클릭 > Next ~~ > Install MongoDB Compass 선택을 해제하고 Next 클릭 > Install

4) 제어판 > 시스템 및 보안 > 시스템 > [고급 시스템 설정] > 환경변수 > [시스템 변수] 목록 > Path 선택 > 편집 > 새로 만들기 > C:\data\db\bin 추가

5) Windows키 + R > cmd 입력 > 다음 명령어 입력

6) 다음 명령어 입력
mongo

2.1.3 Robo3T 설치

1) Robo3T 다운로드
https://robomongo.org/download

2.1.4 mongoose 설치

  • mongoose는 mongoDB에 연결하고 데이터 모델링을 제공해주는 툴.

1) mongoose 설치 - npm으로 제공되고 있음
npm install mongoose

2) node.js 코드

const mongoose = require('mongoose');

app.get('/mongodb', async (req, res) => {
	await mongoose.connect('mongodb://localhost/voyage', {
    	useNewUrlParser: true,
      	useUnifiedTopology: true,
      	useFindAndModify: true,
      	useCreateIndex: true
    });
  
  	res.send('ok');
});
  • mongoose에서는 데이터를 모델링할 때 Schema 객체 사용
const mongoose = require('mongoose');

app.get('/mongodb', async (req, res) => {
	await mongoose.connect('mongodb://localhost/voyage', {
    	useNewUrlParser: true,
      	useUnifiedTopology: true,
      	useFindAndModify: true,
      	useCreateIndex: true
    });
  	
  	const { Schema } = mongoose;
  	const goodsSchema = new Schema({
    	goodsId: {
        	type: Number,
          	required: true,
          	unique: true
        },
      	name: {
        	type: String,
          	required: true,
          	unique: true
        },
      	thumbnailUrl: {
        	type: String
        },
      	category: {
        	type: String
        },
      	price: {
        	type: Number
        }
    });
  
  	let Goods = mongoose.model("Goods", goodsSchema);
  
  	// create(): mongoDB에 데이터 추가 
  	await Goods.create({
    	goodsId: 1,
      	name: "맛있는 저녁",
      	thumbnailUrl: "https://~~",
      	category: "food",
      	price: 15000
    });
  	res.send('ok');
});

2.1.5 mongoose 구조 만들기

1) schemas/index.js

const mongoose = require('mongoose');

const connect = () => {
	mongoose.connect('mongodb://localhost/voyage', {
    	useNewUrlParser: true,
      	useUnifiedTopology: true,
      	useFindAndModify: true,
      	useCreateIndex: true
    })
  	.catch(err => console.log(err));
};

mongoose.connection.on("error", err => {
	console.error("몽고디비 연결 에러", err);
});

module.exports = connect;

2) schemas/goods.js

const mongoose = require("mongoose");

const { Schema } = mongoose;
const goodsSchema = new Schema({
  goodsId: {
    type: Number,
    required: true,
    unique: true
  },
  name: {
    type: String,
    required: true,
    unique: true
  },
  thumbnailUrl: {
    type: String
  },
  category: {
    type: String
  },
  price: {
    type: Number
  }
});

3) index.js

const connect = require("./schemas");
connect();

3. RESTful API 만들기

1) goods route 생성

index.js 파일에 추가

const goodsRouter = require('/routers/goods');
app.use("/api", [goodsRouter]);

2) router 파일 추가

/routers/goods.js

const express = require("express");
const Goods = require("../schemas/Goods");

const router = express.Router();

router.get("/goods", async (req, res, next) => {
	try {
    	const { category } = req.query;
      	const goods = await Goods.find({ category }).sort(".goodsId");
      	res.json({ goods: goods });
    } catch (err) {
    	console.error(err);
      	next(err);
    }
});

router.get("/goods/:goodsId", async (req, res) => {
	const { goodsId } = req.params;
  	goods = await Goods.findOne({ goodsId: goodsId});
  	res.json({ detail: goods });
});

module.exports = router;

3) ejs 파일 수정하기

function get_goods(category) {
	$("#goodsList").empty();
  	console.log(category);
  	$.ajax({
    	type: "GET",
      	url: `/api/goods${category ? "?category=" + category : ""}`,
      	data: {},
      	success: function (response) {
        	let goods = response["goods"];
          	for (let i = 0; i < goods.length; i++) {
            	make_card(goods[i]);
            }
        }
    });
}

상품 추가하기

  • 데이터를 추가할 때는 POST 사용
  • POST 메소드의 특징: GET 메소드와는 다르게 body라는 추가적인 정보를 담아 서버에 전달 가능.

1) /routers/goods.js

router.post('/goods', async (req, res) => {
	const { goodsId, name, thumbnailUrl, category, price } = req.body;
  	
  	let isExist = await Goods.find({ goodsId });
	if (isExist.length == 0) {
        await Goods.create({ goodsId, name, thumbnailUrl, category, price});
    }
  	res.send({ result: "success" });
});

4. Insomnia 설치

https://insomnia.rest/download/

Insomnia Core 다운로드

POST 메서드,
localhost:3000/api/goods
Create

데이터 추가 후 send

{
   "goodsId": 2,
   "name": "시원한 콜라",
   "thumbnailUrl": "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRk7JqMw7ZYZP4ZW136wcoMTmLzbrMIJzUWb1Dhu9cHwCPp0gA&usqp=CAc",
   "category": "drink",
   "price": 3000
}

detail.ejs 수정

function get_detail() {
	$.ajax({
    	type: "GET",
      	url: `/api/goods/${goodsId}`,
      	data: {},
      	error: function(xhr, status, error) {
        	if (status == 404) {
            	alert("존재하지 않는 상품입니다.");
            }
          	window.location.href = "/goods";
        },
      	success: function(response) {
        	let goodsDetail = response["detail"];
            $("#goodsUrl").attr("src", goodsDetail["thumbnailUrl"]);
            $("#goodsName").text(goodsDetail["name"]);
            $("#goodsPrice").text("$" + number2decimals(goodsDetail["price"]));

            sessionStorage.setItem("goodsId", goodsId);
            sessionStorage.setItem("goodsName", goodsDetail["name"]);
            sessionStorage.setItem("goodsPrice", goodsDetail["price"]);
            sessionStorage.setItem("orderNum", 1);
        }
    });

}
post-custom-banner

0개의 댓글