본문 바로가기
Dev/Nodejs-express

[Node.js] express 모듈 사용하기

by Ellen571 2024. 9. 10.
반응형

express?

웹 서버에서 요청하고 전달 받는 리소스 등을 간결하고 가독성이 쉽게 구현하기 위해 사용되는 모듈이다.

  • 직관적인 API를 제공하여 코드를 이해하기 쉽게 만든다.
  • 적은 코드량(Less Code): 복잡한 웹 기능을 간단한 메서드로 구현할 수 있다.
  • 미들웨어(Middleware): 요청 처리 과정에 여러 기능을 쉽게 추가할 수 있는 미들웨어를 제공한다.
  • 라우팅(Routing): URL 경로에 따라 다른 처리를 하는 기능으로, RESTful API 구현이 용이하다.
  • 템플릿 엔진 지원: 동적 HTML 페이지 생성을 위한 다양한 템플릿 엔진을 지원한다.

 

express 사용하기

const express = require('express');
const app = express();
  • express 프레임워크에는 createApplication() 이라는 함수가 있다.
  • 이 함수를 실행해야 하나의 웹서비스가 마련되고 그것을 이라 부른다.
  • express()는 바로 createApplication() 함수를 시작하는 명령이다.
  • 생성된 웹서비스를 반환해 app 이라는 상수에 대입해 사용한다.
  • 왜 두 번의 과정을 거치도록 했을까?
    • Node.js 에서는 하나의 서비스로 2개 이상 앱을 동시 작동하는 것도 가능하기 때문이다.
const express=require('express');
 
const app=express();
app.use(express.static('public'));
app.listen(8080, function() {});
 
const app2=express();
app2.use(express.static('public2'));
app2.listen(8081, function() {});

 

 

express 미들웨어 함수

    • 요청(request)과 응답(response) 사이에 위치하여 다양한 기능을 수행하는 함수들을 말한다.

 

일반적으로 미들웨어 함수를 적용할 때

app.use()를 사용하고,

라우터Http Method(get(), post() 등)를 사용한다.

 

 

express 공식 홈페이지에 미들웨어를 다음과 같이 소개한다.

 

express 미들웨어

https://expressjs.com/ko/guide/writing-middleware.html

 

Express - Node.js web application framework

 

expressjs.com

 

 

 

app.use()

Express 앱에서 항상 실행하는 역할을 한다.

get(), post()등과 달리 요청 URL을 지정하지 않아도 되며, URL에 상관없이 매번 실행된다. 

 

app.use(cors())

app.use(cors());
  • 모든 도메인에서 제한 없이 해당 서버에 요청을 보내고 응답을 받을 수 있다.
const options = {
  origin: "https://naver.com", //접근 권한을 부여할 도메인
  credentials: true, //응답 헤더에 Access-Control-Allow-Credentials를 추가
  optionSuceessStatus: 200, //응답 상태를 결정
};
app.use(cors(options));
  • 특정 도메인에서 서버에 요청르 보내고 응답을 받을 수 있다.

 

app.use(express.json())

app.use(express.json());
  • JSON 형태의 요청 body를 파싱(parse)하기 위해 사용한다.
  • 클라이언트에서 서버로 JSON 형태의 데이터를 전송할 때, Content-Type 헤더를 application/json으로 설정하고 요청 body에 JSON 데이터를 포함하여 전송한다.
// 클라이언트 파일 
const response = await fetch('http://localhost:4000/api/contacts', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ name, email, message }),
});
  • express.json()을 사용하면 서버에서 이 JSON 데이터를 파싱하여 JavaScript 객체로 사용할 수 있다.
    • JSON이 아니라 form 데이터나 멀티파트 데이터 등 다른 형태의 데이터라면 express.urlencoded()나 multer 등의 미들웨어를 사용해야한다.

 

 

라우팅(Routing)

네트워크 패킷의 경로를 설정해주는 것을 의미하는데, 웹 개발에서는 url에 따라 처리하는 것을 말한다.

  • URL 경로와 특정 HTTP 요청 메소드(GET, POST, PUT, DELETE 등)에 대한 응답을 정의
  • 클라이언트의 요청을 적절한 처리 로직으로 연결
  • RESTful API 설계의 기본이 됨

 

라우트(Route)

각 라우트는 하나 이상의 핸들러 함수를 가질 수 있으며, 이러한 함수는 라우트가 일치할 때 실행된다.

다음같은 구조로 라우트를 정의한다.

app.METHOD(PATH, HANDLER)
  • app은 express의 인스턴스
  • METHOD는 HTTP 요청 메소드
  • PATH는 서버에서의 경로
  • HANDLER는 라우트가 일치할 때 실행되는 함수

 

라우트 핸들러(Route Handler)

라우트 핸들러는 특정 라우트에 대한 요청이 들어왔을 때 실행되는 함수

  • req (request): 클라이언트의 HTTP 요청에 대한 정보를 담고 있는 객체
  • res (response): 서버의 HTTP 응답을 형성하는 데 사용되는 객체
  • next (선택적): 다음 미들웨어 함수로 제어를 넘기는 함수

req 객체

  • req.app: req 객체를 통해 app 객체에 접근
  • req.ip: 요청한 Client의 ip 주소가 담김
  • req.body: 클라이언트에서 body로 전달된 정보가 담김
  • req.params: 라우트 경로에서 각각의 'query string'을 파라미터로 가져옴
  • req.query: Request를 호출할 때 쿼리 스트링으로 전달된 정보가 담김
  • req.cookies: Request를 호출할 때 Cookie 정보가 담김
  • req.get(Header): 헤더에 저장된 값을 가져오고 싶을 때 사용

res 객체

  • res.app: res 객체를 통해 app 객체에 접근
  • res.status(코드): Response에 HTTP 상태 코드를 지정
  • res.send(데이터): 데이터를 포함하여 Response를 전달
  • res.json(JSON): JSON 형식으로 Response를 전달
  • res.end(): 데이터 없이 Response를 전달
  • res.direct(주소): 리다이렉트할 주소와 함께 Response를 전달
  • res.cookie(Key, Value, Option): 쿠키를 설정할 때 사용
  • res.clearCookie(Key, Value, Option): 쿠키를 제거할 때 사용

 

 

app.METHOD([path], callback)

 

app.get( [path], callback )

클라이언트가 해당 경로에 대해 요청하면 응답함

 

app.get('/', function (req, res) {
  res.send('Hello World!');
});
  • 홈페이지에서 Hello World!로 응답

 

app.get('/api/posts/:id', async (req, res) => {
  const postId = req.params.id;

  try {
    const post = await db.collection('posts').findOne({ _id: new ObjectId(postId) });
    if (post) {
      res.json(post);
    } else {
      res.status(404).json({ message: 'Post not found' });
    }
  } catch (error) {
    console.error('Error fetching post:', error);
    res.status(500).json({ message: 'Error fetching post' });
  }
});
  • req.params.id: 라우터 경로의 id를 가져옴
  • res.json(post): post 데이터를 json으로 전달
  • res.status(404): post 데이터 없으면 404 전달
  • res.staus(500): 서버에서 에러가 발생하면 500 전달

 

 

app.post( [path], callback )

클라이언트로부터 해당 경로로 들어온 데이터를 처리

 

app.post('/', function (req, res) {
  res.send('Got a POST request');
});
  • 홈페이지인 루트 라우트(/)에서 POST 요청에 응답

 

app.post('/api/posts', async (req, res) => {
  const { title, content } = req.body;

  if (!title || !content) {
    return res.status(400).json({ message: 'Title and content are required.' });
  }

  try {
    const postsCollection = db.collection('posts');
    const newPost = {
      createdAt: new Date(),
      title,
      content
    };
    const result = await postsCollection.insertOne(newPost);

    res.status(201).json({ message: 'Post created sucessfully', postId: result.insertedId })
  } catch (error) {
    console.error('Error inserting post', error);
    res.status(500).json({ message: 'Failed to create post' });
  }
});
  • const { title, content } = req.body: 클라이언트에서 받아온 body 정보를 구조분해할당하여 사용
    • console.log(req.body): { title: 'server', content: 'server is ...'}
    • 구조분해할당을 풀어보면 const title = req.body.title,  const content = req.body.content인데 이걸 간소화함
  • title 또는 content가 없으면 400 상태와 둘 다 입력해달라는 안내를 응답
  • db에 새 post 등록하고 201 상태와 성공을 응답
  • 서버에서 에러 발행하면 500 상태와 실패를 응답
반응형