개발/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

power shell curl post 결과

browser 에서 get 으로 들어가면 post 출력됨

chrome 에 json viewr 익스텐션 설치한뒤에 test stie 접속

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