💕
후원
본문 바로가기
Web/Backend

[백엔드 스터디] 1. 익스프레스 찍어먹기

by r4bb1t 2022. 9. 26.
반응형

동아리에서 프로젝트장을 맡아 프론트엔드 및 백엔드 스터디를 이끌고 있습니다. 백엔드는 저도 초보이다 보니 공부하면서 스터디원들에게 전달하기 위해 만든 자료입니다.

엿장수가 설명하는 양자역학 백엔드
웹 프로젝트 스터디 0.pdf
0.51MB

VSCode, Node 등의 설치는 이미 되어있다고 가정합니다.

공부할 것

  • 서버, 데이터베이스에 대한 개념 알아오기
  • CORS란?
  • SQL 문법 대충이라도 익혀보기
  • GET, POST, PUT 등 Rest API와 각 메소드에 대해

우선 Node.js Typescript 보일러플레이트를 갖다 써봅시다. git clone 으로 푹찍해옵니다.
yarn add express 및 yarn add @types/express로 express와 타입 파일을 설치합니다.
src/index.ts 에 다음과 같은 코드를 입력해봅니다.

import express, { Application, Request, Response } from 'express';

const app: Application = express();

app.get('/', async (req: Request, res: Response): Promise<Response> => {
  return res.status(200).send({
    message: 'Hello World!',
  });
});

const PORT = 3000;

try {
  app.listen(PORT, (): void => {
    console.log(`Connected successfully on port ${PORT}`);
  });
} catch (error: any) {
  console.error(`Error occured: ${error.message}`);
}

yarn dev 로 서버를 띄워봅니다. 이제 브라우저에서 http://localhost:3000 에 접속하면 {"message":"Hello World!"} 가 뜹니다. 와! 이제 기본적인 CRUD를 구현해볼건데요, 테스트를 위해 포스트맨 가입 후 설치 or 웹상에서 사용할 수 있게 준비해둡니다. 또, DB를 연결해야 하는데 간단하게 sqlite3를 사용하겠습니다.

POST 메소드

POST 메소드는 클라이언트에서 서버에 데이터를 보낼 수 있는 메소드입니다.

import cors from 'cors';
import bodyParser from 'body-parser';

yarn add cors, yarn add body-parser 로 라이브러리를 설치해줍니다. cors에 대해서는 꼭! 검색해서 알아보셔야 합니다. body-parser는 post로 보낸 body를 해석할 수 있게 해주는 라이브러립니다.

app.use(cors());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());

위 코드를 추가하여 app에서 각 미들웨어를 사용할 수 있게 해주세요.

app.post('/', async (req: Request, res: Response): Promise<Response> => {
  return res.status(200).send({
    message: `Hello World! ${req.body.name}`,
  });
});

위 코드를 추가해주고, postman에서 보내면, name이 잘 뜨는 것을 확인할 수 있습니다.

DB 달기

yarn add sqlite3 으로 sqlite3을 설치해줍니다. sqlite는 파일 하나로 이루어진 DB로, 따로 DB를 띄우지 않고 서버에 붙일 수 있습니다. db 폴더를 만들어줍니다.

import sqlite3 from 'sqlite3';

임포트 후

const db = new sqlite3.Database('./db/my.db', sqlite3.OPEN_READWRITE, (err) => {
  if (err) {
    console.error(err.message);
  } else {
    console.log('Connected to the mydb database.');
  }
});

위 코드로 db를 초기화해줍니다.

const dropQuery = `
  DROP TABLE IF EXISTS person
`;

const insertQuery = `
  CREATE TABLE IF NOT EXISTS person(
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    name VARCHAR(20)
  )
`;

const dummyDataQuery = `
  insert into person(name) values ('hi'), ('hello')
`;

person이라는 테이블이 있으면 없애고, 없으면 만들어줍니다. 그 후 더미데이터를 넣습니다.

db.serialize(() => {
  db.each(dropQuery);
  db.each(insertQuery);
  db.each(dummyDataQuery);
});

적용.

app.post('/', async (req: Request, res: Response): Promise<Response> => {
  const query = `insert into person(name) values ('${req.body.name}')`;
  db.serialize();
  db.each(query);
  return res.status(200).send({
    message: `입력 완료: ${req.body.name}`,
  });
});

POST 메소드에 위 코드를 추가하여, POST 요청이 왔을때 body의 name을 person에 넣도록 합니다.

app.get('/', async (req: Request, res: Response) => {
  const query = `SELECT * FROM person`;
  db.serialize();
  new Promise((resolve, reject) =>
    db.all(query, (err, rows) => {
      if (err) console.log(err);
      return resolve(rows);
    }),
  ).then((rows) =>
    res.status(200).send({
      user: rows,
    }),
  );
});

GET 메소드를 위와 같이 수정하여 person 테이블을 보여줍니다.

  • 전체 코드
import express, { Application, Request, Response } from 'express';
import cors from 'cors';
import bodyParser from 'body-parser';
import sqlite3 from 'sqlite3';

const app: Application = express();
app.use(cors());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());

const db = new sqlite3.Database('./db/my.db', sqlite3.OPEN_READWRITE, (err) => {
  if (err) {
    console.error(err.message);
  } else {
    console.log('Connected to the mydb database.');
  }
});

const dropQuery = `
  DROP TABLE IF EXISTS person
`;

const insertQuery = `
  CREATE TABLE IF NOT EXISTS person(
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    name VARCHAR(20)
  )
`;

const dummyDataQuery = `
  insert into person(name) values ('hi'), ('hello')
`;

db.serialize(() => {
  db.each(dropQuery);
  db.each(insertQuery);
  db.each(dummyDataQuery);
});

app.get('/', async (req: Request, res: Response) => {
  const query = `SELECT * FROM person`;
  db.serialize();
  new Promise((resolve, reject) =>
    db.all(query, (err, rows) => {
      if (err) console.log(err);
      return resolve(rows);
    }),
  ).then((rows) =>
    res.status(200).send({
      user: rows,
    }),
  );
});

app.post('/', async (req: Request, res: Response): Promise<Response> => {
  const query = `insert into person(name) values ('${req.body.name}')`;
  db.serialize();
  db.each(query);
  return res.status(200).send({
    message: `Hello World! ${req.body.name}`,
  });
});

const PORT = 3000;

try {
  app.listen(PORT, (): void => {
    console.log(`Connected successfully on port ${PORT}`);
  });
} catch (error: any) {
  console.error(`Error occured: ${error.message}`);
}

과제

위 내용을 이용하여, 다음과 같은 프로그램을 만들어 보세요.

  • / 에 get 메소드로 접근하면 모든 책과 음식을 보여줍니다.
  • /books 에 get 메소드로 접근하면 모든 책의 목록을 보여줍니다.
  • /meals 에 get 메소드로 접근하면 모든 음식의 목록을 보여줍니다.
  • /new 에 post 요청 body로 {"type": "book", "name": "책제목예시", "price": 3000, "author": "작가이름예시"} 형식의 json을 전달하면 책 목록에 해당 책을 추가하고, {"type": "meal", "name": "음식이름예시", "price": 3000, "restaurant": "식당이름예시"} 형식의 json을 전달하면 음식 목록에 해당 음식을 추가합니다.
반응형

댓글