Node.Js이란?
node.js는 서버측 자바스크립트 런타임 환경입니다 원래라면 자바스크립트는 웹 브라우저에서만 실행됐지만 NodeJS는 브라우저 밖에서 사용할 수 있습니다 자바스크립트 엔진인 V8엔진을 탑재해 실행 속도가 빠르다는 큰 장점이 있고 이벤트 기반, 비동기 I/O\ 모델을 사용해 가볍고 효율적입니다
런타임이란?
런타임은 Javascript로 만든 프로구램을 실행할 수 있는 프로그램입니다
자바스크립트의 런타임 환경은 과거 웹 브라우저에만 존재 했으나 자바스크립트를 서버단에서 사용하기 위해 나온 것이 바로 Node.js입니다 즉 자바스크립트 코드를 웹 브라우저 없이 실행할 수 있게되었습니다
REP 모드
Node.js는 파이썬과 마찬가지로 대화형 모드를 지원하여 간단한 자바스크립트 코드를 터미널에서 확인해볼 수 있습니다
Node.Js의 특징
자바스크립트를 사용하며 싱글 스레드입니다 여기서 싱글 쓰레드란? 사용자가 직접 제어할 수 있는 스레드는 하나라는 뜻으로 Call Stack이 하나라고 생각하면됩니다 싱글 스레드는 한번에 하나의 작업만 가능합니다 하지만 오래걸리는 작업이 있을 경우 Non-blocking I/O 기능을 이용하여 일부 코드를 다른 프로세스에 넘겨 실행가능합니다 다만 싱글 스레드 특성상 처리중 오류가 발생하면 그 즉시 멈추게됩니다 그렇기 때문에 예외처리가 굉장히 중요하다고 볼 수 있고 PC의 자원 (CPU, 메모리) 자원을 적게 사용하는 장점이 있습니다
callstack 란
프로그램에서 현재 실행중인 서브 루틴에 관한 정보를 저장하는 스택자료 구조입니다 기본적으로 스택은 후입선출을 기본으로 하는 자료구조입니다 후입선출이란? 마지막에 들어온 루틴을 먼저 처리한다는 뜻입니다 들어온 순서대로 처리하는게 아닌 역방향으로 처리합니다

자바스크립트에서 콜스택은 스레드가 1개뿐이기 때문에 단일 콜스택을 갖습니다 말 그대로 한번에 1개의 작업만 다룰 수 있는데 여기서 만약 에러가 발생했는데 예외처리를 안한다면 자바스크립트는 치명적인 에러를 출력하며 프로그램이 멈추게됩니다 그러므로 반드시 예외처리를 해줘야합니다 추가적으로 스택에는 무한대의 공간이 아니라 제한적인 공간으로 너무 많은 스택이 쌓이게 되면 스택오버플로우 에러가 발생할 수 있습니다
블록킹과 논블록킹
블로킹은 부여받은 I/O 작업이 끝나야지만 다음 작업을 수행합니다 그렇기 때문에 오래걸리는 작업을 할때 처리가 오래 걸리기 때문에 해당 작업이 끝날때까지 기다려야합니다
논 블로킹은 I/O 작업이 완료될때까지 기다리지않고 빨리완료된 순서로 처리합니다 그렇기 때문에 프로그램의 작업효율성이 더 뛰어납니다 하지만 데이터처리 과정에서 순서가 잘못되어 심각한 오류 또는 버그를 발생 시킬 수 있으므로 반드시 콜백을 통해 마무리를 해야 잘못된 흐름으로 코드가 실행되지않습니다
동기와 비동기
동기와 비동가는 블록킹과 논블록킹과 유사하지만 약간 다른 의미를 갖고있습니다 다른점은 블록킹은 I/O작업에 관한 처리방식이며 동기 비동기는 작업의 실행 완료를 어떻게 처리할지에 대한 처리방식을 뜻합니다
콜백(Callback)
Callback 함수는, 다른 함수의 매개변수로 함수를 전달하고, 어떠한 이벤트가 발생한 후 매개변수로 전달한 함수가 다시 호출되는 것을 의미합니다 callback의 방식은 다양한 방식이 존재하는데 pormise와 await 의 종류가 있는데 이렇게 다양한 방식이 나오게 된 이유는 콜백이 중첩되게 사용될 경우 흔히 들을 수 있는 콜백 지옥이 펼쳐지기 때문입니다 그래서 단점을 보완하기 위해 나오게 된 문법이 pormise와 await 입니다 하지만 pormise도 중첩이 될 경우 콜백과 유사하게 가독성이 떨어지게 되는 단점이 있고 그 단점을 보완하기 위해 await가 나오게 되었습니다

콜백은 우리의 일상에도 적용되어 이미 사용됐어요! 상황을 예시로 들자면
우리가 카페로 들어가서 직원에게 아이스 아메리카노 한잔 테이크아웃으로 주세요 (요청)
직원이 아이스 아메리카노가 다 만들어지면 호출벨로 알려드릴게요!(응답)
여기서 호출벨이 바로 콜백함수입니다 즉 작업이 완료되면 실행해주세요 라는 의미를 담고있는게 바로 콜백입니다
callback 문법
// 함수 정의: 작업을 수행하고 콜백 함수를 호출하는 함수
function doSomethingAsync(task, callback) {
console.log(`작업처리중: ${task}...`);
setTimeout(() => {
console.log(`${task} 작업완료`);
callback(); // 작업 완료 후 콜백 함수 호출
}, 1000); // 1초 후에 작업 완료
}
// 콜백 함수 정의
function onTaskComplete() {
console.log("요청한 작업이 완료되었습니다!");
}
// 함수 호출: 작업과 콜백 함수를 전달
doSomethingAsync("세탁", onTaskComplete);
doSomethingAsync함수로 세탁이라는 작업을 요청하고 작업이 끝나면 알 수 있도록 onTaskComplete 함수를 같이 보냈습니다 doSomethingAsync함수에서는 요청한 작업을 처리하고 작업이 끝나면 받은 작업이 완료 됐다고 띄우고 같이 받았던 onTaskComplete 함수를 실행시켜 요청한 작업이 최종적으로 완료됐다고 알려줍니다 약간 어려운 개념일 수 있으나 순서를 차근차근 따라가보면 이해하기가 편합니다
pormise 문법
// Promise를 사용하여 비동기 작업을 정의하는 함수
function doSomethingAsync(task) {
return new Promise((resolve, reject) => {
console.log(`작업중: ${task}...`);
setTimeout(() => {
const success = true; // 작업 성공 여부를 정의하는 변수 (true면 성공)
if (success) {
resolve(`${task} 작업 완료!`);
} else {
reject(`작업 실패... ${task}.`);
}
}, 1000); // 작업이 1초동안 이루어짐
});
}
// Promise 사용하기
doSomethingAsync("세탁")
.then((message) => {
// 작업이 성공적으로 완료되었을 때 호출되는 부분
console.log(message);
console.log("요청한 작업이 완료되었습니다!.");
})
.catch((error) => {
// 작업이 실패했을 때 호출되는 부분
console.error(error);
});
await 문법
// Promise를 사용하여 비동기 작업을 정의하는 함수
function doSomethingAsync(task) {
return new Promise((resolve, reject) => {
console.log(`작업중: ${task}...`);
setTimeout(() => {
const success = true; // 작업 성공 여부를 정의하는 변수 (true면 성공)
if (success) {
resolve(`${task} 완료!.`);
} else {
reject(`실패.. ${task}.`);
}
}, 1000); // 1초 후에 작업 완료
});
}
// async/await를 사용하여 비동기 작업을 처리하는 함수
async function performTask() {
try {
const message = await doSomethingAsync("Wash the dishes");
console.log(message);
console.log("요청한 작업이 완료되었습니다!");
} catch (error) {
console.error(error);
}
}
// 함수 호출
performTask();
이 비동기함수에서 콜백을 사용하는 방법이 조금씩 차이가 있지만 pormise의 구조만 잘 이해한다면 다른 방법은 쉽게 사용할 수 있습니다
Express
Express는 Node.js 위에서 실행되는 프레임워크이며 웹 서버나 API 서버를 쉽게 구축할 수 있도록 도와줍니다 Express는 http 내장 모듈보다 빠르고 유연하며, 다양한 기능을 쉽게 사용할 수 있게 해주기때문에 Node.js 로 서버를 개발할때는 보통 Express 모듈을 사용합니다
// Express를 가져옵니다.
const express = require('express');
const app = express();
const port = 3000;
// 기본 경로('/')에 대한 GET 요청 처리
app.get('/', (req, res) => {
res.send('Hello, Express!');
});
// '/about' 경로에 대한 GET 요청 처리
app.get('/about', (req, res) => {
res.send('About Page');
});
// 서버 실행
app.listen(port, () => {
console.log(`Server is running on http://localhost:${port}`);
});
const http = require('http');
const server = http.createServer((req, res) => {
if (req.url === '/' && req.method === 'GET') {
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end('<h1>Welcome to Home Page</h1>');
} else if (req.url === '/about' && req.method === 'GET') {
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end('<h1>About Page</h1>');
} else {
res.writeHead(404, { 'Content-Type': 'text/html' });
res.end('<h1>404 Not Found</h1>');
}
});
server.listen(3000, () => {
console.log(`Server is running on http://localhost:3000`);
});
위의 두 코드를 비교해보면 알 수 있듯 Express가 좀 더 간결하고 요청/응답처리를 짧고 쉽게 처리할 수 있는 장점이 있습니다
라우팅
라우팅은 클라이언트가 특정 경로로 요청을 보냈을때 어떤 처리를 할것인지? 를의미합니다
아래 코드에서 볼수있듯 get, post, put(업데이트), delete(삭제) 함수를 그 자체를 뜻합니다
// 홈 페이지 라우트
app.get('/', (req, res) => {
res.send('Welcome to the homepage!');
});
// 사용자 목록 조회 라우트
app.get('/users', (req, res) => {
res.send('User list');
});
// 특정 사용자 정보 조회 라우트
app.get('/users/:userId', (req, res) => {
res.send(`User details for user ${req.params.userId}`);
});
// 사용자 생성 라우트
app.post('/users', (req, res) => {
res.send('User created');
});
미들웨어
app.use()는 서버와 클라이언트를 이어주는 중간 작업이며 요청(req), 응답(res), 그리고 그 요청과 응답 사이의 작업을 처리하는 역할을 하는 함수입니다 아래의 코드에선 /static 으로 요청 시 public 폴더 안에 있는 모든 파일을 /static 으로 접근 할 수있도록 처리를 해주는 코드입니다
이미지, CSS 파일 및 JS 파일과 같은 정적 파일을 제공하기 위한 설정
app.use('/static', express.static(__dirname ++ '/public'));
폼간 데이터 전송
<!-- 프론트단 -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>GET Form Example</title>
</head>
<body>
<h2>GET 방식으로 폼 전송</h2>
<form action="/search" method="get">
<label for="query">Search: </label>
<input type="text" id="query" name="query">
<button type="submit">Submit</button>
</form>
</body>
</html>
<!-- 백엔드단 -->
const express = require('express');
const app = express();
app.get('/search', (req, res) => {
const query = req.query.query; // 쿼리 파라미터에서 검색어 추출
res.send(`You searched for: ${query}`);
});
app.listen(3000, () => {
console.log('Server is running on http://localhost:3000');
});
여기서 중요한 점은 프론트의 액션을 서버상의 요청경로로 줘야하는것 그리고 get 방식은 url의 query로 들어오기 때문에 서버단에서 query로 접근할 수 있다는것입니다
<!-- 프론트 단 -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>POST Form Example</title>
</head>
<body>
<h2>POST 방식으로 폼 전송</h2>
<form action="/submit" method="post">
<label for="username">Username: </label>
<input type="text" id="username" name="username">
<br>
<label for="password">Password: </label>
<input type="password" id="password" name="password">
<br>
<button type="submit">Submit</button>
</form>
</body>
</html>
<!-- 백엔드단 -->
const express = require('express');
const app = express();
// JSON 및 URL-encoded 본문 데이터를 파싱하기 위한 미들웨어
app.use(express.urlencoded({ extended: true }));
app.use(express.json());
app.post('/submit', (req, res) => {
const username = req.body.username; // 요청 본문에서 데이터 추출
const password = req.body.password;
res.send(`Received username: ${username}, password: ${password}`);
});
app.listen(3000, () => {
console.log('Server is running on http://localhost:3000');
});
반대로 post는 url이 아닌 html의 body로 들어오기때문에 서버단에서 body로 접근해야만 데이터를 받을 수 있습니다
express.urlencoded() 는 URL데이터를 파싱하는 미들웨어로 post 방식에서 본문으로 들어오는 데이터를 해석하기 위해 사용됩니다 해석 후 req,body 객체에 데이터가 할당되며 app.use(express.json())는 JSON 데이터를 파싱하는 미들웨어입니다 클라이언트가 JSON형식으로 데이터를 서버에 전송했을때 해당 JSON 데이터를 javascript 객체로 변환하여 req.body에 할당하기위해 사용됩니다
'SAC' 카테고리의 다른 글
[새싹x코딩온] 풀스택 개발자 부트캠프 과정 5주차-2 회고 | MySQL, MVC 패턴 (1) | 2024.12.01 |
---|---|
[새싹x코딩온] 풀스택 개발자 부트캠프 과정 5주차-1 회고 | 동적 폼 처리, nodejs multer (2) | 2024.11.25 |
[새싹x코딩온] 풀스택 개발자 부트캠프 과정 4주차-1 회고 | Server (0) | 2024.11.15 |
[새싹x코딩온] 풀스택 개발자 부트캠프 과정 3주차-1 회고 | 반응형, Bootstrap (0) | 2024.11.13 |
[새싹x코딩온] 풀스택 개발자 부트캠프 과정 3주차-2 회고 | JavaScript (0) | 2024.11.11 |