티스토리 뷰

항해/주특기 1주차

[node js] 3주차 -1

타올이 2022. 1. 23. 16:34
반응형

API Client 학습

1) API Client란 뭘까?

    • API Client란 개발단계에서 우리가 작성한 API의 요청을 확인하거나 테스팅 할 때 도움을 주는 툴입니다. API Client를 사용함으로 개발 속도를 높이거나 치명적인 에러를 예방하는데 도움을 받을 수 있습니다.
    • Postman, Insomnia 등 여러 API Client가 있지만 이번 강의에서는 Thunder Client를 사용할 예정입니다.
      • VS Code 안에서 사용할 수 있으면서, 기능이 부족하지 않기 때문에 비교적 쉽게 사용 할 수 있습니다!

2) 어떤 상황에 필요할까?

  • 지금까지 우리는 HTTP Method 중 GET Method에 대응하는 API만 만들고 브라우저로 확인했습니다!
  • 아직까진 API Client가 필요 없어보였지만 POST, PATCH, PUT, DELETE, HEAD 등의 다양한 Method에 대한 API를 개발하고 테스트하기 위해서는 반드시 필요한 도구라고 볼 수 있습니다.

3) VS Code - Thunder Client 설치

1. VS Code 내에 좌측 탭 맨아래 Extensions를 눌러줍니다.

2. 검색창이 나오면 제일 위에 나오는 Thunder Client를 눌러보면 아래와 같이 나옵니다.

3.Install 버튼을 눌러 설치를 해주시고 아래와 같이 번개 모양 아이콘이 생기면 설치가 완료된것입니다.

 

4) 2주차에 만들었던 상품 목록 조회 API 호출

이런 화면이 나오게 됩니다. 그럼 이제 맨위의 URI를 입력하는곳에 상품 목록 조회 API의 HTTP Method인 GET으로 설정해 준뒤 http://localhost:3000/api/goods 를 입력하고 Send 버튼을 눌러줍니다.

이전에 브라우저에서 보았던 값이 나오게 되면 성공입니다!

03. 데이터베이스와 MongoDB의 개념

    1. 데이터베이스란 뭘까?
    저번 주 숙제로 MongoDB 설치가 있었죠? 뭔지 잘 모르고 설치하신 분들이 대부분일텐데, 이 개념을 잡아봅니다!
    • 단순히 데이터를 잘 저장하고 잘 찾기 위해 만들어진 소프트웨어를 Database Management System(DBMS) 이라 부릅니다.
    • DBMS가 설치된 서버 컴퓨터를 데이터베이스 서버(DB 서버)라고 부를 수 있습니다.
    • 흔히 "데이터베이스에 저장한다" 라고 말하면 이 DBMS가 설치된 서버에 데이터를 저장한다고 말하는것입니다. 즉, DB 서버의 모든 데이터는 DBMS가 관리하게 됩니다.
    • 데이터베이스의 종류는 크게 다음과 같습니다.
      • 🕸 관계형 데이터베이스 - Relational Database (RDB): 데이터 형식이 정해져 있고, 데이터 끼리 관계를 맺어 모순이 없는 데이터를 유지할 수 있도록 도와주는것에 집중한 데이터베이스를 관계형 데이터베이스라고 부릅니다. 모순이 없는 데이터: 무결성과 정합성이 높은 데이터 -스키마
      • 🗽 비관계형 데이터베이스 - Non-relational Database (NoSQL): 관계형 데이터베이스에 속하지 않는 모든 데이터베이스를 비관계형 데이터베이스라고 부릅니다. 비관계형 데이터베이스는 데이터의 형태가 고정되어 있지 않고 유연하게 확장할 수 있지만, 유연한 만큼 저장되는 데이터를 제대로 관리하지 않으면 데이터베이스에 저장된 데이터를 신뢰할 수 없게 되기도 합니다. 최근 많은 스타트업에서 유연한 설계를 위해 많이 채택되는 데이터베이스 유형입니다.
    1. MongoDB는 뭘까?
    • 국내, 외 수많은 개발자들에게서 사용되고있는 가장 인기있는 비관계형 데이터베이스중 하나입니다.
    • 모든 데이터가 JSON 형태로 저장됩니다.
    • 복잡한 구조를 쉽게 저장할 수 있는 장점이 있습니다.
    • 무료로 사용할 수 있습니다.
    • 스케일을 쉽게 줄이고 늘일 수 있습니다.
    1. 웹 서버와 DB 서버는 어떤 관계일까?
    • 두 개념 다시 정리
      • 웹 서버는 웹 클라이언트가 원하는 데이터와 기능을 제공합니다.
      • DB 서버는 데이터를 최대한 성능 좋게 저장하고 DB 클라이언트가 원하는 데이터를 제공합니다.
    • 결국 두가지 서버는 어떤것을 제공하냐만 다를 뿐, 기본 원칙은 비슷합니다. 그럼 웹 서버는 DB 서버와 어떤 관계일까요?
    • 웹 서버는 DB 서버를 이용하는 DB 클라이언트가 될 수 있습니다.
더보기

💡 정리하면? 브라우저 ↔ 웹 서버 ↔ DB 서버

    1. 앞으로 여러분은?
  • 저와 함께 웹 서버(API 서버)를 만들면서 DB 클라이언트 라이브러리 mongoose를 사용하며 쇼핑몰의 기능을 마저 완성해 볼 예정입니다.

MongoDB Client: Robo3T 학습

    1. Robo3T란?
    • Robo3T는 API의 사용을 도와주는 API Client처럼 MongoDB를 위해서 만들어진 MongoDB Client입니다.
    • Robo3T의 GUI를 통해 MongoDB에 저장된 데이터를 관리하기 쉽게 보여주는 프로그램입니다.
    1. DB Client와 API Client의 다른점은?
  • 서버에 연결해 데이터를 보내는것 까지는 같은 개념이지만 DBMS는 웹처럼 단순하지 않아 프로그램 사용법이 조금 더 복잡하고 DB의 데이터를 조회하거나, 관리할 수 있는 기능을 제공합니다.
  • 오늘 배우게 될 Robo3T는 DB Client 종류 중 하나이며, MongoDB를 관리하기 위한 DB Client입니다.
    1. 간단하게 데이터 제어해보기
    CRUD 명령어도 간단하게 체험해봅니다!
    • db.collectionName.find({})
    • db.collectionName.insertOne({ key: "value", key2: "값" })
    • { key: "value", key2: "값" }  -> document
    • db.collectionName.deleteOne({ _id: ObjectId("...") }
  • 이 수업은 MongoDB가 아닌 Node.js를 배우는것이 목적이기 때문에 개념 잡는 정도만 짚고 넘어갈 예정이에요! 😉

코드에서 MongoDB 이용

    1. 내 코드에서 MongoDB에 연결하려면 뭘 해야 할까요?
    • 이제부터 우리는 API에 MongoDB를 연결해서 데이터를 주고 받아볼 예정입니다!
    • 이를 위해 코드에서도 DB Client 역할을 하는 무언가가 있어야 데이터베이스에 연결을 할 수 있는데요, 우리는 mongoose 라는 도구를 이용해 데이터베이스에 연결할 예정입니다.
    1. mongoose 설치
    • 우리가 작업하던 spa_mall 프로젝트를 열어줍니다!
    • npm 으로 기존 프로젝트에서 터미널을 열어 아래와 같이 입력해 mongoose를 설치 할 수 있습니다.
더보기

npm install mongoose

https://www.npmjs.com/package/mongoose

 

mongoose

Mongoose MongoDB ODM

www.npmjs.com

    1. mongoose의 모델이란?
    데이터베이스에 데이터를 저장해줄때 데이터의 구조를 담당합니다.
    1. mongoose에서는 모델이 왜 필요할까?
  • mongoose에서 데이터를 모델링할시 Schema라는 객체를 사용하는데 이 Schema를 이용해 document를 생성할 때 모델이 사용됩니다

       1. 웹 서버에서 MongoDB에 연결

 

mongoose를 이용해 데이터베이스에 연결합니다.

 

/schemas/index.js.예시

const mongoose = require("mongoose");

const connect = () => {
  mongoose
    .connect("mongodb://localhost:27017/spa_mall")
    .catch(err => console.log(err));
};

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

module.exports = connect;

/app.js 예시

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

         1) 상품 모델 작성

mongoose를 더 편하게 사용하기 위한 방법!

Schema를 생성하여 데이터를 관리하기 위해 모델을 작성합니다.

 

/schemas/goods.js 예시

const mongoose = require("mongoose");

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

module.exports = mongoose.model("Goods", goodsSchema);

         1) 상품 생성 API 작성

  • 이제 상품 데이터를 코드에 넣어두는게 아닌, 데이터베이스에 추가할 수 있게 할 예정이에요!
  • 지금까지 만든 API는 상품 목록 조회, 개별 상품 조회 로 모두 조회하는 API 였어요! 이제는 GET 메서드 뿐만 아니라 POST와 같은 메서드에 대응하는 API도 개발해봅니다.
  • REST API 에 따르면 새로운 데이터를 추가하는 method는 POST 를 쓰는 것을 권장합니다.
  • POST 메소드의 특징은 GET 메소드와는 다르게 body 라는 추가적인 정보를 담아 서버에 전달 할 수 있기 때문에 정보값을 body라는 이름으로 넘겨줄 예정입니다.

/app.js 예시

body로 전달 받은 JSON 데이터를 바로 사용할 수 없어요!

Express.js에서 제공하는 JSON middleware를 사용해 body로 전달된 데이터를 사용할 수 있도록 해봅니다!

app.use(express.json());

/routes/goods.js 예시

router.post("/goods", async (req, res) => {
	const { goodsId, name, thumbnailUrl, category, price } = req.body;

  const goods = await Goods.find({ goodsId });
  if (goods.length) {
    return res.status(400).json({ success: false, errorMessage: "이미 있는 데이터입니다." });
  }

  const createdGoods = await Goods.create({ goodsId, name, thumbnailUrl, category, price });

  res.json({ goods: createdGoods });
});
  • API 작성이 완료되면 Thunder Client로 상품 생성 API를 호출해보세요.
  • 먼저 저번과 같이 Thunder Client 아이콘을 클릭해 준뒤 New Request를 클릭해줍니다.
  • 그리고 아래와 같이 이번엔 HTTP method를 POST, URL은 http://localhost:3000/api/goods 를 입력해줍니다.
  • 이번에는 Body에 추가할 정보값을 입력해 줄건데요, 아래의 예시를 넣어서 Json Content 안에 넣어준뒤 Send 버튼을 눌러서 호출을 해봅시다.

[코드스니펫] 콜라 정보

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

app.js

const express = require('express');
// 14) connect 사용하기 위한 작업, index는 생략가능
const connect = require("./schemas")
const { nextTick } = require('process');
const app = express();
const port = 3000;

// connect 실행
connect();

 
const goodsRouter = require('./routes/goods')
 
const requstMiddleware = (req,res,next)=>{
    
    console.log('Request URL:', req.originalUrl, " - ", new Date());
 
    next();
};

// 18) body에 들어오는 json을 사용할수 있게 도와주는 미들웨어
app.use(express.json());

 
app.use(requstMiddleware);

 
app.use("/api",[goodsRouter]);

 
app.get('/',(req,res)=>{
    res.send("Hello world");
});

 
app.listen(port, ()=>{
    console.log(port, "포트로 서버 연결!")
});

goods.js/router
const express = require('express')
// 16) 내가 만든 스키마를 가져오기, ./는 현재 위치 ../는 상위위치
const Goods = require('../schemas/goods')
 
const router = express.Router();

 
router.get("/", (req,res)=>{
    res.send('this is root page')
});

 
const goods = [
    {
      goodsId: 4,
      name: "상품 4",
      thumbnailUrl:
      category: "drink",
      price: 0.1,
    },
    {
      goodsId: 3,
      name: "상품 3",
      thumbnailUrl:
      category: "drink",
      price: 2.2,
    },
    {
      goodsId: 2,
      name: "상품 2",
      thumbnailUrl:
      category: "drink",
      price: 0.11,
    },
    {
      goodsId: 1,
      name: "상품 1",
      thumbnailUrl:
      category: "drink",
      price: 6.2,
    },
  ];

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

 
    const [detail] = goods.filter((item)=> item.goodsId === Number(goodsId));

 
    res.json({
 
        detail,
    });
});

// 17) 리소스를 생성하는 post, goodId를 생성하는 api
// get을 제외한 모든 메서드는 body를 가져올 수 있음
router.post("/goods",async (req,res)=>{
  const { goodsId, name, thumbnailUrl, category, price } = req.body;

  const goods = await Goods.find({goodsId});
// 20) goods가 빈 배열일때 넣어주면 됨
  if (goods.length){
    return res.status(400).json({ success : false, erroerMessge: "이미 있는 데이터입니다."})
  }
// 21) goods가 빈 값이 아닐때 create를 해준다.
  const createdGoods = await Goods.create({ goodsId, name, thumbnailUrl, category, price });

  res.json({goods: createdGoods });
});


 
module.exports = router;

index.js/schema

const mongoose = require("mongoose")

// 컨넥트
const connect = () => {
    mongoose.connect("mongodb://localhost:27017/spa_mall").catch((err)=>{
        // 에러가 뜰경우 콘솔에 err가 찍임
        console.error(err);
    });
};

module.exports = connect;
goods.js/schema
const mongoose = require('mongoose');

// 15) mongoose schema 생성
const goodsSchma = mongoose.Schema({
    goodsId: {
        type: Number,
        required: true,
        unique: true,
    },
    name: {
        type: String,
        required: true,
        unique: true,
    },
    thumbnailUrl: {
        type: String,
    },
    category: {
        type: String,
    },
    price: {
        type: Number,
    },
});

// Goods는 모델이름
module.exports = mongoose.model("Goods",goodsSchma)
반응형

'항해 > 주특기 1주차' 카테고리의 다른 글

[node js] 3주차 -3  (0) 2022.01.23
[node js] 3주차 -2  (0) 2022.01.23
[node js] 2주차 -4  (0) 2022.01.23
[node js] 2주차 -3  (0) 2022.01.23
[node js] 2주차 - 2  (0) 2022.01.23
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
링크
글 보관함