React 정리

React - fly.io로 pg 생성후 todo 만들기

알럽유 2024. 1. 19. 02:04
728x90
반응형

npm i express 로 백엔드 부분 생성

 

app.js를 만들어주고

 

cors 미들웨어 설치

  • npm i cors
// 모든 도메인에 대해서 CORS 허용해주도록 설정
import express from "express";
import cors from "cors";

const app = express();
app.use(cors());
// cdpn.io에서 들어오는 요청은 특별히 허용해주도록 설정
import express from "express";
import cors from "cors";

const app = express();

const corsOptions = {
  origin: "*",
 
};

app.use(cors(corsOptions));

fly.io

Windows 에서 설치

윈도우는 새로운 버전의 powershell 을 통하여 설치 가능합니다. 우선 powershell  관리자 권한 으로 실행한 후, 하기의 명령어를 실행하여 봅시다.

iwr https://fly.io/install.ps1 -useb | iex

또는

pwsh -Command "iwr https://fly.io/install.ps1 -useb | iex"

flyctl 설치 확인

flyctl 이 정상적으로 설치되었는지 확인하기 위하여, 운영체제의 터미널을 실행하여 아래의 명령어를 입력하여 동작하는지 확인합니다.

flyctl

만일 정상적으로 설치되었다면, fly 와 관련된 내용이 출력될 것입니다.

flyctl 을 이용하여 fly.io 에 로그인

flyctl 을 이용하여 fly 서비스와 연동하기 위해서는 계정을 연동하여야 합니다.

flyctl auth login

명령어를 입력하면 fly 서비스 페이지와 함께 로그인을 할 수 있게 됩니다.

flyctl 을 이용한 docker 어플리케이션 배포

이번 절에서는 flyctl 을 통해서 docker 어플리케이션을 빌드하고 배포하는 방법에 대해서 간략히 서술했습니다.

 

Dockerfile 이 있는 프로젝트의 경로에서 터미널을 실행합니다. 그 후, 하기의 명령어를 입력합니다.

fly launch

DB 연결

fly.io 로 pg 생성

flyctl pg create
  • 여기서 생성되는 정보는 영구저장소에 기록
  • 외부에서는 fly.io 안쪽의 db에 바로접근이 불가능하기 때문에, 접근이 필요할 때 마다 flyctl proxy 명령으로 개구멍을 open
flyctl proxy 5432 -a [DB 서버명]

EX : flyctl proxy 5432 -a appName
  • ctrl + c 로 프록시 닫기
  • 디비버로 해당 DB에 접속되는지 테스트
  • 디비 접급 정보에 에 새 db 정보 저장
  • DB 비번을 노출한 이유 : 외부에서 접근이 불가능하기 때문에

 

잘 적어둔 정보를 잘 입력한다.

-- Drop the database if it exists and create a new one
DROP DATABASE IF EXISTS todo202401;
CREATE DATABASE todo202401;

-- Connect to the new database
-- In pgSQL, you usually switch databases using a client or connection string

-- Create the 'todo' table
CREATE TABLE todo (
    id SERIAL PRIMARY KEY,
    created_date TIMESTAMP NOT NULL,
    modified_date TIMESTAMP NOT NULL,
    content VARCHAR(200) NOT NULL,
    is_checked BOOLEAN DEFAULT false NOT NULL
);

DROP TABLE IF EXISTS todo;
SELECT * FROM todo;
INSERT INTO todo (created_date, modified_date, content, is_checked) VALUES
    (NOW(), NOW(), '첫 번째 할 일', false),
    (NOW(), NOW(), '두 번째 할 일', true),
    (NOW(), NOW(), '세 번째 할 일', false);
-- Add unique constraint to user_code and no
ALTER TABLE todo ADD CONSTRAINT unique_user_code_no UNIQUE (user_code, "no");

-- Insert test data

PG 설치

  • npm install pg PG 연결 app.js
  • # 테이블 생성 CREATE TABLE todo ( id SERIAL PRIMARY KEY, created_date TIMESTAMP NOT NULL, modified_date TIMESTAMP NOT NULL, content VARCHAR(200) NOT NULL, is_checked BOOLEAN DEFAULT FALSE NOT NULL ); # 테이블 전체 조회 SELECT table_name FROM information_schema.tables WHERE table_schema = 'public';​
  • import express from "express";
    import pkg from 'pg';
    
    const { Pool } = pkg;
    
    const pool = new Pool({
        user: 'postgres',
        password: '[비밀번호]',
        host: '127.0.0.1',
        database: 'postgres',
        port: 5432,
      });
    
    
    const app = express();
    
    app.use(express.json());
    
    const port = 3000;
    
    app.get("/", (req, res) => {
        res.send("Hello World!");
    });
    
    
    // get 다건
    app.get("/api/v1/todos", async (req, res) => {
        try {
            const { rows } = await pool.query(
                `
                SELECT *
                FROM todo
                ORDER BY id DESC
                `
            );
    
            res.json({
                resultCode: "S-1",
                msg: "성공",
                data: rows,
            });
        } catch (error) {
            console.error(error);
            res.status(500).json({
                resultCode: "F-1",
                msg: "에러 발생",
            });
        }
    });
    
    
    // get 단건
    app.get("/api/v1/todos/:id", async (req, res) => {
        try {
            const { id } = req.params;
            const { rows } = await pool.query(
                `
                SELECT *
                FROM todo
                WHERE id = $1
                ORDER BY id DESC
                `,
                [id]
            );
    
            if (rows.length === 0) {
                res.status(404).json({
                    resultCode: "F-1",
                    msg: "not found",
                });
                return;
            }
    
            res.json({
                resultCode: "S-1",
                msg: "성공",
                data: rows[0],
            });
        } catch (error) {
            console.error(error);
            res.status(500).json({
                resultCode: "F-1",
                msg: "에러 발생",
            });
        }
    });
    
    // post 등록
    app.post("/api/v1/todos", async (req, res) => {
        try {
            const { content } = req.body;
            const { rows } = await pool.query(
                `
                INSERT INTO todo (created_date, modified_date, content, is_checked)
                VALUES (NOW(), NOW(), $1, false)
                RETURNING *
                `,
                [content]
            );
    
            res.json({
                resultCode: "S-3",
                msg: "성공",
                data: rows[0],
            });
        } catch (error) {
            console.error(error);
            res.status(500).json({
                resultCode: "F-1",
                msg: "에러 발생",
            });
        }
    });
    
    // patch 수정
    app.patch("/api/v1/todos/:id", async (req, res) => {
        try {
            const { id } = req.params;
            const { rows } = await pool.query(
                `
                SELECT *
                FROM todo
                WHERE id = $1
                ORDER BY id DESC
                `,
                [id]
            );
    
            if (rows.length === 0) {
                res.status(404).json({
                    resultCode: "F-1",
                    msg: "not found",
                });
                return;
            }
    
            const { is_checked } = req.body;
    
            await pool.query(
                `
                UPDATE todo
                SET modified_date = NOW(),
                    is_checked = $1
                WHERE id = $2
                `,
                [is_checked, id]
            );
    
            res.json({
                resultCode: "S-3",
                msg: "수정성공",
                data: rows[0],
            });
        } catch (error) {
            console.error(error);
            res.status(500).json({
                resultCode: "F-1",
                msg: "에러 발생",
            });
        }
    });
    
    // delete 삭제
    app.delete("/api/v1/todos/:id", async (req, res) => {
        try {
            const { id } = req.params;
            const { rows } = await pool.query(
                `
                SELECT *
                FROM todo
                WHERE id = $1
                ORDER BY id DESC
                `,
                [id]
            );
    
            if (rows.length === 0) {
                res.status(404).json({
                    resultCode: "F-1",
                    msg: "not found",
                });
                return;
            }
    
            await pool.query(
                `
                DELETE FROM todo
                WHERE id = $1
                `,
                [id]
            );
    
            res.json({
                resultCode: "S-4",
                msg: "삭제성공",
                data: rows[0],
            });
        } catch (error) {
            console.error(error);
            res.status(500).json({
                resultCode: "F-1",
                msg: "에러 발생",
            });
        }
    });
    
    app.listen(port, () => {
        console.log(`Example app listening on port ${port}`);
    });

프론트 부분은 저번 시간에 만든 코드를 참고한다.

https://codingbasics.tistory.com/224

 

React로 Todo 만들기

빈 폴더를 하나 만들고 터미널을 열고 npm create vite@latest √ Project name: . or 생성할 폴더명(본인이름) √ Package name: movie-app √ Select a framework: » React √ Select a variant: » JavaScript npm install npm run dev #

codingbasics.tistory.com