# 🏅 Day 20 - 建立 API 與整合 TypeORM 查詢
## 設計 GET 和 POST API 路由。
API 是用來在客戶端與伺服器之間進行溝通的橋樑。
GET 請求:用於從伺服器取得資料,例如取得特定表中的所有記錄或特定條件的記錄。
POST 請求:用於將資料新增到伺服器,例如向特定表中插入一筆新的記錄。
設計 API 的基本步驟:
1. 確定 API 的路由結構,例如:/api/credit-package。
2. 確定使用的 HTTP 方法,例如:GET、POST。
3. 根據需求,撰寫相應的處理邏輯(例如資料庫操作、資料處理等)。
## 使用 TypeORM 進行資料查詢與新增
資料查詢(find 方法):
使用 TypeORM 的 Repository 提供的方法可以輕鬆查詢資料,例如:
1. find():查詢所有記錄,並可選擇特定欄位。
2. findOne():查詢符合條件的一筆記錄。
## 舉例說明
GET 請求,取得所有 CreditPackage 資料:
```
if (req.url === "/api/credit-package" && req.method === "GET") {
try {
const purchases = await AppDataSource.getRepository("CreditPackage").find({
select: ["id", "name", "credit_amount", "price"], // 指定需要的欄位
});
res.writeHead(200, { "Content-Type": "application/json" }); // 設定回應標頭
res.write(
JSON.stringify({
status: "success",
data: purchases, // 回傳資料
})
);
res.end(); // 結束回應
} catch (error) {
res.writeHead(500, { "Content-Type": "application/json" });
res.write(
JSON.stringify({
status: "error",
message: error.message, // 錯誤訊息
})
);
res.end();
}
}
```
POST 請求,新增一筆 CreditPackage 資料:
```
if (req.url === "/api/credit-package" && req.method === "POST") {
let body = "";
req.on("data", (chunk) => {
body += chunk; // 取得請求中的資料
});
req.on("end", async () => {
try {
const { name, credit_amount, price } = JSON.parse(body); // 解析請求中的 JSON 資料
const newCreditPackage = {
name,
credit_amount,
price,
};
const result = await AppDataSource.getRepository("CreditPackage").save(
newCreditPackage
); // 將資料新增到資料庫
res.writeHead(201, { "Content-Type": "application/json" }); // 設定回應標頭
res.write(
JSON.stringify({
status: "success",
data: result, // 回傳新增的資料
})
);
res.end();
} catch (error) {
res.writeHead(500, { "Content-Type": "application/json" });
res.write(
JSON.stringify({
status: "error",
message: error.message, // 錯誤訊息
})
);
res.end();
}
});
}
```
## 題目
建立一組新的 API,整合 typeorm 與資料庫的 Skill 表。
1.GET /api/skill,功能:查詢並回傳所有 Skill 資料,包含 id 和 name 欄位。
2.POST /api/skill,功能:新增一筆 Skill 資料。
( 請求 body 應包含:name:技能名稱,string 格式 )
回報區
---
| # | Discord | CodePen / 答案 |
| -------- | -------- | -------- |
| 01 | helena | [CodePen](https://codepen.io/helena27/pen/gbYVZvw) |
| 02 | poyi | [CodePen](https://codepen.io/poyi-the-flexboxer/pen/ogvKWVo) |
| 03 | Tau | [CodePen](https://codepen.io/Tau-Hsu/pen/EaxYPWd?editors=0010) |
| 04 | adengg | [CodePen](https://codepen.io/Osases/pen/bNGbBEL?editors=0010) |
| 05 | sian | [CodePen](https://codepen.io/uxitysjl-the-flexboxer/pen/wBvwoXE?editors=0010) |
| 06 | JC | [CodePen](https://codepen.io/lifetimingwhisper/pen/vEBoMJO)
| 07 | hananhpun | [CodePen](https://codepen.io/hannahpun/pen/XJrvoyG)
|08|janetlai|[Codepen](https://codepen.io/eiddkqxz-the-builder/pen/wBvwjez?editors=1010)
|09| sui_hsilan|[Codepen](https://codepen.io/suihsilan/pen/dPyyPLb?editors=0010)
|10 | hsin yu | [CodePen](https://codepen.io/tina2793778/pen/YPzzwNM) |
|11 |ZoeKang|[CodePen](https://codepen.io/byehywmx-the-animator/pen/myddOoB?editors=0010)
| 12 | bian_yang_mofa | [CodePen](https://codepen.io/cssf998811/pen/ByaaGjP?editors=0010) |
| 13 | yutzu | [CodePen](https://codepen.io/dtafsrmf-the-lessful/pen/OPJPmZg?editors=0010) |
| 14 | JerryOOO | [CodePen](https://codepen.io/fatiangel/pen/dPyMPWN?editors=0010) |
| 15 | HarryKuo | [CodePen](https://codepen.io/harry_kuo/pen/qEBqrwW?editors=0010) |
|16|wuyuli_21403| [CodePen](https://codepen.io/Job-Wilhelm/pen/ogNwzEE) |
|17|shiang| [CodePen](https://codepen.io/shiang29/pen/bNGLdqj?editors=1010) |
<!-- 可複製下方格式
| | | [CodePen]() |
-->
<!-- 解答:
1.GET /api/skill,功能:查詢並回傳所有 Skill 資料,包含 id 和 name 欄位。
if (req.url === "/api/skill" && req.method === "GET") {
try {
const skill = await AppDataSource.getRepository("Skill").find({
select: ["id", "name"]
})
res.writeHead(200, headers)
res.write(JSON.stringify({
status: "success",
data: skill
}))
res.end()
} catch (error) {
res.writeHead(500, headers)
res.write(JSON.stringify({
status: "error",
message: "伺服器錯誤"
}))
res.end()
}
}
2. POST /api/skill,功能:新增一筆 Skill 資料。
if (req.url === "/api/skill" && req.method === "POST") {
let body = "";
req.on("data", (chunk) => {
body += chunk;
});
req.on("end", async () => {
try {
const data = JSON.parse(body);
if (!data.name || typeof data.name !== "string" || data.name.trim() === "") {
res.write(
JSON.stringify({
status: "failed",
message: "欄位未填寫正確",
})
);
res.end();
return;
}
const skillRepo = await AppDataSource.getRepository("Skill");
const existSkill = await skillRepo.findOne({
where: { name: data.name },
});
if (existSkill) {
res.writeHead(409, { "Content-Type": "application/json" });
res.write(
JSON.stringify({
status: "failed",
message: "資料重複",
})
);
res.end();
return;
}
const newSkill = skillRepo.create({ name: data.name });
const result = await skillRepo.save(newSkill);
res.write(
JSON.stringify({
status: "success",
data: result,
})
);
res.end();
} catch (error) {
console.error(error);
res.write(
JSON.stringify({
status: "error",
message: error.message || "伺服器錯誤",
})
);
res.end();
}
});
}
-->