ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 노드 REST API 서버 만들기
    노드 2023. 4. 13. 12:10

    REST API

    서버에 요청을 보낼 때는 주소를 통해 요청의 내용을 표현하는 것

    • /index.html이면 index.html을 보내달라는 뜻이다.
    • 항상 html을 요구할 필요는 없다.
    • 서버가 이해하기 쉬운 주소가 좋다.

     

    REST API(Representational State Transfer)

    • 서버의 자원을 정의하고 자원에 대한 주소를 지정하는 방법이다.
    • /user면 사용자 정보에 관한 정보를 요청하는 것이다.
    • /post면 게시글에 관련된 자원을 요청하는 것이다.

     

    HTTP 요청 메서드

    • GET : 서버 자원을 가져오려고 할 때 사용
    • POST : 서버에 자원을 새로 등록하고자 할 때 사용(또는 멀 써야할 지 애매할 때)
    • PUT : 서버의 자원을 요청에 들어있는 자원으로 치환 하고자 할 때 사용
    • PATCH : 서버 자원의 일부만 수정하고자 할 때 사용
    • DELETE : 서버의 자원을 삭제 하고자 할 때 사용

     

    HTTP 프로토콜

    클라이언트가 누구든 서버와 HTTP 프로토콜로 소통 가능

    • iOS, 안드로이드, 웹이 모두 같은 주소로 요청 보낼 수 있다.
    • 서버와 클라이언트의 분리

     

    RESTful

    • REST API를 사용한 주소 체계를 이용하는 서버
    • GET / user는 사용자를 조회하는 요청, POST / user는 사용자를 등록하는 요청이다.

     

    REST API를 사용하여 간단하게 RESTful한 페이지를 구성해보자.

    총 준비물은 5개 이다.

    //about.html
    <!DOCTYPE html>
    <html>
    <head>
      <meta charset="utf-8" />
      <title>RESTful SERVER</title>
      <link rel="stylesheet" href="./restFront.css" />
    </head>
    <body>
    <nav>
      <a href="/">Home</a>
      <a href="/about">About</a>
    </nav>
    <div>
      <h2>소개 페이지입니다.</h2>
      <p>사용자 이름을 등록하세요!</p>
    </div>
    </body>
    </html>
    //restFront.css
    a { color: blue; text-decoration: none; }
    //restFront.html
    <!DOCTYPE html>
    <html lang="ko">
    <head>
      <meta charset="utf-8" />
      <title>RESTful SERVER</title>
      <link rel="stylesheet" href="./restFront.css" />
    </head>
    <body>
    <nav>
      <a href="/">Home</a>
      <a href="/about">About</a>
    </nav>
    <div>
      <form id="form">
        <input type="text" id="username">
        <button type="submit">등록</button>
      </form>
    </div>
    <div id="list"></div>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <script src="./restFront.js"></script>
    </body>
    </html>
    //restServer.js
    const http = require('http');
    const fs = require('fs').promises;
    
    const users = {}; // 데이터 저장용
    
    http.createServer(async (req, res) => {
      try {
        if (req.method === 'GET') {
          if (req.url === '/') {
            const data = await fs.readFile('./restFront.html');
            res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
            return res.end(data);
          } else if (req.url === '/about') {
            const data = await fs.readFile('./about.html');
            res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
            return res.end(data);
          } else if (req.url === '/users') {
            res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' });
            return res.end(JSON.stringify(users));
          }
          // /도 /about도 /users도 아니면
          try {
            const data = await fs.readFile(`.${req.url}`);
            return res.end(data);
          } catch (err) {
            // 주소에 해당하는 라우트를 못 찾았다는 404 Not Found error 발생
          }
        } else if (req.method === 'POST') {
          if (req.url === '/user') {
            let body = '';
            // 요청의 body를 stream 형식으로 받음
            req.on('data', (data) => {
              body += data;
            });
            // 요청의 body를 다 받은 후 실행됨
            return req.on('end', () => {
              console.log('POST 본문(Body):', body);
              const { name } = JSON.parse(body);
              const id = Date.now();
              users[id] = name;
              res.writeHead(201, { 'Content-Type': 'text/plain; charset=utf-8' });
              res.end('ok');
            });
          }
        } else if (req.method === 'PUT') {
          if (req.url.startsWith('/user/')) {
            const key = req.url.split('/')[2];
            let body = '';
            req.on('data', (data) => {
              body += data;
            });
            return req.on('end', () => {
              console.log('PUT 본문(Body):', body);
              users[key] = JSON.parse(body).name;
              res.writeHead(200, { 'Content-Type': 'text/plain; charset=utf-8' });
              return res.end('ok');
            });
          }
        } else if (req.method === 'DELETE') {
          if (req.url.startsWith('/user/')) {
            const key = req.url.split('/')[2];
            delete users[key];
            res.writeHead(200, { 'Content-Type': 'text/plain; charset=utf-8' });
            return res.end('ok');
          }
        }
        res.writeHead(404);
        return res.end('NOT FOUND');
      } catch (err) {
        console.error(err);
        res.writeHead(500, { 'Content-Type': 'text/plain; charset=utf-8' });
        res.end(err.message);
      }
    })
      .listen(8082, () => {
        console.log('8082번 포트에서 서버 대기 중입니다');
      });

    서버를 만들었다. 그리고 그 서버는 8082번 포트에 연결했다. 

     

    응답 부분을 보면 다음과 같다

    req는 요청에 대한 부분이다. 주소창에 입력을 하면 그건 GET요청이다. (외우자) 

    즉, localhost:8082 라고 주소창에 입력을 하면 그건 GET 요청인 것이다. 그리고 사실상 맨뒤에 /를 생략한 것이다.

    그러면 

    if (req.method === 'GET') {
          if (req.url === '/') {

    }

    부분이 실행되게 된다. 이런 흐름으로 다른 요청도 처리된다.

    결과를 보자.

    GET요청에 대한 응답을 잘 받아온 것을 확인할 수 있다.

     

    다음 포스트에서는 각각의 요청에 대한 처리를 살펴보겠다.

    '노드' 카테고리의 다른 글

    노드 쿠키 이해하기  (1) 2023.04.13
    노드 POST, PUT, DELETE 요청 보내기  (0) 2023.04.13
    노드 fs로 HTML 읽어 제공하기  (0) 2023.04.13
    노드 http 서버 만들기  (0) 2023.04.13
    노드 에러 처리하기  (0) 2023.04.12
Designed by Tistory.