ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 코딩 자율학습단(Vue.js 프런트엔드 개발 입문) 16일차
    정보교육/프런트엔드 2024. 7. 8. 06:34

    10장 데이터 통신하기


    10.1 데이터 통신에서 알아야 할 개념

    1. HTTP와 메서드

    통신 프로토콜: 데이터 통신에 필요한 특정한 규칙과 규약

    클라이언트에서 서버로 HTTP 요청

    서버는 요청에 대해 HTTP 응답

    주요 HTTP 메서드

    GET: 데이터 가져오기

    POST: 데이터 쓰기(추가하기)

    PUT: 데이터 전체 변경하기

    PATCH: 데이터 일부 변경하기

    DELETE: 데이터 삭제하기

     

    2. API

    API: Application Programming Interface, 클라이언트와 서버는 HTTP를 사용해 데이터를 주고받을 때 필요한 데이터를 어떻게 요청하고 어떻게 응답받을지 정하는 약속

    엔드포인트: 클라이언트에서 직접 API의 기능을 사용하려고 호출하는 끝점


    10.2 Node.js로 웹 서버와 API 만들기

    // vue.js.frontend/ch10/server/server.js
    const express = require('express');
    const fs = require('fs/promises');
    const path = require('path');
    const app = express();
    const port = 3000;
    const dataFilePath = path.join(__dirname, 'data.json');
    app.use(express.json());
    // CORS 에러 해결하기(server)
    app.use((req, res, next) => {
      res.header('Access-Control-Allow-Origin', '*');
      res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, PATCH, DELETE');
      next();
    });
    
    // GET: 모든 데이터 가져오기
    app.get('/api/data', async (req, res) => {
      try {
        const data = await readDataFile();
        res.json(data);
      } catch (error) {
        res.status(500).json({ error: 'Internal Server Error' });
      }
    });
    // POST: 새로운 데이터 추가하기
    app.post('/api/data', async (req, res) => {
      try {
        const newData = req.body;
        const data = await readDataFile();
        const writeData = {
          id: data.length + 1,
          name: `${newData.name} ${data.length + 1}`,
          description: `${newData.description} ${data.length + 1}`,
        };
        data.push(writeData);
        await writeDataFile(data);
        res.json(newData);
      } catch (error) {
        console.log(error);
        res.status(500).json({ error: 'Internal Server Error' });
      }
    });
    // PUT: 데이터 업데이트하기
    app.put('/api/data/:id', async (req, res) => {
      try {
        const id = Number(req.params.id);
        const updatedData = req.body;
        const data = await readDataFile();
        const index = data.findIndex((item) => item.id === id);
        if (index !== -1) {
          data[index] = { ...data[index], ...updatedData };
          await writeDataFile(data);
          res.json(data[index]);
        } else {
          res.status(404).json({ error: 'Not Found' });
        }
      } catch (error) {
        res.status(500).json({ error: 'Internal Server Error' });
      }
    });
    // PATCH: 데이터 부분 업데이트하기
    app.patch('/api/data/:id', async (req, res) => {
      try {
        const id = Number(req.params.id);
        const partialData = req.body;
        const data = await readDataFile();
        const index = data.findIndex((item) => item.id === id);
        if (index !== -1) {
          data[index] = { ...data[index], ...partialData };
          await writeDataFile(data);
          res.json(data[index]);
        } else {
          res.status(404).json({ error: 'Not Found' });
        }
      } catch (error) {
        res.status(500).json({ error: 'Internal Server Error' });
      }
    });
    // DELETE: 데이터 삭제하기
    app.delete('/api/data/:id', async (req, res) => {
      try {
        const id = Number(req.params.id);
        const data = await readDataFile();
        const index = data.findIndex((item) => item.id === id);
        if (index !== -1) {
          const deletedItem = data.splice(index, 1)[0];
          await writeDataFile(data);
          res.json(deletedItem);
        } else {
          res.status(404).json({ error: 'Not Found' });
        }
      } catch (error) {
        res.status(500).json({ error: 'Internal Server Error' });
      }
    });
    // Helper 함수: 데이터 파일 읽기
    async function readDataFile() {
      const data = await fs.readFile(dataFilePath, 'utf-8');
      return data ? JSON.parse(data) : [];
    }
    // Helper 함수: 데이터 파일 쓰기
    async function writeDataFile(data) {
      await fs.writeFile(dataFilePath, JSON.stringify(data, null, 2), 'utf-8');
    }
    app.listen(port, () => {
      console.log(`Server is running at http://localhost:${port}`);
    });
    // vue.js.frontend/ch10/server/data.json
    [
      {
        "id": 1,
        "name": "update data",
        "description": "update description"
      },
      {
        "id": 2,
        "name": "new data 2",
        "description": "sample data 2"
      }
    ]


    10.3 Fetch API로 데이터 통신하기

     

    1. 기본문법

    2. HTTP 메서드 사용법

    3. 뷰에서 사용하기

    // vue.js.frontend/ch10/src/App.vue
    <script setup>
    const getData = () => {
      fetch('/api/data')
        .then((response) => response.json())
        .then((result) => console.log(result))
        .catch((error) => console.error('데이터를 가져오던 중 에러 발생:', error));
    };
    const postData = () => {
      fetch('/api/data', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          name: 'new data',
          description: 'sample data',
        }),
      })
        .then((response) => response.json())
        .then((result) => console.log(result))
        .catch((error) => console.error('데이터를 추가하던 중 에러 발생:', error));
    };
    const putData = () => {
      fetch('/api/data/1', {
        method: 'PUT',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          name: 'update data',
          description: 'update description',
        }),
      })
        .then((response) => response.json())
        .then((result) => console.log(result))
        .catch((error) =>
          console.error('전체 데이터를 업데이트하던 중 에러 발생:', error)
        );
    };
    const patchData = () => {
      fetch('/api/data/1', {
        method: 'PATCH',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          description: 'update description',
        }),
      })
        .then((response) => response.json())
        .then((result) => console.log(result))
        .catch((error) =>
          console.error('데이터를 부분 업데이트하던 중 에러 발생:', error)
        );
    };
    </script>
    <template>
      <div>
        <button @click="postData">POST</button>
        <button @click="getData">GET</button>
        <button @click="putData">PUT</button>
        <button @click="patchData">PATCH</button>
      </div>
    </template>

    4. CORS 에러 해결하기

    - 서버에서 해결하기

    // CORS 에러 해결하기(server)
    app.use((req, res, next) => {
      res.header('Access-Control-Allow-Origin', '*');
      res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, PATCH, DELETE');
      next();
    });

    - 클라이언트에서 해결하기

    // CORS 에러 해결하기(client)
      server: {
        proxy: {
          '/api': {
            target: 'http://localhost:3000',
            changeOrigin: true,
          },
        },
      },
    })
Designed by Tistory.