랄지 IT
Express 정리 본문
Express는 Node.js 환경에서 동작하는 웹 애플리케이션 프레임워크 이다.
웹 애플리케이션 구성에 필요한 기능들을 제공한다.
Express는 Node.js가 설치되어 있음을 전제로 한다.
npm으로 express를 설치한다.
npm install express
사용 법)
app.js를 생성하여 express를 불러오고, express 메소드를 호출하여 사용한다.
사용 예)
const express = require('express');
const app = express();
app.get('/', (req, res) => res.send('hellow world'));
app.listen(3000, () => console.log('...'));
라우팅
클라이언트는 서버에 URI 및 HTTP 요청 메소드 (get, post 등)으로 요청을 전달한다.
이러한 클라이언트 요청에 응답하는 방법을 결정하는 것을 라우팅이라 한다.
라우팅 사용예)
app.method(path, handler)
*method: get, post 등
*path: 라우트
*handler: 클라이언트 요청 url과 라우트가 일치할 경우 실행될 함수
body-parser
body-parser 미들웨어는 body에 담겨 보내진 데이터를 request 객체의 body 프로퍼티에 바인딩한다.
body-parser를 설치가 필요하다.
body-parser설치후, app.js에 추가한다.
const bodyParser = require('body-parser')
app.user(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
라우트 메소드
Express는 HTTP 메소드에 해당하는 라우팅 메소드를 지원한다.
(GET, POST, PUT 등등)
app.all() 메소드는 모든 HTTP 메소드에 대응한다.
next()를 사용하면 후속 라우트 핸들러로 제어를 전달할 수 있다.
사용예)
app.all('/', (req,res,next) => { console.log(...), next() }, 후속핸들러)
라우트 패스
: 문자열 또는 정규표현식을 사용할 수 있다.
app.get('/문자열', (req,res) => res.send('root'));
app.get('/정규표현식', ...);
라우트 핸들러
: 요청을 처리하는 콜백함수 이다. 함수나 함수배열 또는 둘을 조합한 형태로 사용한다.
app.get('/', (req,res) => {});
const 함수1 = function(req,res,next){
...
}
app.get('/', [함수1, 함수2, 함수3]);
Response methode
- res.메소드() 형식으로 사용한다.
- res.redirect() 요청경로를 재지정함
- res.render() 뷰 템플릿을 렌더링함
- res.send() 다양한 유형의 응답을 전송함
등등이 있다.
미들웨어
- 요청 오브젝트(req), 응답 오브젝트(res) 그리고
애플리케이션의 요청-응답 사이클 내에서
다음 미들웨어 함수에 대한 액세스 권한을 갖는 함수 이다.
- 미들웨어에는 유용한 동작을 하거나, 요청이 실행되는 데 도움이 되는
무언가를 추가하는 패스스루 함수가 있다.
예를 들면, 바디파서와 쿠키파서는
각각 HTTP요청 페이로드(req.body)와 파싱된 쿠키 데이터(req.cookie)를 추가한다.
정적 파일의 제공
app.use(express.static('public'))
템플릿 엔진
- pug, ejs 등의 템플릿 엔진을 사용할 수 있다.
- 엔진 지정후, 세팅한다.
예)
app.set('views', __dirname + '/views'); // 디렉토리 경로 지정
app.set('view engine', 'ejs'); // 뷰 엔진 지정
app.engine('html', require('ejs').renderFile); // 엔진 설정
에러 핸들링
- 웹 애플리케이션은 에러가 발생하였을 경우, 반드시 클라이언트에
에러 관련 정보를 알려야 한다.
- 에러는 1.클라이언트에 의한것(잘못된 인풋데이터) 2. 서버에 의한것(코드내 버그)
둘 중 하나 일 수 있다.
- 익스프레스에서 에러처리는 매개변수가 4개 (err,req,res,next)인 미들웨어 함수를 사용한다.
세션
- 웹 애플리케이션은 로그인 인증 등의 용도로 세션을 사용한다.
익스프레스는 메모리상(MemoryStore)에 세션 데이터를 저장할 수 있다.
- 개발을 위한 MemoryStore 사용은 문제될 경이 없지만,
Production 환경에서는 적절하지 않으므로,
Production 환경에서는 Redis, MongoDB 등을 사용하여
영속적 Session Data를 관리하는 것이 일반적이다.
- HTTP 프로토콜은 상태를 유지하지 않는다. (stateless protocol)
HTTP 프로토콜은 요청을 전송하고, 응답을 전송받은 시점에서 통신이 종료되며,
어떠한 상태 정보도 남지 않는다.
따라서 로그인 상태임을 인식(유지)할 수 없으므로, 매번 사용자 인증과정을 반복해야 한다.
이를 보완하기 위해 Session과 Cookie를 사용한다.
- 쿠키: 클라이언트에 일시적으로 데이터를 저장하는 방식.
(이전 접속한 URL과 다른 URL에서는 쿠키를 사용할 수 없음)
- 세션: 브라우저를 통해 서버에 접속한뒤, 접속을 종료하는 시점까지를 세션이라고 함.
세션은 최초 접속시점에 생성되어 일정기간 유지되며, 접속이 종료되면(브라우저 종료시) 삭제된다.
- 쿠키와 달리 세션은 서버에 저장된다. 세션은 쿠키보다 안전하다.
- cookie-based session:
쿠키에 보안에 관련된 정보를 저장하는 것은 바람직하지 않으므로,
쿠키에는 Session ID만을 저장하고 전송된 Session ID를 사용하여
Session에 저장된 정보를 사용하는 방법
- MemoryStore를 사용한 세션관리
사용예)
var session = require('express-session')
app.use(session({ // 세션설정
secret: '...',
resave: false,
saveUninitialized: true
}))
app.get('/...', function(req,res){
var session = req.session;
if(session && session.count){
...
}
})
- 세션 데이터는 쿠키에 저장되지 않고, 서버사이드에 저장된다. 쿠키에는 세션ID만이 저장된다.
Redis를 사용한 세션관리
- Redis는 in-memory data structure store로, key-value 형태로 data를 저장한다.
- express의 경우, connect-redis 모듈을 사용하여 redis를 사용한 세션관리가 가능하다.
- redis는 공식적으로 windows를 지원하지 않지만, 64bit포팅판을 제공하고 있다.
- npm으로 connect-redis 모듈을 인스톨하고, 세션 설정시 stroe: new RedisStore({})를 넣어준다.
- (애플리케이션을 재가동 하여도 이전 카운트가 보존된다.)
MySQL 연동
- MySQL은 오픈 소스 관계형 데이터베이스 관리 시스템(RDBMS)이다.
- 사전에 (컴퓨터 등에) MySQL이 설치되어 있어야 하고, npm 모듈 설치 후, 사용할 수 있다. (npm install)
- MySQL에 접속하여 테이블을 생성하고 테스트용 데이터를 insert 한다.
CREATE DATABASE ...
CREATE TABLE ...
INSERT INTO ...
SELECT ...
- Node.js와 MYSQL 연동)
createConnect 메소드의 인자로 전달되는 객체에
자신의 데이터베이스 정보(유저명, 패스워드 등)을 입력하여야 한다.
사용예)
const mysql = require('mysql');
const connection = mysql.createConnection({
host: 'localhost',
user: mysql username,
password: mysql password,
database: mysql database name
});
connection.connect(); // 연결
connection.query('SELECT * from Users', (error, rows, field) => {
if(error) throw error;
console.log(rows); // 콘솔에 결과 출력되면 성공한 것임
});
connection.end();
Route 작성
- 클라이언트 요청에 대응하는 라우트 설정
app.get('/usres', (req,res) => {
connection.query('SELECT * FROM Users', (error, rows) => {
if(error) throw error;
console.log(rows);
res.send(rows); // 쿼리 조회후 나온 (db)데이터 전송함
});
})
실시간 채팅 애플리케이션
- Node.js에서는 손쉽게 RTC(실시간 양방향 통신=>채팅 등)의
웹 애플리케이션을 작성할 수 있는 Socket.io를 사용할 수 있다.
- WebSocket: 브라우저와 서버 간 동적인 양방향 연결 채널을 구성하는 HTML5 프로토콜이다.
하지만, 오래된 브라우저의 경우에는 지원하지 않는 경우가 있다.
- 브라우저 간 호환이나 이전 버전 호환을 고려하여 Node.js를 위한
강력한 크로스 플랫폼 WebSocket API인 Socket.io를 사용하는 것이 바람직 하다.
- 설치후 사용: npm install socket.io
소켓 서버측 코드)
var app = require('express')();
var server = require('http').createServer(app);
var io = require('socket.io')(server);
app.get('/', function(req,res) {
res.sendFile(__Dirname + '/index.html');
});
// 클라이언트가 소켓 서버에 접속했을때, connection 이벤트가 발생한다.
// connection 이벤트 핸들러를 정의한다.
io.on('connection', function(socket){
});
- connection event handler function의 인자로 socket 객체가 전달된다.
socket객체는 개별 클라이언트와의 interacting을 위한 기본적인 객체이다.
io 객체는 연결된 전체 클라이언트와의 interacting을 위한 객체이다.
- connection event가 발생(클라이언트가 접속)하면 클라이언트가 전송한 메시지를
수신하거나 클라이언트에게 메세지를 전송한다.
수신:받음)
// 이벤트명: 클라이언트가 메시지 전송시 지정
// function: 이벤트 핸들러, data는 송신한 메세지
socket.on('이벤트명', function(data){
console.log(data)
});
송신:보냄)
// emit: 메세지 전송
// msg: 송신 메세지
// 접속된 모든 클라이언트에게 메세지를 전송한다.
io.emit('이벤트명', mgs);
// 메세지를 전송한 클라이언트에게만 메세지를 전송한다.
socket.emit('이벤트명', msg);
// 특정 클라이언트에게만 메세지를 전송한다.
io.to(id).emit('이벤트명', data);
소켓 클라이언트측 코드)
- 클라이언트 라이브러리는 스크립트 태그의 src 어트리뷰트 값으로
'/socket.io/socket.io.js'를 지정하면 된다. 실제 패스에 socket.io 파일을 배치할 필요는 없다.
그 이유는 socket.io가 서버 가동시에 소켓 라이브러리를 자동 생성 해주기 때문이다.
- socket.io 서버에 접속하기 위해 io() 메소드를 호출한다.
$(function(){ // 즉시실행함수로 싼다
var socket = io();
메세지 송신) emit 메소드 사용
socket.emit('이벤트 이름', 메시지);
메세지 수신) on 메소드 사용
socket.on('이벤트 이름', function(data){
console.log(data);
});
});
- 소켓은 서로 다른 엔드포인트 또는 경로를 할당하는 의미로
소켓에 네임스페이스를 지정할 수 있다.
네임 스페이스를 특별히 지정하지 않은 경우, 디폴트로 '/'를 사용하게 된다.
* 네임스페이스(Namespace): 개체를 구분할 수 있는 범위를 나타내는 말로
일반적으로 하나의 이름 공간에서는 하나의 이름이 단 하나의 개체만을 가리키게 된다.
- Room:
각 네임스페이스 내에서 임의의 채널을 지정할 수 있다. 이를 room이라 하며,
이를 통해 room에 join되어 있는 클라이언트 만의 데이터 송수신이 가능하게 된다.
즉, 클라이언트는 socket을 가지게 되며, 이 socket은 네임스페이스를 가지고,
각 네임스페이스는 room을 가질 수 있다.
각 socket은 랜덤하고 유일하게 작성된 socket.id로 구별된다.
room에 join하기 위해서는 join메소드를 사용한다.
사용예: 서버)
var chat = io.of('/chat').on('connection', function(socket){
socket.on('chat message', function(data){
console.log(data);
var name = socket.name = data.name;
var room = socket.room = data.room;
socket.join(room); // room에 join한다.
chat.to(room).emit('chat message', data.msg); // room에 메세지 전송
})
})
사용예: 클라이언트)
var chat = io('http://localhost:3000/chat'),
news = io('/news');
$('form').submit(function(e){
e.prevaenDefault();
// 서버로 자신의 정보를 전송한다.
chat.emit('chat message', {
name: $("#name").val();
room: $("#room")val();
msg: $("#msg").val();
});
});
// 서버로부터 메시지가 수신되면 처리
chat.on("chat message", function(data){
$("#chat").append($('<li>').text(data));
});
Heroku에서 Node.js 와 MongoDB 설치
- Heroku는 AWS의 laaS상에 구축된 PaaS이다.
Git으로 deploy가 가능하며, 간단한 개발시 사용할 수 있는 플랫폼이다.
순서
1. node.js, npm, git이 사전에 install 되어 있어야 한다.
2. Heroku CLI 설치(Heroku 관리 도구=>홈페이지에서 받는다)하고, 로그인 한다. heroku login
3. Sample app을 clone 한다. git clone ...
4. app을 heroku에 생성한다. heroku create ...
5. 생성된 앱을 push 한다 git push ,,,
6. url 방문하여 앱 동작을 확인한다. 또는 명령어로 확인 한다. heroku open
* 로그 확인: heroku login --tail
* 루트 디렉터리에 있는 profile 에는 app이 start할때, 실행되어야 하는 동작을 명시적으로 정의한다.
web: node index.js
* 앱 실행시 반드시 heroku 명령어를 사용해야 하는 것은 아니다. 일반적인 방법(npm start)도 가능하다.
* github와 연동하여 heroku에 수정사항을 반영할수 도 있다.
=> (web) heroku dashboard: deploy 탭에서 connect to github 클릭후,
github repository를 등록할 수 있음. 이후 코드를 github에 push하면 자동으로 heroku deploy 실행.
* heroku addons:create papertrail 등으로 heroku add-on(별도 추가) 설치도 가능함.
=> Redis, MongoDB, MySQL 등 다수의 data store add-on을 제공한다.
- nodejs에서 MongoDB 사용위해서는 npm으로 mongoose를 설치후 require, 설정 추가, connect 하여 사용할 수 있다.
(과정은 위에서 작성한 MySQL과 비슷)
mongoDB 사용예)
var Books = require('./models/books');
app.get('/books', function(req,res){
Books.find(function(err, books){
if(err) return res.status(500).send({error: 'database failure'});
res.json(books);
})
})
'Node.js' 카테고리의 다른 글
Node.js 정리 (0) | 2021.03.02 |
---|