[๋ฐ๋ธŒ์ฝ”์Šค] ๋„์„œ ๋ชฉ๋ก ์กฐํšŒ ํŽ˜์ด์ง• ์ ์šฉ API

2025. 5. 19. 22:34ยท๐Ÿ•Š๏ธํ”„๋กœ๊ทธ๋ž˜๋จธ์Šค ๋ฐ๋ธŒ์ฝ”์Šค/ํ”„๋กœ์ ํŠธ

join์œผ๋กœ ์นดํ…Œ๊ณ ๋ฆฌ ์•„์ด๋””-์ด๋ฆ„ ๋งคํ•‘

 

1. fk ์ถ”๊ฐ€ ํ›„

2. join ์ฟผ๋ฆฌ ์‹คํ–‰

SELECT * FROM books LEFT
JOIN category ON books.category_id = category.id;

 

3. api์—์„œ join ์ฟผ๋ฆฌ ์‹คํ–‰

const conn = require("../mariadb");
const { StatusCodes } = require("http-status-codes");

const getAllBooks = (req, res) => {
  let { category_id } = req.query;

  if (category_id) {
    let sql = `SELECT * FROM books LEFT JOIN category ON books.category_id = category.id WHERE books.category_id=?`;
    conn.query(sql, category_id, (err, result) => {
      if (err) {
        return res.status(StatusCodes.BAD_REQUEST).end();
      }

      if (result.length) return res.status(StatusCodes.OK).json(result);
      else return res.status(StatusCodes.NOT_FOUND).end();
    });
  } else {
    let sql = `SELECT * FROM books LEFT JOIN category ON books.category_id = category.id`;
    conn.query(sql, (err, result) => {
      if (err) {
        return res.status(StatusCodes.BAD_REQUEST).end();
      }

      return res.status(StatusCodes.OK).json(result);
    });
  }
};

const getBookById = (req, res) => {
  //parseInt ์ ์šฉ ์‹œ, id ์†์„ฑ์„ ๊ตฌ์กฐ ๋ถ„ํ•ด ์‹œ๋„
  //parseInt๋Š” ์ˆซ์ž๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋ฏ€๋กœ, ๊ตฌ์กฐ ๋ถ„ํ•ด ๋ถˆ๊ฐ€. '
  //parseInt๋Š” ๋ฌธ์ž์—ด์„ ์ •์ˆ˜๋กœ ๋ณ€ํ™˜ํ•˜๋Š”๋ฐ, ๊ฐ์ฒด์ธ req.parmas ์ „์ฒด๋ฅผ ์ „๋‹ฌํ•˜๋Š” ์˜ค๋ฅ˜๊ฐ€ ์žˆ์—ˆ๋‹ค.

  let { id } = req.params;

  let sql = `SELECT * FROM books LEFT JOIN category ON books.category_id = category.id WHERE books.id=?`;

  conn.query(sql, id, (err, result) => {
    if (err) {
      return res.status(StatusCodes.BAD_REQUEST).end();
    }

    if (result[0]) return res.status(StatusCodes.OK).json(result[0]);
    else return res.status(StatusCodes.NOT_FOUND).end();
  });
};

module.exports = {
  getAllBooks,
  getBookById,
};

 

 

๊ธฐ๊ฐ„ ์กฐ๊ฑด ์ถ”๊ฐ€ํ•˜๊ธฐ

๋ฐ์ดํ„ฐ์ด์Šค ์‹œ๊ฐ„ ๋ฒ”์œ„๋ฅผ ๊ตฌํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” DATE_ADD()์™€ DATE_SUB()๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค

- DATE_ADD(๊ธฐ์ค€๋‚ ์งœ, INTERVAL)

- DATE_SUB(๊ธฐ์ค€๋‚ ์งœ, INTERVAL)

 

SELECT DATE_ADD(NOW(), INTERVAL 1 MONTH);

์‹œ๊ฐ„ ๋ฒ”์œ„ ์ง€์ •, ๋ฒ”์œ„ ์ง€์ •์€ BETWEEN์„ ์‚ฌ์šฉํ•œ๋‹ค.

 

SELECT * FROM books WHERE pub_date BETWEEN  DATE_SUB(NOW(), INTERVAL 10 DAY) AND NOW();

 

๊ธฐ์กด์˜ ๋ณต์žกํ•˜๋˜ if-else ๋ฌธ์„ sql ๋ฌธ ์กฐ๊ฑด๋ฌธ ์ฒ˜๋ฆฌ๋กœ ๋ถ„๋ฆฌํ•˜์—ฌ ๊ตฌ์กฐ ๊ฐœ์„ 

//๋ณ€๊ฒฝ ์ „
  if (category_id) {
    let sql = `SELECT * FROM books LEFT JOIN category ON books.category_id = category.id WHERE books.category_id=?`;
    conn.query(sql, category_id, (err, result) => {
      if (err) {
        return res.status(StatusCodes.BAD_REQUEST).end();
      }

      if (result.length) return res.status(StatusCodes.OK).json(result);
      else return res.status(StatusCodes.NOT_FOUND).end();
    });
  } else {
    let sql = `SELECT * FROM books LEFT JOIN category ON books.category_id = category.id`;
    conn.query(sql, (err, result) => {
      if (err) {
        return res.status(StatusCodes.BAD_REQUEST).end();
      }

      return res.status(StatusCodes.OK).json(result);
    });
  }
 //๋ณ€๊ฒฝ ํ›„
 let sql = "SELECT * FROM books";
  let values = [];
  if (category_id && news) {
    sql +=
      " WHERE category_id=? AND pub_date BETWEEN DATE_SUB(NOW(), INTERVAL 1 MONTH) AND NOW()";
    values = [category_id, news];
  } else if (category_id) {
    sql += " WHERE category_id=?";
    values = category_id;
  } else if (news) {
    sql +=
      " WHERE pub_date BETWEEN DATE_SUB(NOW(), INTERVAL 1 MONTH) AND NOW()";
    values = news;
  }

  conn.query(sql, values, (err, result) => {
    if (err) {
      return res.status(StatusCodes.BAD_REQUEST).end();
    }

    if (result.length) {
      return res.status(StatusCodes.OK).json(result);
    } else {
      return res.status(StatusCodes.NOT_FOUND).end();
    }
  });

 

์ด์ œ ์ฟผ๋ฆฌ๊ฐ€ ์ถ”๊ฐ€๋  ๋•Œ๋งˆ๋‹ค conn.query๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์ฒ˜๋ฆฌํ•˜์ง€ ์•Š๊ณ , sql ๋ฌธ ์กฐ๊ฑด ๋ฌธ๋‚ด์—์„œ SQL ์ฟผ๋ฆฌ์— ๋Œ€ํ•œ ๋ถ„๊ธฐ๋งŒ ์ฒ˜๋ฆฌํ•œ ํ›„, conn.query์—์„œ ์œ„์—์„œ ์ฒ˜๋ฆฌํ•œ sql๊ณผ values๋ฅผ ๋ฐ›์•„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค. 

 

์กฐ๊ฑด๋ฌธ ์ž‘์„ฑ ์‹œ, ์กฐ๊ฑด์˜ ์ˆœ์„œ๋ฅผ ํ•ญ์ƒ ์œ ์˜ํ•ด์•ผ ํ•จ!

 

์˜ค๋ฅ˜: ๊ฐœ๋ณ„์กฐํšŒ ์‹œ id๊ฐ€ ๋ฌด์กฐ๊ฑด 0์œผ๋กœ ๋‚˜์˜ค๋Š” ๋ฌธ์ œ

์›์ธ: book ํ…Œ์ด๋ธ”์˜ id์™€, category์˜ id๊ฐ€ join ์‹œ ์ถฉ๋Œํ•˜์—ฌ ๋ฐœ์ƒํ•˜๋Š” ๋ฌธ์ œ์˜€์Œ

 

๊ธฐ์กด์— ์•„๋ž˜์ฒ˜๋Ÿผ ์ฟผ๋ฆฌ๋ฅผ ์‚ฌ์šฉ์ค‘์ด์—ˆ์Œ

  let sql = `SELECT * FROM books LEFT JOIN category ON books.category_id = category.id WHERE books.id=?`;

SELECT *๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ books์™€ category ํ…Œ์ด๋ธ” ๋ชจ๋‘ id ์ปฌ๋Ÿผ์„ ๊ฐ€์ ธ, JOIN ๊ฒฐ๊ณผ์—์„œ๋„ ๋‘ id๊ฐ€ ์ถฉ๋Œ ํ•œ ใ„ฑ๊ฒƒ. mariadb์—์„œ๋Š” ๋‚˜์ค‘์— ์˜ค๋Š” ํ…Œ์ด๋ธ”๋กœ id ๊ฐ’์ด ๋ฎ์–ด์จ์ง€๊ฑฐ๋‚˜, ์ผ๋ถ€ ๊ฒฝ์šฐ์—๋Š” ๊ธฐ๋ณธ๊ฐ’์ธ 0์œผ๋กœ ์„ค์ •๋  ์ˆ˜ ์ž‡๋‹ค.

 

ํ™•์ธ ๊ฒฐ๊ณผ, ๋ฌด์กฐ๊ฑด 0 ์ด ์•„๋‹Œ category์˜ id ๊ฐ’์œผ๋กœ ์ถœ๋ ฅ๋˜๊ณ  ์žˆ์—ˆ๋‹ค.

 

์™ธ๋ž˜ํ‚ค ๊ด€๊ณ„๋ฅผ ์ด์šฉํ•ด, ํ•„์š”ํ•œ category_name๋งŒ ๊ฐ€์ ธ์˜ค๋„๋ก ์ˆ˜์ •ํ–ˆ๋‹ค.

  let sql = `SELECT books.*, (SELECT category_name FROM category WHERE id = books.category_id) as category_name 
             FROM books 
             WHERE books.id=?`;

JOIN ๋Œ€์‹  ์„œ๋ธŒ์ฟผ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ  category_name ๋งŒ ๊ฐ€์ ธ์˜ค๋„๋ก ๋ณ€๊ฒฝ

books ํ…Œ์ด๋ธ” ๋ชจ๋“  ์ปฌ๋Ÿผ์€ ์œ ์ง€ํ•˜๊ณ , category ํ…Œ์ด๋ธ”๊ณผ์˜ ๋ถˆํ•„์š”ํ•œ JOIN์„ ์ œ๊ฑฐํ•˜์˜€๋‹ค

์ด์ œ books ํ…Œ์ด๋ธ”์˜ ๋ฐ์ดํ„ฐ๋Š” ์˜จ์ „ํžˆ ์œ ์ง€๋˜๋ฉด์„œ(id ํฌํ•จ), category_name๋งŒ ์ถ”๊ฐ€๋กœ ๊ฐ€์ ธ์™€ ์ •์ƒ์ ์œผ๋กœ id๊ฐ€ ์ถœ๋ ฅ๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์ž‡๋”ฐ.

 

ํŽ˜์ด์ง• ์ ์šฉ

์ฟผ๋ฆฌ๋ฌธ์œผ๋กœ ์ฒ˜๋ฆฌ

SELECT * FROM books LIMIT 4 OFFSET 8

- LIMIT ์ถœ๋ ฅํ•  ํ–‰์˜ ์ˆ˜
- OFFSET: ์‹œ์ž‘ ์ง€์ 

 

๊ณ ์ •ํ•˜์ง€ ์•Š๊ณ , ๋™์ ์œผ๋กœ ๋ฐ›์•„ ์ฒ˜๋ฆฌํ•˜๋„๋ก

-limit์€ url๋กœ ๋ฐ›์•„์„œ ์ฒ˜๋ฆฌ

 

/books?limit={page ๋‹น ๋„์„œ ์ˆ˜}&currentPage={ํ˜„์žฌ ํŽ˜์ด์ง€}

 let { category_id, news, limit, currentPage } = req.query;

  let offset = (currentPage - 1) * limit;

  let sql = "SELECT * FROM books LIMIT ? OFFSET ?";
  let values = [limit, offset];
  if (category_id && news) {
    sql +=
      " WHERE category_id=? AND pub_date BETWEEN DATE_SUB(NOW(), INTERVAL 1 MONTH) AND NOW()";
    values = values.push(category_id, news);
  } else if (category_id) {
    sql += " WHERE category_id=?";
    values = values.push(category_id);
  } else if (news) {
    sql +=
      " WHERE pub_date BETWEEN DATE_SUB(NOW(), INTERVAL 1 MONTH) AND NOW()";
    values = values.push(news);
  }

 

์˜ค๋ฅ˜: ER_PARSE_ERROR(1064)

sql ๊ตฌ๋ฌธ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒ

 

1. 

```

  code: 'ER_PARSE_ERROR',
  errno: 1064,
  sqlState: '42000',
  sqlMessage: "You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '? WHERE category_id=? AND pub_date BETWEEN DATE_SUB(NOW(), INTERVAL 1 MONTH) ...' at line 1",
  sql: 'SELECT * FROM books LIMIT 4 OFFSET ? WHERE category_id=? AND pub_date BETWEEN DATE_SUB(NOW(), INTERVAL 1 MONTH) AND NOW()'
}

```

 

2. 

```

  code: 'ER_PARSE_ERROR',
  errno: 1064,
  sqlState: '42000',
  sqlMessage: "You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ''0'' at line 1",
  sql: "SELECT * FROM books  WHERE category_id=4 AND pub_date BETWEEN DATE_SUB(NOW(), INTERVAL 1 MONTH) AND NOW() LIMIT 0 OFFSET '0'"
}

```

 

3. 

```

  code: 'ER_PARSE_ERROR',
  errno: 1064,
  sqlState: '42000',
  sqlMessage: "You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ''true' OFFSET 4' at line 1",
  sql: "SELECT * FROM books  WHERE category_id='0' AND pub_date BETWEEN DATE_SUB(NOW(), INTERVAL 1 MONTH) AND NOW() LIMIT 'true' OFFSET 4"
}

```

 

์›์ธ: 

1. sql ๋ฌธ๋ฒ•์˜ ์ˆœ์„œ. limit๊ณผ offset์„ ๋ชจ๋“  ์ฟผ๋ฆฌ์— ์ ์šฉํ•˜๊ธฐ ์œ„ํ•ด where ์ ˆ ์•ž์— ๋ฐฐ์น˜ํ•˜์˜€๋Š”๋ฐ, ์˜ฌ๋ฐ”๋ฅธ ์ˆœ์„œ๊ฐ€ ์•„๋‹ˆ์–ด์„œ ๋ฐœ์ƒํ•œ ๋ฌธ์ œ์˜€๋‹ค.

sql ๋ฌธ์˜ ์˜ฌ๋ฐ”๋ฅธ ์ˆœ์„œ: 

์ ˆ (Clause) ์„ค๋ช…

SELECT ์กฐํšŒํ•  ์ปฌ๋Ÿผ ์ง€์ •
FROM ํ…Œ์ด๋ธ” ์ง€์ •
WHERE ์กฐ๊ฑด ์ง€์ • (ํ•„ํ„ฐ๋ง)
GROUP BY ๊ทธ๋ฃนํ™” (์ง‘๊ณ„์šฉ)
HAVING ๊ทธ๋ฃน ํ•„ํ„ฐ๋ง
ORDER BY ์ •๋ ฌ
LIMIT / OFFSET ํ–‰ ๊ฐœ์ˆ˜ ์ œํ•œ, ์‹œ์ž‘ ์œ„์น˜ ์ง€์ •



๋”ฐ๋ผ์„œ SELECT * FROM ์œ„์น˜์—์„œ limit, offset์„ ์„ค์ •ํ•˜๋ฉด ใ…์•ˆ๋˜๊ณ , ์กฐ๊ฑด ๋ฌธ ์ข…๋ฃŒ ํ›„ ์ตœํ›„์— sql += ํ•˜์—ฌ limit, offset ์กฐ๊ฑด์„ ์ถ”๊ฐ€ํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.

2. offset ๊ฐ’์ด ๋ฌธ์ž์—ด 0์œผ๋กœ ์ „๋‹ฌ๋˜์—ˆ๋‹ค.

์ˆซ์ž ํƒ€์ž…์ด์–ด์•ผ ํ•˜๋Š”๋ฐ, ๋ฌธ์ž์—ด์ด ์‚ฌ์šฉ๋˜์–ด ๋ฐœ์ƒํ•œ ์˜ค๋ฅ˜. parseInt๋กœ ์ˆซ์ž ๋ณ€ํ™˜

 

3. ํŒŒ๋ผ๋ฏธํ„ฐ ๋ฐ”์ธ๋”ฉ ์ˆœ์„œ ๋ฌธ์ œ

values ๋ฐฐ์—ด์˜ ๊ฐ’์ด sql์˜ ? ์œ„์น˜์™€ ์ˆœ์„œ๋Œ€๋กœ ๋งค์นญ๋˜์–ด์•ผ ํ•œ๋‹ค.

where ์ ˆ์˜ ์กฐ๊ฑด ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ€ ๋จผ์ € ์˜ค๊ณ , limit.offset์ด ๋‚˜์ค‘์— ์™€์•ผ ํ•จ

 

ํ•ด๊ฒฐ
```

let sql = "SELECT * FROM books";  // ๊ธฐ๋ณธ ์ฟผ๋ฆฌ
if (์กฐ๊ฑด) {
  sql += " WHERE ...";           // WHERE ์ ˆ ์ถ”๊ฐ€
}
sql += " LIMIT ? OFFSET ?";      // ๋งˆ์ง€๋ง‰์— LIMIT/OFFSET ์ถ”๊ฐ€

```

 

```

let values = [];
// WHERE ์ ˆ ํŒŒ๋ผ๋ฏธํ„ฐ ๋จผ์ € ์ถ”๊ฐ€
if (category_id) values.push(parseInt(category_id));
// LIMIT/OFFSET ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” ๋งˆ์ง€๋ง‰์— ์ถ”๊ฐ€
values.push(parseInt(limit), parseInt(offset));

```

 

news ์กฐ๊ฑด ์ฒ˜๋ฆฌ๋กœ ๋ณ€๊ฒฝ

api ์„ค๊ณ„ ๋ฐฉ์‹ ์ค‘, ํŒŒ๋ผ๋ฏธํ„ฐ ์ „๋‹ฌ ๋ฐฉ์‹๊ณผ ์กฐ๊ฑด ์ฒ˜๋ฆฌ ๋ฐฉ์‹์ด ์žˆ๋‹ค. ๊ธฐ์กด์—๋Š” news๋ฅผ ํŒŒ๋ผ๋ฏธํ„ฐ ์ „๋‹ฌ ๋ฐฉ์‹์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๊ณ  ์žˆ์—ˆ๋Š”๋ฐ, ํŒŒ๋ผ๋ฏธํ„ฐ ๋ฐ”์ธ๋”ฉ์—์„œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค.

```

-- ๋ฐœ์ƒํ•œ ์˜ค๋ฅ˜ ์ฟผ๋ฆฌ
SELECT * FROM books WHERE category_id='0' AND pub_date BETWEEN ... LIMIT 'true' OFFSET 4

```

 

๋ฌธ์ œ์ :

- news ๊ฐ’์ด where ์ ˆ์ด ์•„๋‹Œ limit ์ ˆ์— ๋ฐ”์ธ๋”ฉ๋˜์–ด limit true์™€ ๊ฐ™์€ ์ž˜๋ชป๋œ ์ฟผ๋ฆฌ ์ƒ์„ฑ

- values ๋ฐฐ์—ด์— news ๊ฐ’์„ ์‚ฌ์šฉํ•˜๋ฉด์„œ ํŒŒ๋ผ๋ฏธํ„ฐ ์ˆœ์„œ๊ฐ€ ๊ผฌ์ž„

- ๋ถˆํ•„์š”ํ•œ ํŒŒ๋ผ๋ฏธํ„ฐ ๋ฐ”์ธ๋”ฉ์œผ๋กœ sql ์˜ค๋ฅ˜ ๋ฐœ์ƒ

 

 

```

// ๋ณ€๊ฒฝ ์ „: ํŒŒ๋ผ๋ฏธํ„ฐ ๋ฐ”์ธ๋”ฉ ๋ฐฉ์‹
if (news) {
  sql += " WHERE pub_date BETWEEN ... AND NOW()";
  values.push(news);  // ๋ฌธ์ œ ๋ฐœ์ƒ
}

// ๋ณ€๊ฒฝ ํ›„: ์กฐ๊ฑด ์ฒ˜๋ฆฌ ๋ฐฉ์‹
if (news === "true") {
  sql += " WHERE pub_date BETWEEN ... AND NOW()";
  // ํŒŒ๋ผ๋ฏธํ„ฐ ๋ฐ”์ธ๋”ฉ ์—†์ด ์กฐ๊ฑด๋งŒ ์ฒ˜๋ฆฌ
}

```

 

- ์•ˆ์ •์„ฑ: sql ์ธ์ ์…˜ ์œ„ํ—˜ ์ œ๊ฑฐ, ํŒŒ๋ผ๋ฏธํ„ฐ ๋ฐ”์ธ๋”ฉ ์˜ค๋ฅ˜ ๋ฐฉ์ง€, ์ž˜๋ชป๋œ ์ž…๋ ฅ ๊ฐ’ ์ฐจ๋‹จ

- ๋ช…ํ™•์„ฑ:์ตœ์‹  ๋„์„œ ์—ฌ๋ถ€๋ผ๋Š” ์˜๋„๊ฐ€ ์ฝ”๋“œ์— ๋ช…ํ™•ํžˆ ๋“œ๋Ÿฌ๋‚จ- true/false๋กœ ๋‹จ์ˆœํ™”๋œ ์ฒ˜๋ฆฌ

- ํšจ์œจ์„ฑ: ๋ถˆํ•„์š”ํ•œ ํŒŒ๋ผ๋ฏธํ„ฐ ๋ฐ”์ธ๋”ฉ ์ œ๊ฑฐ, sql ์ฟผ๋ฆฌ ์‹คํ–‰ ์„ฑ๋Šฅ ํ–ฅ์ƒ

 

์ง€๊ธˆ์€ true, false๋กœ ์‹ ๊ฐ„ ๋„์„œ ์—ฌ๋ถ€๋งŒ ํŒ๋ณ„ํ•˜์—ฌ ๊ฐ€๋Šฅํ•œ ๊ตฌ์กฐ. ๋งŒ์•ฝ ๊ธฐ๊ฐ„๋ณ„ ์กฐํšŒ ๋“ฑ์˜ ๊ตฌ์กฐ ๊ฐœ์„  ์‹œ, ์•„๋ž˜ ๋ฐฉํ–ฅ์œผ๋กœ ํ™•์žฅ ๊ฐ€๋Šฅ

```

//๊ธฐ๊ฐ„๋ณ„ ์กฐํšŒ

// /books?timeRange=1m|3m|6m
const timeRangeMap = {
  '1m': 1,
  '3m': 3,
  '6m': 6
};

if (timeRange && timeRangeMap[timeRange]) {
  sql += " WHERE pub_date BETWEEN DATE_SUB(NOW(), INTERVAL ? MONTH) AND NOW()";
  values.push(timeRangeMap[timeRange]);
}

```

```

//์ปค์Šคํ…€ ๋‚ ์งœ ์กฐํšŒ

// /books?dateFrom=2024-01-01&dateTo=2024-03-31
if (dateFrom && dateTo) {
  sql += " WHERE pub_date BETWEEN ? AND ?";
  values.push(dateFrom, dateTo);
}

```

 

๊ฐ•์‚ฌ๋‹˜์€ ๋„ˆ๋ฌด ์˜ค๋ฅ˜ ์—†์ด ์ž˜ ํ•ด๋ณด์—ฌ์„œ ํ•œ ์‹œ๊ฐ„๋™์•ˆ ๊ณ ๋ฏผํ•˜๋‹ค๊ฐ€ ์งˆ๋ฌธ๊ธ€๊นŒ์ง€ ๋‚จ๊ฒผ๋Š”๋ฐ ๋ฐ”๋กœ ๋‹ค์Œ ์˜์ƒ์— ์žˆ์–ด์„œ ๊ฐœํ—ˆ๋งํ•˜๊ณ  ๋ถ€๋„๋Ÿฌ์›Ÿ๋‹น. ๋‘๋ช… ๋ดค๋˜๋ฐ,,,. ์—ญ์‹œ ๊ฐ•์˜๋Š” ์ œ๋•Œ ์ž˜ ๋“ค์–ด์•ผ ํ•จ

'๐Ÿ•Š๏ธํ”„๋กœ๊ทธ๋ž˜๋จธ์Šค ๋ฐ๋ธŒ์ฝ”์Šค > ํ”„๋กœ์ ํŠธ' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

[๋ฐ๋ธŒ์ฝ”์Šค] ์žฅ๋ฐ”๊ตฌ๋‹ˆ ์กฐํšŒ api ๊ตฌํ˜„  (1) 2025.05.19
[๋ฐ๋ธŒ์ฝ”์Šค] ์ข‹์•„์š” api ๊ตฌํ˜„  (0) 2025.05.19
[๋ฐ๋ธŒ์ฝ”์Šค] ๋„์„œ ์กฐํšŒ API  (0) 2025.05.16
[๋ฐ๋ธŒ์ฝ”์Šค] ํšŒ์›๊ฐ€์ž…, ๋กœ๊ทธ์ธ ๊ตฌํ˜„  (0) 2025.05.15
[๋ฐ๋ธŒ์ฝ”์Šค] ๋ถ์Šคํ† ์–ด ํ”„๋กœ์ ํŠธ #1. app.js ๋ฐ ์œ ์ € api ๋ผ์šฐํ„ฐ ํ…œํ”Œ๋ฆฟ  (0) 2025.05.13
'๐Ÿ•Š๏ธํ”„๋กœ๊ทธ๋ž˜๋จธ์Šค ๋ฐ๋ธŒ์ฝ”์Šค/ํ”„๋กœ์ ํŠธ' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€
  • [๋ฐ๋ธŒ์ฝ”์Šค] ์žฅ๋ฐ”๊ตฌ๋‹ˆ ์กฐํšŒ api ๊ตฌํ˜„
  • [๋ฐ๋ธŒ์ฝ”์Šค] ์ข‹์•„์š” api ๊ตฌํ˜„
  • [๋ฐ๋ธŒ์ฝ”์Šค] ๋„์„œ ์กฐํšŒ API
  • [๋ฐ๋ธŒ์ฝ”์Šค] ํšŒ์›๊ฐ€์ž…, ๋กœ๊ทธ์ธ ๊ตฌํ˜„
ํ‚ํ‚์ž‰
ํ‚ํ‚์ž‰
๋ฟŒ๋ก ํŠธ ๊ฐœ๋ฐœ์ž(์ง€๋ง์ƒ)์˜ ํ’€์Šคํƒ ๊ฐœ๋ฐœ์ž ๋„์ „๊ธฐ
  • ํ‚ํ‚์ž‰
    monicx.dev
    ํ‚ํ‚์ž‰
  • ์ „์ฒด
    ์˜ค๋Š˜
    ์–ด์ œ
    • ๋ถ„๋ฅ˜ ์ „์ฒด๋ณด๊ธฐ (92) N
      • ๐Ÿ–ฅ๏ธdevelop (11)
        • Github (2)
        • Frontend (4)
        • Backend (5)
        • Mobile (0)
        • CS (0)
        • Three.js (0)
        • Docker (0)
      • ๐Ÿ“•review (17) N
        • ์ฑ… (10)
        • ํ–‰์‚ฌ (0)
        • ํšŒ๊ณ  (3) N
      • โญproject (5)
        • petiary (2)
        • ๆšŽ่ฉ  (0)
        • ์ธํ„ด (2)
      • ๐Ÿ˜ถ‍๐ŸŒซ๏ธalgorithm (0)
      • ๐Ÿ’กtips (1)
      • ๐Ÿ˜Ždaily (10)
      • ๐Ÿ•น๏ธgame (0)
      • ๐Ÿ•Š๏ธํ”„๋กœ๊ทธ๋ž˜๋จธ์Šค ๋ฐ๋ธŒ์ฝ”์Šค (47) N
        • TIL (26)
        • ํ”„๋กœ์ ํŠธ (15) N
        • ํšŒ๊ณ  (6)
  • ๋ธ”๋กœ๊ทธ ๋ฉ”๋‰ด

    • ํ™ˆ
    • ํƒœ๊ทธ
  • ๋งํฌ

    • ๋ฒจ๋กœ๊ทธ
  • ์ธ๊ธฐ ๊ธ€

  • ์ตœ๊ทผ ๊ธ€

  • hELLOยท Designed By์ •์ƒ์šฐ.v4.10.3
ํ‚ํ‚์ž‰
[๋ฐ๋ธŒ์ฝ”์Šค] ๋„์„œ ๋ชฉ๋ก ์กฐํšŒ ํŽ˜์ด์ง• ์ ์šฉ API
์ƒ๋‹จ์œผ๋กœ

ํ‹ฐ์Šคํ† ๋ฆฌํˆด๋ฐ”