개발/Node
# [node] 익스프레스 프레임워크를 사용하여 간단한 서버 실행 해보자.
ForrestPark
2025. 1. 10. 15:20
ℹ️ 참고
1.🌐
1.📚 도서,Node.js백엔드 개발자 되기
3.6 익스프레스 프레임워크 사용하기
익스프레스 프레임워크
기능 | 설명 |
---|---|
라우팅 | URL 요청을 함수와 매핑 |
정적 파일 서비스 | CSS, js, 이미지등 정적 파일 다루는 기능 |
템플릿 엔진 | 동적인 웹페이지를 html 인스턴스를 사용해 생성 |
요청 데이터 핸들링 | http 요청을 추상화해 편리하게 다루는 기능 |
응답 데이터 핸들링 | http 응답을 커스터마이징 할수 있는기능, 파일다운, 이미지 출력 |
파일 업로드 | http로 전송된 파일을 읽고 다룰수 있는 기능 |
쿠키 및 세션 지원 | 클라이언트 측 혹은 서버측 메모리에 일정 기간 동안 저장해야하는 데이터를 다루는 기능 |
리다이렉트 | 서버의 응답시 다른 페이지로 전달 시키는 기능 |
에러 페이지 | 요청이 잘못되었거나 서버 에러시 특정 에러페이지를 보여줌 |
미들웨어 | 요청 혹은 응답 사이에 공통된 기능 추가 |
3.6.1 익스프레스 설치
(1) Terminal npm(node package manager) 수행
mkdir chapter3
cd chapter3
mkdir express-server
cd express-server
npm install express
(2) express folder file 확인
ls > node_modules package.json, package-loc.json 파일이 존재 확인
cd node_module
npm ls ##의존성 패키지 정보 확인
3.6.3 첫 익스프레스 서버 만들기
(1) Express module import 및 app 객체 생성
const express = require("express");// express 모듈 불러오기
const app = express(); // express 를 초기화 후 app 에 할당
const port = 80;
});
(2) GET method 요청시 응답 작성
app.get("/", (req,res) => {
res.set({ "Content-Type": "text/html; charset=utf-8"});
res.end("헬로 express");
});
(3) Server listen (구축)
app.listen(port, () =>{
console.log(`START SERVER : use ${port} http://forrestest.site`);
라우터 리펙터링
url path 별로 들어오는 요청에 응답을 매핑 해본다.
(1) url, express import, server listen
const url = require("url");
const express = require("express");
const app = express();
const port = 80;
app.listen(port, () => {
console.log(" 익스프레스로 라우터 리펙터링하기 ");
});
(2) GET method path 별 함수 사용
// Get method routing setting
app.get("/", (_,res) => res.end("Home"));
app.get("/user", user);
app.get("/feed", feed);
(3) 앞에 사용한 함수(user, feed) 정의 입력
function user(req,res){
const user = url.parse(req.url, true).query;
// 결과값으로 유저명과 나이 제공
res.json(`[user] name : ${user.name}, age: ${user.age}`);
}
function feed(_, res){
res.json(`<ul>
<li>picture1</li>
<li>picture2</li>
<li>picture3</li>
<li>picture4</li>
</ul>`)
}
3.7 간단한 API server 만들기
DB 없이 메모리 기반으로 동작하는 휘발성 게시판을 만들어 보자
3.7.1 게시판 API 코드 작성
REST API 원칙 : 자원을 URL 에 표현하고 자원을 가져오는 행위 HTTP 메서드로 표현
경로 | HTTP 메서드 | 설명 |
---|---|---|
/ | get | 게시판 목록을 가져옴 |
/post | post | 게시판 글 생성, id,title,name,text,createdDt |
posts/:id | delete | 글 삭제 |
3.7.2 API 규칙에 맞게 서버 구현
(1) import, posts(개시글목록) 초기화
const express = require("express")
const app = express();
let posts = [];// 게시글 리스트로 사용할 posts 에 빈 리스트 할당
posts 는 게시글을 의미. 게시판 리스트로 할당. 글삭제시 삭제된 목록으로 다시 재할당 -> const 가 아닌 let으로 한다.
(2) json 미들웨어 활성화
// req.body 를 사용하려면 JSON 미들 웨어 사용
// 사용하지 않으면 undefined 로 변환
app.use(express.json()); // JSON 미들웨어 활성화
express.json() 미들웨어 활성화 , app.use(): 미들웨어 사용할때 사용하는 함수.
(3) "/" post 요청시 게시글(posts)을 json 으로 파싱하여 응답.
// Post 요청시 컨텐트 타입이 application/x-www-form-urlencoded 인 경우 파싱
app.use(express.urlencoded({ extended: true})); // json 미들 웨어와 함께 사용
app.get("/", (req,res) => {// /로 요청이 오면 실행
res.json(posts); // 게시글 리스트를 json 형식으로 보여줌
})
- application/x-www-form-urlencoded: body 에 키&값&키2=값2 같은 키=값 조합 형태를 가진 데이터
- post 요청은 대부분이 application/x-www-form-urlencoded 타입임.
- 주로 express json 과 함께 사용
- res.end() 인수는 문자열과 바이트 버퍼 만 입력 가능. list data 전달시 res.end() 사용불가.
- res.json()은 리스트와 json 을 응답 처리 할수 있음
(4) "/post" 글 포스팅 요청시 posts 리스트 에 게시글 정보 추가
app.post("/post", (req,res) => { // /post 로 요청이 오면 콜백 함수 실행
const {title, name, text } = req.body; // http 요청이 body 데이터를 변수에 할당
console.log(req.body)
// 게시글 리스트에 새로운 게시글 정보 추가
posts.push({ id: posts.length +1 , title,name, text, createDt : Data()})
res.json({title,name,text});
})
- 요청의 body 에 남겨진 title, name, text 값을 title, name, text 변수로 각각 할당.
- 객체 타입은 비구조화 할당(destructuring assignment) 이 가능, body의 여러 요소를 여러변수에 한번에 할당 가능.
- post 요청이므로 req.body 에 키와 값이 들어가 있음.
- application/x-www-form-urlencoded 타입 데이터를 urlencoded 미들웨어가 객체로 변겨애서 req.body 에 추가.
(5) "/posts/:id" 요청시 글 삭제
app.delete("/posts/:id", (req,res) => {
const id = req.params.id; // app.delete에 설정한 path 정보에서 id 값을 가져옴
const filteredPosts = posts.filter((post) => post.id !== +id);// 글 삭제 로직
const isLengthChanged = post.length !== filteredPosts.length; // 삭제 확인
posts = filteredPosts;
if (isLengthChanged){ // posts의 데이터 개수가 변경되었으면 삭제 성공
res.json("OK");
return;
}
res.json("NOT CHANGED")// 변경되지 않음.
})
- 게시판 글에서 id 이외의 글들만 뽑아 filteredPosts 에 다시 할당.
- 삭제시 slice(),filter(), map(), reduce() 등 배열에서 특정 인덱스 삭제를 위한 함수 있음.
- 데이터 개수가 삭제 되었는 지 확인하고 삭제 되었으면 return 을 통해 call back 을 빠져나옴.( 빠른반환 기법 , early return)
(6) Server 실행
app.listen(80, ()=> { console.log("welcome posts START!"); });
전체코드
const express = require("express")
const app = express();
let posts = [];// 게시글 리스트로 사용할 posts 에 빈 리스트 할당
// req.body 를 사용하려면 JSON 미들 웨어 사용
// 사용하지 않으면 undefined 로 변환
app.use(express.json()); // JSON 미들웨어 활성화
// Post 요청시 컨텐트 타입이 application/x-www-form-urlencoded 인 경우 파싱
app.use(express.urlencoded({ extended: true}));
app.get("/", (req,res) => {// /로 요청이 오면 실행
res.json(posts); // 게시글 리스트를 json 형식으로 보여줌
})
app.post("/post", (req,res) => { // /post 로 요청이 오면 실행
const {title, name, text } = req.body; // http 요청이 body 데이터를 변수에 할당
// 게시글 리스트에 새로운 게시글 정보 추가
posts.push({ id: posts.length +1 , title,name, text, createDt : Date()})
res.json({title,name,text});
})
app.delete("/posts/:id", (req,res) => {
const id = req.params.id; // app.delete에 설정한 path 정보에서 id 값을 가져옴
const filteredPosts = posts.filter((post) => post.id !== +id);// 글 삭제 로직
const isLengthChanged = posts.length !== filteredPosts.length; // 삭제 확인
posts = filteredPosts;
if (isLengthChanged){ // posts의 데이터 개수가 변경되었으면 삭제 성공
res.json("OK");
return;
}
res.json("NOT CHANGED")// 변경되지 않음.
})
app.listen(80, ()=> {
console.log("welcome posts START!\n http://forrestest.site");
});
3.8 게시판 api 테스트
💁♂️curl 옵션
옵션 | 설명 | 예시 |
---|---|---|
-X | **http 메서드 정보 | curl -X POST http://forrestest.site** |
-d | POST 통신시 body 데이터 | curl -d "key=1value1@key2=value2" localhost:80 |
-H | 헤더 정보 | curl -H |
-x | 프록시 서버 설정 | curl -x http://forrestest.site:proxy_port -- proxy-user username:password |
-T | 파일을 서버에 전송 시 사용 | curl -T file.txt http://forrestest.site |
-A | 유저 에이전트 변경 | curl -A "Mozilla/5.0" http://forrestest.site |
-i | 서버의 응답을 결과로 출력 | curl -i https://forrestest.site |
-l | 서버 응답에서 헤더 값만 출력 | curl -l http://server.com/test.txt |
-O | 서버의 파일을 이름변경없이 내려받기 | curl -O http://server.com/test.txt |
-L | 리다이렉트 url 따라가기 | curl -L http://server.com/redirectingURL |
-s | 에러가 발생해도 출력 안함 | curl -s localhost:80 |
-S | 에러 발생시 에러 출력 | curl -S localhost:80 |
3.8.2 curl 로 post 호출해 게시글 등록하기
💁♂️ curl test 시 헤더에 Content-Type: application/x-www-form-urlencoded 정보도 필요함
curl -X POST "Content-Type: application/x-www-form-urlencoded" -d "title=제목1&name=forre&text=안녕하세요~" http://forrestest.site/post
3.8.3 curl 로 delete 를 호출해 게시글 삭제하기
# curl -X POST "Content-Type: application/x-www-form-urlencoded" -d "title=제목1&name=포레&text=안녕하세요~" http://forrestest.site/post
# curl -X POST "Content-Type: application/x-www-form-urlencoded" -d "title=제목1&name=대표&text=일똑바로 합시다!😤" http://forrestest.site/post
# curl -X POST "Content-Type: application/x-www-form-urlencoded" -d "title=제목1&name=김민x&text=네!😤" http://forrestest.site/post
# curl -X POST "Content-Type: application/x-www-form-urlencoded" -d "title=제목1&name=포게&text=무서워..." http://forrestest.site/post
curl -X DELETE http://forrestest.site/posts/3