본문 바로가기

WINK-(Web & App)/Express.js (Node.js) 스터디

[2024 Node.js 스터디] 김태일 #5주차

반응형

06. 익스프레스 웹 서버 만들기

익스프레스 : 서버를 제작하는 과정에서 겪게 되는 불편을 해소하고 편의 기능을 추가한 웹 서버 프레임워크

- http 모듈의 요청과 응답 객체에 추가 기능 부여

- 기존 메서드들 사용가능, 편리한 메서드들 추가해 기능 보완

- 코드를 분리하기 쉽게 만들어 관리하기 용이

- if문으로 요청 메서드와 주별 구별하지 않아도 됨

 

06.1 익스프레스 프로젝트 시작하기

1) learn-express 폴더 생성

2) 항상 package.json 제일 먼저 생성 --> npm init 명령어를 콘솔에서 호출해 단계적으로 내용물 입력 or npm init -y를 입력해 파일을 만든 뒤 내용 수정

package.json
{
  "name": "learn-express",
  "version": "0.0.1",
  "description": "익스프레스를 배우자",
  "main": "app.js",
  "scripts": {
    "start": "nodemon app"
  },
  "author": "ZeroCho",
  "license": "MIT"
}

start 부분에 start 속성 넣어줘야 함

nodemon app을 하면 app.js를 nodemon으로 실행한다는 것을 의미

코드에 수정사항이 생길 때마다 nodemon모듈을 이용하여 서버를 자동으로 재시작, nodemon이 실행되는 콘솔에 rs를 입력해 수동으로 재시작

nodemon은 개발용으로만 사용 권장

//app.js
const express = require('express');

const app = express();
app.set('port', process.env.PORT || 3000);

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

app.listen(app.get('port'), () => {
  console.log(app.get('port'), '번 포트에서 대기 중');
});

서버 역할을 할 파일

express 모듈을 실행해 app변수에 할당 (익스프레스 내부에 http 모듈이 내장되어 있으므로 서버 역할 가능)

app.set('port', 포트) : 서버가 실행될 포트 설정

app.get(주소, 라우터) : 주소에 대한 GET 요청이 올 때 어떤 동작을 할 지 적는 부분

listen을 하는 부분은 http 웹 서버와 동일

npm start 실행
http://localhost:3000로 접속

 

단순한 문자열 대신 HTML로 응답하고 싶다면 res.sendFile 메서드 사용

index.html
<html>
<head>
  <meta charset="UTF-8" />
  <title>익스프레스 서버</title>
</head>
<body>
  <h1>익스프레스</h1>
  <p>배워봅시다.</p>
</body>
</html>
//app.js
const express = require('express');
const path = require('path');

const app = express();
app.set('port', process.env.PORT || 3000);
app.get('/', (req, res) => {
  // res.send('Hello, Express');
  res.sendFile(path.join(__dirname, '/index.html'));
});

app.listen(app.get('port'), () => {
  console.log(app.get('port'), '번 포트에서 대기 중');
});

파일 경로 path 모듈로 지정 필수

 

06.2 자주 사용하는 미들웨어

미들웨어

- 요청과 응답의 중간에 위치

- 익스프레스의 핵심

- 요청과 응답을 조작해 기능 추가하기도, 나쁜 요청을 걸러내기도 함

- 위에서부터 아래로 순서대로 실행되면서 요청과 응답 사이에 특별한 기능을 추가

- app.use와 함께 사용 (app.use(미들웨어) 꼴)

//app.js
...
app.set('port', process.env.PORT || 3000);

app.use((req, res, next) => {
  console.log('모든 요청에 다 실행됩니다.');
  next();
});
app.get('/', (req, res, next) => {
  console.log('GET / 요청에서만 실행됩니다.');
  next();
}, (req, res) => {
  throw new Error('에러는 에러 처리 미들웨어로 갑니다.')
});

app.use((err, req, res, next) => {
  console.error(err);
  res.status(500).send(err.message);
});

app.listen(app.get('port'), () => {
...

익스프레스 서버에 미들웨어를 연결

app.use에 매개변수가 req,res,next인 함수를 넣으면 됨

next 함수 : 다음 미들웨어로 넘어가는 함수

 

app.use(미들웨어) 모든 요청에서 미들웨어 실행
app.use('/abc', 미들웨어) abc로 시작하는 요청에서 미들웨어 실행
app.post('/abc', 미들웨어) abc로 시작하는 POST 요청에서 미들웨어 실행

app.use app.get 같은 라우터에 미들웨어를 여러 개 장착 가능

 

dotenv

- process.env를 관리 (보안과 설정의 편리성때문에 별도의 파일로 관리)

- .env 파일을 읽어서 process.env로 만듦

 

1) morgan

- 추가적인 로그 생성

app.use(morgan('dev'));

 

2) static

- 정적인 파일들을 제공하는 라우터 역할

- 설치 필요 X, express 객체 안에서 꺼내 장착

app.use('요청 경로', express.static('실제 경로'));

 

3) body-parser

- 요청의 본문에 있는 데이터를 해석해서 req.body 객체로 만듦

- 폼 데이터나 AJAX요청의 데이터 처리

- 멀티파트(이미지, 동영상, 파일)데이터는 처리 못함

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

 

- JSON과 URL-encoded 형식의 데이터 외에도 Raw, Text 형식의 데이터를 추가로 해석 가능

(Raw는 요청의 본문이 버퍼 데이터일 때, Text는 텍스트 데이터일 때 해석하는 미들웨어)

const bodyParser = require('body-parser');
app.use(bodyParser.raw());
app.use(bodyParser.text());

 

4) cookie-parser

- 요청에 동봉된 쿠키를 해석해 req.cookies 객체로 만듦

- 쿠키를 생성할 때 쓰이는 것은 아님 (쿠키를 생성, 제거하려면 res.cookie, res.clearCookie 메서드를 사용해야 함)

 

5) express-session

- 세션 관리용 미들웨어

- 세션을 구현하거나 특정 사용자를 위한 데이터를 임시적으로 저장해둘 때 매우 유용

- 세션은 사용자별로 req.session객체 안에 유지

- 인수로 세션에 대한 설정을 받음

- 세션 관리 시 클라이언트에 쿠키를 보냄

 

6) 미들웨어의 특성 활용하기

미들웨어의 특성

- req, res, next를 매개변수로 갖는 함수로서 app.use app.get, app.post 등으로 장착

- 특정한 주소의 요청에만 미들웨어가 실행되게 하려면 첫 번째 인수로 주소를 넣으면 

- 동시에 여러 개의 미들웨어 장착 가능

- next도 호출하지 않고 응답도 보내지 않으면 클라이언트는 응답을 받지 못해 계속 기다리게 됨

- res.locals 객체를 통해 미들웨어 간에 데이터 공유 가능

 

7) multer

- 여러가지 파일을 멀티파트 형식으로 업로드할 때 사용

 

 

06.3 Router 객체로 라우팅 분리하기

 

라우터를 분리할 수 있는 방법

a) routes 폴더 만들기

b) 폴더안에 index.js와 user.js를 작성

//index.js
const express = require('express');

const router = express.Router();

// GET / 라우터
router.get('/', (req, res) => {
  res.send('Hello, Express');
});

module.exports = router;
//user.js
const express = require('express');

const router = express.Router();

// GET /user 라우터
router.get('/', (req, res) => {
  res.send('Hello, User');
});

module.exports = router;

 

c) js 파일을 app.use를 통해 app.js에 연결

//app.js
...
const path = require('path');

dotenv.config();
const indexRouter = require('./routes');
const userRouter = require('./routes/user');
...
  name: 'session-cookie',
}));

app.use('/', indexRouter);
app.use('/user', userRouter);

app.use((req, res, next) => {
  res.status(404).send('Not Found');
});

app.use((err, req, res, next) => {
...

 

d) 에러 처리 미들웨어 위에 404 상태코드를 응답하는 미들웨어를 하나 추가

e) 서버를 실행한 뒤 localhost:3000과 localhost:3000/user로 접속하면 각각에 해당하는 응답을 받을 수 있음

 

 

06.4 req, res 객체 살펴보기

- 익스프레스의 req, res객체 => http 모듈의 req, res 객체를 확장한 것

req.app req 객체를 통해 app 객체에 접근
req.body body-parser 미들웨어가 만드는 요청의 본문을 해석
 req.cookies cookie-parser 미들웨어가 만드는 요청의 쿠키를 해석
req.ip 요청의 ip 주소가 담겨 있음
req.params 라우트 매개변수에 대한 정보가 담긴 객체
req.query 쿼리스트링에 대한 정보가 담긴 객체
req.signedCookies 서명된 쿠키들은 req.cookies 대신 여기에 담겨있음
req.get(헤더 이름) 헤더의 값을 가져오고 싶을 때 사용
res.app req.app처럼 res 객체를 통해 app 객체에 접근할 수 있음
res.cookie(키, 값, 옵션) 쿠키를 설정하는 메서드
res.clearCookie(키, 값, 옵션) 쿠키를 제거하는 메서드
res.end() 데이터 없이 응답을 보냄
res.json(JSON) JSON 형식의 응답을 보냄
res.locals 하나의 요청 안에서 미들웨어 간에 데이터를 전달하고 싶을 때 사용
res.redirect(주소) 리다이렉트할 주소와 함께 응답을 보냄
res.render(뷰, 데이터) 다음 절에서 다룰 템플릿 엔진을 렌더링해서 응답할 때 사용
res.send(데이터) 데이터(HTML, 문자열, 버퍼 등)와 함께 응답을 보냄
res.sendFile(경로) 경로에 위치한 파일을 응답
res.set(헤더, 값) 응답의 헤더를 설정
res.status(코드) 응답 시의 HTTP 상태 코드를 지정

 

※ 메서드 체이닝 : 객체의 메서드를 연속적으로 호출하는 방식 --> 코드양을 줄일 수 있음

req나 res 객체의 메서드는 메서드체이닝을 지원하는 경우가 많음

 

 

06.5 템플릿 엔진 사용하기

- 자바스크립트를 사용해서 HTML을 렌더링할 수 있게 함

 

대표적인 템플릿 엔진1) 퍼그- 문법이 간단해서 코드양 줄어듦- HTML과 문법이 많이 다름

 

  • HTML과 차이점

1-1) HTML 표현

퍼그 HTML
doctype html
html
    head
        title = title
        link(rel='stylesheet', href='/stylesheets/style.css')
<!DOCTYPE html>
<html>
    <head>
        <title>익스프레스</title>
        <link rel="stylesheet" href="/style.css"/>
    </head>
</html>
퍼그 HTML
#login-button
.post-image
span#highlight
p.hidden.full
<div id="login-button></div>
<div class="post-image"></div>
<span id="highlight"></span>
<p class="hidden full"></p>

속성 중 아이디와 클래스가 있는 경우 다음과 같이 표현

 

- HTML 텍스트는 태그 또는 속성 뒤에 한 칸을 띄고 입력하면 됨

- 에디터에서 텍스트를 여러 줄 입력하고 싶다면 파이프(|) 사용 (HTML 코드에서는 한 줄로 나옴)

- style이나 script 태그로 CSS 또는 자바스크립트 코드를 작성하고 싶다면 다음과 같이 태그 뒤에 점(.)을 붙임

 

1-2) 변수

- 자바스크립트 변수를 템플릿에 렌더링 가능

 

1-3) 반복문

- 반복문 사용 가능 (HTML 불가능)

   --> each 나 for를 활용

 

1-4) 조건문

- 조건문(if, else if, else) 사용 가능

 

1-5) include

- 다른 퍼그나 HTML파일 넣을 수 있음

'include 파일 경로'의 형태로 사용

 

1-6) extends와 block

- 레이아웃을 정할 수 있으며, 공통되는 레이아웃 부분 따로 관리 가능

 

 

2) 넌적스

- 퍼그의 HTML 문법 변화에 적응하기 힘든 사람에게 유용

-  HTML 문법을 그대로 사용하되 추가로 자바스크립트 문법을 사용

- 연결방법

a) configure의 첫 번째 인수로 views 폴더의 경로를 넣음

b) 두 번째 인수로 옵션을 넣음

c) express 속성에 app 객체를 연결

d) atch 옵션이 true이면 HTML 파일이 변경될 때 템플릿 엔진을 다시 렌더링

 pug와 같은 특수 확장자 대신 html그대로 사용 가능

 

2-1) 변수

- res.render 호출 시 보내는 변수를 넌적스가 처리

넌적스에서 변수는 {{}}로 감쌈

 

2-2) 반복문

- 넌적스에서는 특수한 문{% %}안에 씀- 반복문도 이 안에 씀- for in문과 endfor사이에 위치

 

2-3) 조건문

- 조건문도 마찬가지로 {% %}안에 if, elif, else, endif 사용

 

2-4) include

- 다른 HTML 파일을 넣을 수 있음- include 파일 경로와 같은 형태로 사용- 웹 제작 시 공통되는 부분 따로 관리 가능

 

2-5) extends와 block

- 레이아웃을 정할 수 있으며, 공통되는 레이아웃 부분을 따로 관리 가능

 

 

3) 에러 처리 미들웨어

- 404 응답 미들웨어와 에러 처리 미들웨어를 다음과 같이 수정해 에러 발생 시 error.html에 에러 내용을 표시

 

 

07. MySQL

- MYSQL : SQL 언어를 사용하는 관계형 데이터베이스 관리 시스템의 대표 주자

- 몽고디비 : NoSQL의 대표 주자

 

 

07.1 데이터베이스란?

- 관련성을 가지며 중복이 없는 데이터들의 집합

 

DBMS : 데이터베이스를 관리하는 시스템

서버의 하드 디스크나 SSD등의 저장 매체에 데이터를 저장

여러 사람이 동시에 사용 가능

 

RDBMS: 관계형 DBMS

SQL이라는 언어를 사용해 데이터 관리

 

07.2 MYSQL 설치하기 (리눅스)

- 윈도와 맥은 워크벤치 설치 필요

mysql-server 설치
외부 접속 기능 설정, MYSQL실행

 

07.4 데이터베이스 및 테이블 생성하기

 

1) 데이터베이스 생성하기

MYSQL 프롬프트로 진행

CREATE SCHEMA [데이터베이스명] : 데이터베이스 생성 명령어

nodejs라는 이름의 데이터베이스를 생성한 다음, use nodejs; 명령어를 추가로 입력해 앞으로 nodejs 데이터베이스를 사용하겠다는 것을 MySQL에 알림

세미클론을 붙여야 해당 구문 실행

 

2) 테이블 생성하기

테이블 : 데이터가 들어갈 수 있는 틀

mysql> CREATE TABLE nodejs.users (
    -> id INT NOT NULL AUTO_INCREMENT,
    -> name VARCHAR(20) NOT NULL,
    -> age INT UNSIGNED NOT NULL,
    -> married TINYINT NOT NULL,
    -> comment TEXT NULL,
    -> created_at DATETIME NOT NULL DEFAULT now(),
    -> PRIMARY KEY(id),
    -> UNIQUE INDEX name_UNIQUE (name ASC))
    -> COMMENT = '사용자 정보'
    -> ENGINE = InnoDB;
Query OK, 0 row affected (0.09 sec)

CREATE TABLE [데이터베이스명.테이블명]로 테이블을 생성

콤마(,)로 구분해 칼럼 생성

  • 칼럼의 자료형
INT 정수를 의미
VARCHAR 자릿수를 의미
TEXT 긴글을 저장할 때 사용
TINYINT -128부터 127까지의 정수를 저장할 때 사용
DATETIME 날짜와 시간에 대한 정보
  • 옵션
NULL, NOTNULL 빈칸을 허용할지 여부를 묻는 옵션
AUTO_INCREMENT 숫자를 저절로 올리겠다는 뜻
UNSIGNED 숫자 자료형에 적용되는 옵션
ZEROFILL 숫자의 자릿수가 고정되어 있을 때 사용
COMMENT 테이블에 대한 보충 설명

 

mysql> CREATE TABLE nodejs.comments (
    -> id INT NOT NULL AUTO_INCREMENT,
    -> commenter INT NOT NULL,
    -> comment VARCHAR(100) NOT NULL,
    -> created_at DATETIME NOT NULL DEFAULT now(),
    -> PRIMARY KEY(id),
    -> INDEX commenter_idx (commenter ASC),
    -> CONSTRAINT commenter
    -> FOREIGN KEY (commenter)
    -> REFERENCES nodejs.users (id)
    -> ON DELETE CASCADE
    -> ON UPDATE CASCADE)
    -> COMMENT = '댓글'
    -> ENGINE=InnoDB;
Query OK, 0 row affected (0.09 sec)

사용자의 댓글을 저장하는 테이블

 

 

07.5 CRUD 작업하기

- Create, Read, Update, Delete의 첫 글자를 모은 두문자어

- 데이터베이스에서 많이 수행하는 네 가지 작업

 

1) Create(생성)

- 데이터를 생성해서 테이터베이스에 넣는 작업

- 데이터를 넣는 명령어 : INSERT INTO [테이블명] ([컬럼1], [컬럼2], .. .) VALUES ([값1], [값 2], ...)

 

2) Read(조회)

- 데이터베이스에 있는 데이터를 조회하는 작업

- users 테이블의 모든 데이터를 조회하는 SQL문 : SELECT * FROM [테이블명]

- 특정 칼럼만 조회하는 것도 가능

 

3) Update(수정)

- 데이터베이스에 있는 데이터를 수정하는 작업

- 수정 명령어 : UPDATE [테이블명] SET [컬럼명=바꿀 값] WHERE [조건]

 

4) Delete(삭제)

- 데이터베이스에 있는 데이터를 삭제하는 작업

- 삭제 명령어 : DELETE FROM [테이블명] WHERE [조건]

 

 

07.6 시퀄라이즈 사용하기

- MYSQL 작업을 쉽게 할 수 있도록 도와주는 라이브러리

- 자바스크립트 객체와 데이터베이스의 릴레이션을 매핑해주는 도구(ORM)로 분류됨

- 다른 데이터베이스도 같이 사용 가능

- 자바스크립트 구문을 알아서 SQL로 바꿔줌  -->  자바스크립트만으로 MySQL 조작 가능

 

a) equelize와 sequelize-cli, mysql2 패키지를 설치

$ npm i express morgan nunjucks sequelize sequelize-cli mysql2
$ npm i -D nodemon
$ npx sequelize init

 

b) 익스프레스와 시퀄라이즈 연결코드 작성

//app.js
const express = require('express');
const path = require('path');
const morgan = require('morgan');
const nunjucks = require('nunjucks');

const { sequelize } = require('./models');

const app = express();
app.set('port', process.env.PORT || 3001);
app.set('view engine', 'html');
nunjucks.configure('views', {
  express: app,
  watch: true,
});
sequelize.sync({ force: false })
  .then(() => {
    console.log('데이터베이스 연결 성공');
  })
  .catch((err) => {
    console.error(err);
  });

app.use(morgan('dev'));
app.use(express.static(path.join(__dirname, 'public')));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));

app.use((req, res, next) => {
  const error =  new Error(`${req.method} ${req.url} 라우터가 없습니다.`);
  error.status = 404;
  next(error);
});

app.use((err, req, res, next) => {
  res.locals.message = err.message;
  res.locals.error = process.env.NODE_ENV !== 'production' ? err : {};
  res.status(err.status || 500);
  res.render('error');
});

app.listen(app.get('port'), () => {
  console.log(app.get('port'), '번 포트에서 대기 중');
});

 

c) MySQL과 연동할 때는 config 폴더 안의 config.json 정보가 사용 

//config/config.json
{
  "development": {
    "username": "root",
    "password": "[root 비밀번호]",
    "database": "nodejs",
    "host": "127.0.0.1",
    "dialect": "mysql"
  },
...
}

password 속성에는 MySQL 비밀번호를 입력하고, database 속성에는 nodejs를 입력

 

d) $ npm start로 서버 실행

 

e) 두 로그가 뜨면 연결 성공

 

2) 모델 정의하기

- MySQL에서 정의한 테이블을 시퀄라이즈에서도 정의해야 함

- MySQL의 테이블은 시퀄라이즈의 모델과 대응됨

- 시퀄라이즈는 기본적으로 모델 이름은 단수형으로, 테이블 이름은 복수형으로 사용

 

2-1) static initiate

- 테이블에 대한 설정

 

2-2) static associate 

- 다른 모델과의 관계를 작성

MySQL 시퀄라이즈
VARCHAR(100) STRING(100)
INT INTEGER
TINYINT BOOLEAN
DATETIME DATE
INT UNSIGNED INTEGER.UNSIGNED
NOT NULL allowNull: false
UNIQUE unique: true
DEFAULT now() defaultValue: Sequelize.NOW

MySQL과 시퀄라이즈의 비교

sequelize static initiate 메서드의 매개변수와 연결되는 옵션
timestamps 로우가 생성될 때와 수정될 때의 시간이 자동으로 입력
underscored  캐멀 케이스(camel case)를 스네이크 케이스(snake case)로 바꾸는 옵션
modelName 모델 이름을 설정
tableName 실제 데이터베이스의 테이블 이름이 됨
paranoid 로우를 삭제할 때 완전히 지워지지 않고 deletedAt에 지운 시각이 기록됨
charset  utf8로 설정해야 한글이 입력
collate utf8_general_ci로 설정해야 한글이 입력

테이블 옵션

3) 관계 정의하기

일대다 관계  -->  ex) 사용자 한명은 댓글을 여러 개 작성 가능

일대일 관계  -->  ex) 사용자와 사용자에 대한 정보 테이블

다대다 관계  -->  ex) 게시글 테이블과 해시태그 테이블

 

3-1) 일대다(1:N) 관계

- hasMany라는 메서드로 표현 - sers 테이블의 로우 하나를 불러올 때 연결된 comments 테이블의 로우들도 같이 불러올 수 있음

- belongsTo 메서드(반대) : comments 테이블의 로우를 불러올 때 연결된 users 테이블의 로우를 가져옴

Tip) 다른 모델의 정보가 들어가는 테이블에는 belongsTo를 사용

 

3-2) 일대일(1:1) 관계

- hasMany 메서드 대신 hasOne 메서드 사용

 belongsTo hasOne이 반대이면 안됨

 

3-3) 다대다(N:M) 관계

- belongsToMany 메서드 사용

- 메서드 사용 후 새로운 모델 생성되면 through 속성에 모델 이름 작성 

- 데이터를 조회할 때 여러 단계를 거쳐야 함

 

4) 쿼리 알아보기

- 프로미스를 반환하므로 then을 붙여 결괏값을 받을 수 있음

- async/await 문법과 같이 사용 가능

 데이터를 넣을 때 MySQL의 자료형이 아니라 시퀄라이즈 모델에 정의한 자료형대로 넣어야 함

 

로우를 조회하는 쿼리

  • 모든 데이터를 조회하는 SQL문
SELECT * FROM nodejs.users;
User.findAll({});

 

  • Users 테이블의 데이터 하나만 가져오는 SQL문
SELECT * FROM nodejs.users LIMIT 1;
User.findOne({});

 

  • attributes 옵션을 사용해서 원하는 컬럼 가져옴
SELECT name, married FROM nodejs.users;
User.findAll({
  attributes: ['name', 'married'],
});

 

  • where 옵션이 조건들을 나열하는 옵션
SELECT name, age FROM nodejs.users WHERE married = 1 AND age > 30;
const { Op } = require('sequelize');
const { User } = require('../models');
User.findAll({
  attributes: ['name', 'age'],
  where: {
    married: true,
    age: { [Op.gt]: 30 },
  },
});

 undefined라는 자료형을 지원하지 않으므로 where 옵션에는 undefined가 들어가면 안 됨(null 대신 사용)

 

시퀄라이즈 연산자

Op.gt 초과
Op.gte 이상
Op.lt 미만
Op.lte 이하
Op.ne 같지 않음
Op.or 또는
Op.in 배열 요소 중 하나
Op.notIn 배열 요소와 모두 다름

 

조회할 로우 개수를 설정하는 방법

- limit  옵션으로 가능

SELECT id, name FROM users ORDER BY age DESC LIMIT1;
User.findAll({
  attributes: ['id', 'name'],
  order: [['age', 'DESC']],
  limit: 1,
});

 

로우를 수정하는 쿼리

- update 메서드로 수정 가능

UPDATE nodejs.users SET comment = '바꿀 내용' WHERE id = 2;
User.update({
  comment: '바꿀 내용',
}, {
  where: { id: 2 },
});

 

로우를 삭제하는 쿼리

- destroy 메서드로 삭제

DELETE FROM nodejs.users WHERE id = 2;
User.destory({
  where: { id: 2 },
});

 

4-1) 관계 쿼리

- findOne이나 findAll 메서드를 호출할 때 프로미스의 결과로 모델을 반환

- MySQL의 JOIN 기능

- 여러 개를 추가할 때는 배열로 추가 가능

 

4-2) SQL 쿼리하기

- 직접 SQL문을 통해 쿼리 가능 (추천 X)

 

5) 쿼리 수행하기

 

5-1) 모델에서 데이터를 받아 페이지를 렌더링하는 방법

- async/await try/catch문을 사용해서 조회 성공 시와 실패 시의 정보를 얻을 수 있음

- 데이터베이스에서 데이터를 조회한 후 템플릿 렌더링에 사용 가능

 

5-2) JSON 형식으로 데이터를 가져오는 방법

- 데이터를 반활할 때 JSON 형식으로 반환

 

  • 댓글에 관련된 CRUD 작업을 하는 라우터
POST /comments 댓글을 생성하는 라우터
PATCH /comments/:id 댓글을 수정하는 라우터(update메서드 사용)
DELETE /comments/:id 댓글을 삭제하는 라우터(destroy메서드 사용)

 

 

09. 익스프레스 SNS서비스 만들기

 

09.1 프로젝트 구조 갖추기

1) nodebird 속성 생성

2) package.json 생성

3) 시퀄라이즈 설치

4) 필요한 폴더들 생성

5) npm 패키지들 설치, app.js 작성(라우터 생성, 미들웨어.에러 처리 미들웨어, 8001번 포트에 연결)

6) 기본적인 라우터와 템플릿 엔진 생성

7) 컨트롤러(controllers폴더) 생성 --> 미들웨어 중 하나, 코드를 편하게 관리 가능

8) 클라이언트 코드 생성 (html, css)

9) npm start로 서버 실행

 

09.2 데이터베이스 세팅하기

- MySQL과 시퀄라이즈로 데이터베이스 설정

1) models 폴더 안에 js파일 생성 (사용자 정보를 저장하는 모델)

2) 생성된 모델 시퀄라이즈에 등록

3) 모델을 시퀄라이즈 객체에 연결

4) 모델 간의 관계를 associate 함수 내에 정의

5) 생성한 모델을 데이터베이스 및 서버에 연결

6) npx sequelize db:create 명령어를 통해 데이터베이스 생성

데이터베이스 생성에서 발생한 오류

 

반응형