Java Script(9)- Buffer, Stream, Npm, Rest, Express 프레임워크
*이 글을 읽기전에 작성자 개인의견이 있으니, 다른 블로그와 교차로 읽는것을 권장합니다.*
1. 버퍼(buffer)
버퍼는 컴퓨팅과 통신 시스템에서 사용되는 중요한 개념으로, 데이터를 한 곳에서 다른 곳으로 전송하는 동안 일시적으로 데이터를 저장하는 임시 저장 영역을 말합니다. 오버런(과다한 데이터 흐름)이나 언더런(부족한 데이터 흐름)을 방지하고 시스템의 다양한 구성 요소 간에 원활한 통신을 보장합니다.
- 메모리에 저장되는 일부 공간
- 바이트 단위로 저장되며 integar 형태의 배열
const buf = Buffer.from('Hi');
console.log(buf);
console.log(buf.length);
console.log(buf[0]);
console.log(buf[1]);
console.log(buf.toString());
const buf2 = Buffer.alloc(2);
buf2[0] = 72;
buf2[1] = 105;
console.log(buf2.toString());
1-1. alloc():
'Buffer.alloc(size)' 메서드는 지정된 크기의 새로운 버퍼를 만들고 초기화합니다. 이때 초기화는 버퍼의 내용을 모두 0으로 채우는 것입니다.
// node.js를 메모리 버퍼에 문자열 사이즈만큼 메모리를 할당하고 문자를 저장
const buf3 = Buffer.alloc(6);
buf3[0]=110;
buf3[1]=111;
buf3[2]=100;
buf3[3]=101;
buf3[4]=106;
buf3[5]=115;
console.log(buf3.toString());
2. 스트림(Stream)
스트림(Stream)은 데이터를 읽고 쓰는 데 사용되는 추상적인 개념입니다. 이는 데이터를 작은 단위로 나누어 전송하거나 처리할 때 특히 유용합니다. 스트림은 대용량 데이터를 메모리에 한 번에 로드하지 않고, 조각조각 나누어 처리할 수 있도록 해줍니다. 이는 메모리 효율성과 성능을 향상시킵니다.
스트림은 보통 다음과 같은 세 가지 타입으로 나뉩니다:
- Readable Stream (읽기 가능한 스트림): 데이터를 읽을 수 있는 스트림입니다. 파일에서 데이터를 읽거나 네트워크에서 데이터를 가져올 때 사용됩니다.
- Writable Stream (쓰기 가능한 스트림): 데이터를 쓸 수 있는 스트림입니다. 파일에 데이터를 쓰거나 네트워크로 데이터를 보낼 때 사용됩니다.
- Duplex/Transform Stream (양방향/변환 스트림): 읽기와 쓰기 모두 가능한 스트림입니다. 또는 데이터를 읽어서 변환한 후 다시 쓸 수 있는 스트림입니다.
const fs = require('fs');
const beforeMem = process.memoryUsage().rss;
console.log(beforeMem);
fs.readFile('./test.txt',(_,data) => {
fs.writeFile('./file.txt', data, () => {
console.log('파일 저장 완료!');
});
const afterMem = process.memoryUsage().rss;
const diff = afterMem - beforeMem;
const result = diff / 1024 / 1024;
console.log(diff);
console.log(`메모리 사용: ${result} MB`);
});
/* test.txt*/
hello hello hello
2-1. pipe() :
Node.js에서 스트림을 다른 스트림으로 연결하는 메서드입니다. 이를 사용하면 데이터를 한 스트림에서 다른 스트림으로 전달할 수 있습니다. 데이터를 효율적으로 처리하고 복사하지 않고도 한 스트림에서 다른 스트림으로 데이터를 전달할 수 있습니다.
const fs = require('fs');
const zlib = require('zlib');
const readStream = fs.createReadStream('file.txt');
const zlibStream = zlib.createGzip();
const writeStream = fs.createWriteStream('./file2.txt.gz');
const piping = readStream.pipe(zlibStream).pipe(writeStream);
piping.on('finish', () => {
console.log('끝!');
});
3. HTTP 모듈
Node.js의 http 모듈은 HTTP 서버 및 클라이언트를 생성하는 데 사용됩니다. 이 모듈을 사용하면 Node.js 애플리케이션에서 웹 서버를 만들고 웹 요청을 처리할 수 있습니다. 또한 다른 서버로의 HTTP 요청을 보낼 수도 있습니다.
- 웹 서버와 클라이언트를 만들고 관리하는데 사용되는 핵심 모듈
- HTTP 서버를 만들거나 HTTP 클라이언트 요청을 만들 수 있습니다.
const http = require('http');
const fs = require('fs');
const server = http.createServer((req, res) => {
console.log('서버가 동작중입니다');
console.log(req.headers);
console.log(req.headers);
console.log(req.method);
const url = req.url;
res.setHeader('Content-Type', 'text/html');
if(url === '/'){
fs.createReadStream('./page/index.html').pipe(res);
console.log('index.html');
}else if(url === '/news'){
fs.createReadStream('./page/news.html').pipe(res);
console.log('news.html')
}else{
fs.createReadStream('./page/not-found.html').pipe(res);
console.log('not-found.html')
}
});
// localhost: 8080
// 서버포트 8080
server.listen(8080);
4. npm
npm(Node Package Manager)은 JavaScript 패키지를 관리하고 배포하는 도구입니다. 주로 Node.js 애플리케이션에서 사용되며, 프로젝트에 필요한 패키지를 설치하고 관리할 때 주로 활용됩.
- 패키지 관리: npm을 사용하여 프로젝트에 필요한 패키지를 설치하고 관리할 수 있습니다. npm install 명령을 사용하여 패키지를 설치하고, npm uninstall 명령을 사용하여 패키지를 제거할 수 있습니다.
- 의존성 해결: 패키지를 설치할 때 npm은 해당 패키지가 의존하는 다른 패키지들도 함께 설치하고 관리합니다. 이를 통해 프로젝트의 의존성을 쉽게 관리할 수 있습니다.
- 버전 관리: npm은 패키지의 버전을 관리하고 업데이트할 수 있습니다. npm update 명령을 사용하여 모든 패키지를 최신 버전으로 업데이트하거나, 특정 패키지를 업데이트할 수 있습니다.
- 스크립트 실행: package.json 파일에 정의된 스크립트를 실행할 수 있습니다. 예를 들어, npm start 명령을 사용하여 프로젝트를 시작하거나, npm test 명령을 사용하여 테스트를 실행할 수 있습니다.
- 프로젝트 초기화: npm init 명령을 사용하여 새로운 프로젝트를 초기화할 수 있습니다. 이 명령은 프로젝트의 기본 구성을 설정하고 package.json 파일을 생성합니다.
- package.json 기본값으로 생성하기: npm init -y
- 라이브러리 설치: npm install 패키지명, npm i 패키지명
- nodemon 설치: npm i nodemon --save-dev
5.템플릿 엔진
템플릿 엔진(Template Engine)은 웹 애플리케이션에서 동적인 HTML을 생성하기 위해 사용되는 도구나 프레임워크입니다. 템플릿 엔진은 정적인 HTML과 동적인 데이터를 조합하여 클라이언트에게 동적으로 생성된 컨텐츠를 제공할 수 있습니다.
- HTML 페이지 내에서 데이터를 동적으로 삽입하고 조작하는 데 도움이 되며, 주로 웹 어플리케이션에서 뷰 부분을 생성하는데 활용합니다.
- Handlebars: 미니멀한 문법을 가지고 있고, 자바스크립트 객체와 매우 유사한 문법을 사용합니다.
- EJS (Embedded JavaScript): JavaScript 코드를 HTML에 직접 삽입할 수 있는 템플릿 엔진입니다.
- Pug (이전에는 Jade): 간결하고 가독성이 좋은 문법을 가지고 있으며, HTML을 생성하기 위해 들여쓰기를 사용합니다.
- ejs 공식 홈페이지(https://ejs.co/)
// npm i ejs입력
const http = require('http');
const fs = require('fs');
const ejs = require('ejs');
const name = '김사과';
const userid = 'apple';
const jobs = [
{job: '학생'},
{job: '개발자'},
{job: '교사'},
{job: '공무원'},
{job: '취준생'}
];
const server = http.createServer((req, res) => {
const url = req.url;
res.setHeader('Content-Type', 'text/html');
if(url == '/'){
ejs.renderFile('./templete/index.ejs', {name:name}).then((data) => res.end(data));
}else if(url === '/news'){
ejs.renderFile('./templete/news.ejs', {jobs:jobs}).then((data) => res.end(data));
}else{
ejs.renderFile('./templete/not-found.ejs', {userid:userid, name:name}).then((data) => res.end(data));
}
});
server.listen(8080);
문제
/ index와 /news 외의 모든 페이지를 not-found.ejs로 만들어 출력하기
단, not-found.ejs에 전달할 매개변수는 userid는 'apple', name은 '김사과'로 함
출력예시
apple(김사과)님이 요청하신 페이지가 없어요! 😎😎😎
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Not Found</title>
</head>
<body>
<h2>Not Found</h2>
<p><%=userid%>(<%=name%>)페이지가 없어요!😎😎😎</p>
</body>
</html>
6. REST(Representational State Transfer)
REST(Representational State Transfer)는 분산 하이퍼미디어 시스템을 위한 아키텍처 스타일 중 하나입니다. REST는 클라이언트와 서버 간의 통신을 위한 표준화된 방법을 정의하고, 자원을 표현하고 상태를 전송하기 위한 규칙을 제공합니다.
REST는 HTTP를 기반으로 하여, HTTP 메서드(GET, POST, PUT, DELETE 등)를 사용하여 자원에 대한 행위를 표현합니다. 이를 통해 클라이언트와 서버 간의 통신을 간단하게 만들고, 자원의 상태를 표현하고 전달할 수 있습니다.
REST의 주요 특징은 다음과 같습니다:
- 자원(Resource): 모든 것을 자원으로 간주하고, 각 자원에는 고유한 식별자(URI)가 있습니다. 자원은 서버에 존재하며 클라이언트가 요청할 수 있는 대상입니다.
- 표현(Representation): 자원은 여러 표현으로 표현될 수 있습니다. 예를 들어, JSON, XML, HTML 등 다양한 형식으로 표현될 수 있습니다. 클라이언트는 자원의 표현을 요청할 수 있습니다.
- 상태(State): 클라이언트와 서버 간의 통신은 상태를 전송하지 않습니다. 모든 상태 정보는 클라이언트에 저장되어야 합니다. 클라이언트가 요청을 보낼 때 필요한 모든 정보를 요청에 포함해야 합니다.
- 통일된 인터페이스(Uniform Interface): REST는 통일된 인터페이스를 제공하여 서비스의 구성요소 간의 상호작용을 단순화합니다. 이를 통해 시스템을 더욱 확장 가능하고 유연하게 만듭니다.
- 무상태(Stateless): 서버는 각 요청을 개별적으로 처리하고, 클라이언트의 상태를 저장하지 않습니다. 이는 서버의 확장성을 향상시키고, 서비스의 중복성을 줄여줍니다.
REST API: REST 기반으로 서비스 API를 구현한 것
API(Application Programming Interface):
기능의 집합을 제공해서 컴퓨터 프로그램간의 상호작용을 하도록 하는 것입니다.
const http = require('http');
const skills = [
{name:'Python'},
{name:'MySQL'},
{name:'HTML'},
{name:'CSS'},
{name:'JavaScript'}
]
const server = http.createServer((req, res) => {
const url = req.url;
const method = req.method;
if(method === 'GET'){
// 2XX: 정상적인 호출, 4XX: 페이지 없음, 5XX: 서버 오류
res.writeHead(200, {'Content-Type':'application/json'});
res.end(JSON.stringify(skills));
}
});
server.listen(8080);
7. Express 웹 프레임워크
Express는 Node.js를 위한 강력한 웹 프레임워크로, 웹 애플리케이션 및 API를 쉽게 개발할 수 있도록 도와줍니다. Express는 미들웨어를 기반으로 한 간결하고 유연한 구조를 가지고 있으며, 높은 수준의 라우팅 및 요청/응답 처리 기능을 제공합니다. Express는 JavaScript로 작성되어 있으며, 노드 생태계에서 가장 인기 있는 웹 프레임워크 중 하나입니다. 간결하고 유연한 구조를 가지고 있어서 작은 프로젝트부터 큰 애플리케이션까지 다양한 용도로 사용됩니다. Express를 사용하면 개발 생산성을 향상시키고 빠르게 웹 애플리케이션을 개발할 수 있습니다.
Express의 주요 특징은 다음과 같습니다:
- 미들웨어(Middleware): Express는 미들웨어를 사용하여 요청 처리를 구성합니다. 미들웨어는 요청과 응답 객체를 수정하거나 라우팅 및 오류 처리 등의 기능을 추가할 수 있습니다. 또한, 서드파티 미들웨어를 사용하여 기능을 확장할 수 있습니다.
- 라우팅(Routing): Express는 HTTP 요청 메서드(GET, POST, PUT, DELETE 등)에 따라 요청을 처리할 수 있습니다. 라우터를 사용하여 특정 URL 패턴에 대한 요청을 처리하고, 동적 라우팅 및 매개변수 전달 등을 지원합니다.
- 템플릿 엔진 지원: Express는 다양한 템플릿 엔진을 지원하여 HTML을 동적으로 생성할 수 있습니다. 대표적으로는 Pug, EJS 등이 있습니다.
- 정적 파일 서비스: Express는 정적 파일(이미지, CSS, JavaScript 등)을 제공하기 위한 내장 미들웨어를 제공합니다. 이를 통해 정적 자산을 쉽게 제공할 수 있습니다.
- RESTful API 지원: Express를 사용하여 RESTful API를 쉽게 개발할 수 있습니다. HTTP 요청 메서드와 URL을 사용하여 자원을 표현하고, JSON 형식으로 데이터를 반환할 수 있습니다.
- 세션 및 인증 관리: Express는 세션 및 인증을 위한 미들웨어를 제공하여 사용자의 상태를 유지하고 인증을 구현할 수 있습니다.
라우팅 요청메서드: CRUD Operation
Post: 생성(create)
GET: 조회(read)
PUT: 수정(update)
DELETE: 삭제(delete)
발동 명령어:
- npm i Express
import express from 'express';
// 객체 생성
const app = express();
// 미들웨어
// next: 다음 미들웨어를 호출
app.use((req, res, next) => {
res.setHeader('node-skill', 'node.js!');
next();
})
app.get('/', (req, res) =>{
res.send('<h2>익스프레스 서버로 만든 첫번째 페이지</h2>');
});
app.get('/hello', (req, res) => {
res.setHeader('Content-Type', 'application/json');
res.status(200).json({userid: 'apple', name:'김사과', age:20});
})
app.use((req,res) => {
res.send('<h2>페이지를 찾을 수 없습니다.</h2>');
})
// 서버 실행
app.listen(8080);
app.listen()은 Express 애플리케이션을 특정 포트에서 실행하도록 하는 메서드입니다. 이 메서드는 클라이언트의 HTTP 요청을 수신하고 해당 요청에 대한 응답을 제공하는 서버를 만듭니다. 따라서 app.listen(8080)은 port가 8080에서 실행함을 의미합니다.
import express from 'express';
import bodyParser from 'body-parser';
// npm i body-parser
const app = express();
app.use(bodyParser.urlencoded({exteneded: true}));
app.get('/', (req, res) => {
res.send('<h2>로그인</h2><form action="/login" method="post"><p>아이디: <input type="text" name="userid" id="userid"></p><p>비밀번호: <input type="password" name="userpw" id="userpw"></p><p><button type="submit">로그인</button></p></form>');
});
//localhost:8080/posts
// localhost:8080/posts?id=1, query는 ?뒤에 찍힘
// localhost:8080/posts?id=1&userid=apple&name=김사과
app.get('/posts', (req,res)=>{
console.log('posts 호출');
console.log('path: ', req.path);
console.log('query: ', req.query);
res.sendStatus(200);
});
// localhost:8080/posts/1
// localhost:8080/posts/1?id=1
app.get('/posts/:id', (req,res)=>{
console.log('posts/:id 호출');
console.log('path: ', req.path);
console.log('query: ', req.query);
console.log('query: ', req.params);
res.sendStatus(200);
});
// localhost:8080/mypage
// localhost:8080/myroom
app.get(['/mypage', '/myroom'], (req,res)=>{
console.log('path: ', req.path);
res.send(`<h2> ${req.path} 페이지! </h2>`);
});
//localhost:8080/member/:10
// { userid: 10 }
app.get('/:userid', (req,res)=>{
console.log(req.path, '호출');
console.log(`${req.params.userid}번 멤버가 출력됨!`);
res.sendStatus(200);
});
app.listen(8080);
8. Postman
Postman은 API 개발 및 테스트를 위한 인기있는 협업 플랫폼입니다. 개발자는 Postman을 사용하여 API 요청을 만들고, 테스트하고, 문서화하며, 공유할 수 있습니다. API 개발 및 테스트를 위한 강력한 도구로서, 다양한 기능과 사용자 친화적인 인터페이스를 제공하여 개발자들이 API를 효율적으로 관리하고 테스트할 수 있도록 돕습니다.
주요 기능은 다음과 같습니다:
- API 요청 생성: Postman을 사용하여 다양한 HTTP 요청(GET, POST, PUT, DELETE 등)을 만들고 테스트할 수 있습니다. 요청의 헤더, 바디, 파라미터 등을 쉽게 구성할 수 있습니다.
- 테스트 환경 설정: Postman을 사용하여 API 요청에 대한 테스트를 작성하고 실행할 수 있습니다. 예를 들어, 응답을 검증하고 특정 조건에 따라 테스트를 수행할 수 있습니다.
- 환경 변수 및 컬렉션: Postman은 환경 변수와 컬렉션을 사용하여 API 요청을 구성하고 관리할 수 있습니다. 환경 변수를 사용하여 동일한 요청을 다른 환경에 쉽게 적용할 수 있으며, 컬렉션을 사용하여 API 요청을 구조화하고 관리할 수 있습니다.
- 문서화: Postman은 API 요청과 응답을 문서화하고 공유할 수 있는 기능을 제공합니다. API 요청을 자세히 설명하고 예제를 제공하여 다른 사용자들이 API를 쉽게 사용할 수 있도록 돕습니다.
- 협업: Postman은 팀원들과 API를 협업하고 공유할 수 있는 플랫폼을 제공합니다. API 요청과 테스트를 공유하고 다른 사용자와 협업하여 API를 개발하고 테스트할 수 있습니다.
기존 콘솔화면이 아닌 postman으로 테스트합니다.
// http://localhost:8080/login?userid=apple&userpw=1111
app.get('/login', (req,res)=>{
console.log('login 호출!');
console.log('path: ', req.path);
console.log('query: ', req.query);
res.sendStatus(200);
});
app.post('/login', (req,res) =>{
console.log('/login 호출!');
console.log(req.body);
res.status(200).send('로그인 되었습니다!');
});
app.listen(8080);