전날에는 tensorflow.js를 한번 훑어보고 다음 날 노드 공부를 시작하였다.
이전에 노드 공부하며 들었던 인프런 강의 중 괜찮았던 강의가 몇 개 생각나 다시 들을 예정
나 이렇게나 인프런 잘 이용하는데 인프런에서 상이라도 줘야되는거 아닌가 ~..
그나저나 공부해야할게 참으로 많 군 요 허허
[Inflearn] 테스트주도개발(TDD)로 만드는 NodeJS API 서버 - 김정환
node.js는 확장성 있는 네트워크 애플리케이션(특히 서버 사이드) 개발에 사용되는 소프트웨어 플랫폼이다.
작성 언어로 자바스크립트를 활용하며 논블로킹(Non-blocking) I/O와 단일 스레드 이벤트 루프를 통한 높은 처리 성능을 가지고 있다.
내장 HTTP 서버 라이브러리를 포함하고 있어 웹 서버에서 아파치 등의 별도의 소프트웨어없이 동작이 가능하며 이를 통해 웹 서버의 동작에 더 많은 통제를 가능케 한다.
(출처: 위키백과)
노드에서 모듈(module)이란?
노드로 개발한 어플리케이션을 이루는 기본 조직
- 기본 모듈 : node.js에서 기본적으로 제공하는 모듈
- 써드파티(third-party) 모듈 : 노드 모듈 패키지 관리 툴(NPM)로 설치한 모듈, node_modules 폴더 아래 설치됨
- 사용자 정의 모듈
module.exports = {
function1 : function1,
function2 : function2,
....
};
노드의 특징
1. 브라우저 밖에서 자바스크립트 코드 실행 가능
2. 크롬 v8 엔진 사용
3. 이벤트 기반의 비동기 I/O 프레임워크
1) 싱글 스레드로 동작하는 이벤트 큐에 요청 저장
2) 가벼운 이벤트의 경우 이벤트 루프에서 처리
3-1) 무거운 이벤트(파일 읽고 쓰기, 네트워크 등 시간이 다소 걸리는 이벤트)의 경우 논블록킹 워커 스레드로 보내 처리
3-2) 처리 후 다시 이벤트 큐에 전달
4. CommonJS를 구현한 모듈 시스템
노드는 파일 형태로 모듈을 관리할 수 있는 CommonJS로 구현
const module = require('module');
* ES6에서는 자바스크립트 자체 ES6 Module이라는 이름으로 모듈화를 지원하기 시작 -> import
노드 vs 자바스크립트
javascript는 브라우저를 통해서만 작동하며 주로 클라이언트 개발을 위해 사용되어왔음 (브라우저 콘솔창을 통해 실행됨)
이랬던 javascript를 서버사이드로 옮겨와 브라우저 밖에서 사용할 수 있도록 한 것이 바로 node
노드를 통해 자바스크립트로 서버 개발이 가능해짐!
const http = require('http');
const hostname = '127.0.0.1'; // host
const port = 3000; // port
const server = http.createServer((req, res) => {
// routing
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('users\n');
}else {
res.statusCode = 404;
res.end('Not Found\n')
}
});
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
node.js로 REST 서버를 편리하게 구현할 수 있도록 해주는 웹 프레임워크 중 하나 (그 외 Koa, Hapi 등이 있음)
npm install express
어플리케이션(application)
익스프레스 인스턴스로 서버에 필요한 기능을 추가하고 라우팅 설정, 서버를 요청 대기 상태로 만들 수 있다.
미들웨어(middle ware)
요청(req)과 응답(res) 객체, 요청-응답 중 다음 미들웨어 함수에 대한 액세스 권한을 갖는 함수로 구조 내에서 중간 처리를 위한 함수
* next()로 다음 함수를 호출하지 않을 경우 에러 발생
- express 웹 어플리케이션 생성과 미들웨어 예제
const express = require('express');
const app = express();
function logger(req, res, next) {
console.log('i am logger');
next(); // 다음 실행
}
function logger2(req, res, next) {
console.log('i am logger2');
next();
}
app.use(logger2);
app.use(logger);
// i am logger2 -> i am logger
app.listen(3000, function() {
console.log('Server is Running!');
})
- 에러 미들웨어 예제
const express = require('express');
const app = express();
// 일반 미들웨어
function commonmw(req, res, next) {
console.log('commonmw');
next(new Error('error occured'));
}
// 에러 미들웨어
function errormw(err, req, res, next) {
console.log(err.message);
next();
}
app.use(commonmw);
app.use(errormw); // error occured (commonmw error message)
app.listen(3000, function() {
console.log('Server is Running!');
})
에러가 발생할 때 앞에서 발생한 에러 객체를 인자로 받아서 사용
라우팅(routing)
요청 url에 대해 적절한 핸들러 함수로 연결해주는 기능 (Router 객체를 이용하여 라우팅도 가능)
app.use('/', function(req, res) {
// '/' 주소로 들어오는 모든 HTTP 메소드 요청 처리
});
app.get('/', function(req, res) {
// '/' 주소로 들어오는 GET 메소드 요청 처리
});
app.post('/data', function(req, res) {
// '/data' 주소로 들어오는 POST 메소드 요청 처리
});
모카(Mocha) nodejs 테스트 러너를 지원하는 테스트 프레임워크
Should 검증(assertion) 라이브러리로 assert 모듈을 불러오지 않고도 여러가지 검증 메서드 사용 가능, 가독성을 높혀줌
SuperTest 익스프레스 통합 테스트용 라이브러리, 내부적으로 익스프레스 서버를 가동시켜 실제로 요청을 보낸 뒤 결과 검증
[mocha] https://mochajs.org/
[should] https://github.com/tj/should.js/
[supertest] https://github.com/visionmedia/supertest
npm 모듈 설치
# 개발 의존성 모듈로 설치
npm install mocha --save-dev
npm install should --save-dev
npm install supertest --save-dev
package.json 의존성
"dependencies": {
...
},
"devDependencies": {
"mocha": "^9.1.2",
"should": "^13.2.3",
"supertest": "^6.1.6"
}
package.json 테스트 스크립트 추가 (mocha 테스트코드파일.js)
"scripts": {
"test": "mocha index.spec.js", // npm test
"start": "node index.js" // npm start
},
테스트할 js파일 마지막에 exports 추가
module.exports = {
function1 : function1,
function2 : function2,
...
};
테스트 파일 생성 -> ~.spec.js는 ~.js에 대한 테스트 코드 파일
* 모카(mocha) 메서드
- describe() : 테스트의 범위 설정
- it() : 단위테스트 설정
- done() : 비동기 단위 테스트 완료를 알려줌
* 검증(assertion)
- assert 모듈 이용
/* utils.js
function capitialize(str) {
return str.charAt(0).toUpperCase() + str.slice(1);
}
*/
const utils = require('./utils');
const assert = require('assert')
describe('utils.js모듈의 capitalize 함수는', () => {
it('문자열의 첫번째 문자를 대문자로 반환한다', () => {
const result = utils.capitialize('hello');
assert.equal(result, 'Hello');
})
});
- should 모듈 이용 (가독성↑)
const utils = require('./utils');
require('should')
describe('utils.js모듈의 capitalize 함수는', () => {
it('문자열의 첫번째 문자를 대문자로 반환한다', () => {
const result = utils.capitialize('hello');
result.should.be.equal('Hello')
})
});
-> 검증 성공
-> 검증 실패
예) /users?limit= limit만큼 사용자 목록 조회
index.js
const express = require('express')
const app = express()
const morgan = require('morgan');
const port = 3000;
app.use(morgan('dev'));
// user list
var users = [
{id: 1, name: 'alice'},
{id: 2, name: 'bek'},
{id: 3, name: 'chris'},
]
app.get('/users', (req, res) => {
const limit = parseInt(req.query.limit, 10); // 정수로 타입 변경(10진수)
if (Number.isNaN(limit)) {
// limit이 정수가 아닐 경우 parseInt() 결과 NaN 반환
return res.status(400).end();
}
res.json(users.slice(0, limit)); //res.body
});
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`)
});
// test
module.exports = app;
index.spec.js
describe('GET /users는', () => {
describe('성공 시', () => {
it('1-1) 유저 객체를 담은 배열을 응답한다.', (done) => {
request(app)
.get('/users')
.end((err, res) => {
console.log(res.body);
res.body.should.be.instanceOf(Array);
done();
});
});
it('1-2) 최대 limit 갯수만큼 응답한다', (done) => {
request(app)
.get('/users?limit=2')
.end((err, res) => {
console.log(res.body);
res.body.should.have.lengthOf(2)
done();
});
});
});
// -- 성공시
describe('2) 실패 시', () => {
it('limit이 숫자형이 아니면 400을 응답한다.', (done) => {
request(app)
.get('/users?limit=two')
.expect(400)
.end(done);
})
})
})
* limit가 없을 시 오류 발생
해결 -> limit가 없을 때 기본값 10으로 설정
// index.js에 추가
req.query.limit = req.query.limit || 10;
검증 성공 시
++ ) morgan 모듈 이용하여 주석 남기기
개발 의존성 모듈로 설치
npm install morgan --save-dev
스크립트 추가
const morgan = require('morgan');
app.use(morgan('dev'));
오랜만에 웹 플밍하니까 재밌는거 같기도하고..
얼른 익혀서 캡스톤 해야쥐
[캡스톤 일지] ~10.21 NodeJS TDD 웹개발 훑어보기(2) (0) | 2021.10.23 |
---|---|
[캡스톤 일지] ~10.16 robotjs 이용한 마우스 커서 이동 (0) | 2021.10.16 |
[캡스톤 일지] ~10.13 미디어파이프 이용한 정적제스처 인식과 문제 발생 (0) | 2021.10.14 |
[캡스톤 일지] ~10.04 생활코딩로 간단히 살펴본 Tensorflow.js (0) | 2021.10.05 |
[캡스톤 일지] ~09.24 서비스 기획과 미디어파이프 테스트 (0) | 2021.09.24 |
댓글 영역