테스트주도개발(TDD)로 만드는 NodeJS API 서버 - 001
오리엔테이션
강의소개
노드로 API 서버 만들기
테스트 주도 개발 익히기
개발 환경 구성
nodejs 설치 확인
$ node -v
$ npm -v
비쥬얼 스튜디오설치
NodeJS 기초
V8 엔진
브라우저 밖에서 자바스크립트 코드를 실행 할 수 있다
크롬에서 사용하는 V8 엔진을 사용한다
이벤트 기반의 비동기 I/O 프레임워크
CommonJS를 구현한 모듈 시스템
이벤트기반 비동기 I/O
- 클라이언트가 nodejs 서버로 HTTP 요청을 보냄
- nodejs 서버는 HTTP 요청을 이벤트로 만들어서 event queue 에 보관
- event loop 가 이벤트큐에 있는 이벤트를 하나씩 꺼내서 job 으로 처리함 (
이벤트기반
) - 이 event loop 가 single thread 임
- 바로 응답할 수 있는 job 은 event loop 가 처리하여 클라이언트로 리턴함
- 바로 응답할 수 없는 job 은 Non-blocking Worker 에게 위임하여 비동기로 처리함 (
비동기 I/O
) - Non-blocking Worker 는 작업을 완료하면 callback 으로 event loop 에 돌려줌
모듈시스템1
브라우저에서는 모듈을 만들 때 윈도우 객체를 사용
// 브라우저의 개발자 모드
> window.module1 = function() { return 'myModule1'; }
> module1();
"myModule1";
> windows.module1();
"myModule1";
혹은 RequireJS 같은 의존성 로더를 사용
nodejs 는 파일형태로 모듈을 관리할 수 있는 CommonJS 로 구현
모듈시스템2
http 모듈 사용예시
// http 라는 모듈을 가져와서 http 라는 변수에 할당
const http = require('http');
// http 모듈의 createServer() 함수 실행
http.createServer();
모듈 만들기
math.js 생성
// node-api/math.js
function sum(a, b) {
return a + b;
}
module.exports = {
sum: sum
}
index.js 에서 만든 모듈 사용하기
// node-api/index.js
const math = require('./math.js');
const result = math.sum(1, 2);
console.log(result);
실행
# node-api 폴더에서
$ node index.js
3
비동기 세계 1 - readFileSync
노드는 기본적으로 비동기로 동작함
- readFile() vs readFileSync() 의 이해
data.txt 생성
// node-api/data.txt
This is data file
index.js
// node-api/index.js
const fs = require('fs');
const data = fs.readFileSync('./data.txt', 'utf8');
console.log(data);
console.log('end');
실행
# node-api 폴더에서
$ node index.js
This is data file
end
비공기 세계 2 - readFile
index.js
// node-api/index.js
const fs = require('fs');
const data = fs.readFile('./data.txt', 'utf8', function(err, data){
console.log(data);
});
console.log('end');
실행
# node-api 폴더에서
$ node index.js
end
This is data file
비동기는 원래 함수가 호출된 세계와 콜백함수의 세계가 시간적으로 분리되는 개념
노드로 만나는 Hello World
Hello World 노드버전
index.js
// node-api/index.js
const http = require('http');
const hostname = '127.0.0.1';
const port = 3000;
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end('Hello, World!\n');
});
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
실행
# node-api 폴더에서
$ node index.js
Server running at http://localhost:3000/
# 종료는 Ctrl + c
접속확인
$ curl -X GET 'localhost:3000'
Hello, World!
헬로월드 코드읽기
index.js
// node-api/index.js
const http = require('http'); // http 모듈을 가져옴
const hostname = '127.0.0.1'; // hostname 선언, 할당
const port = 3000; // port 선언, 할당
const server = http.createServer((req, res) => { // http 의 createServer 함수를 실행
// 파라메터로 (req, res) ~ res.end 까지 전달
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end('Hello, World!\n');
});
server.listen(port, hostname, () => { // server 의 listen 을 실행해서 클라이언트 요청 대기 상태로 만듬
console.log(`Server running at http://${hostname}:${port}/`);
});
라우팅 추가하기
현재 index.js 는 어떤 경로를 호출하더라도 ‘Hello, World!’ 라고 응답합
호출하는 경로에 따라 다른 응답을 하도록 개선
index.js
// node-api/index.js
const http = require('http');
const hostname = '127.0.0.1';
const port = 3000;
const server = http.createServer((req, res) => {
if(req.url === '/') {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end('Hello, World!\n');
} else if(req.url === '/users') {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end('User list');
} else {
res.statusCode = 404;
res.end('Not Found');
}
});
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
실행
# node-api 폴더에서
$ node index.js
Server running at http://localhost:3000/
접속확인
$ curl -X GET 'localhost:3000'
Hello, World!
$ curl -X GET 'localhost:3000/users'
User list