# [Nuxt] Nuxt 3 - Server ###### tags: `Nuxt` * 支援 HMR 的 API 和 server handlers:`server/api`、`server/routes`、`server/middleware` * 每個檔案都要 export `defineEventHandler()` 或 `eventHandler()`(別名) * 可以直接 return JSON 資料、`Promise` 或使用 `event.node.res.end()` ## `server/api` * 有前綴 `/api` * 範例:`server/api/user.js` 的路徑為 `/api/user` * 檔名可以加上 `get` / `post` / `delete` / `put` 等等匹配 HTTP Method * 範例:`user.get.js`、`user.post.js` * 若以沒寫到的 Method 發送請求會顯示 405 Method Not Allowed * 動態參數:檔名以 `[]` 包住參數名稱 ```javascript // server/api/user/[name].js export default defineEventHandler((event) => { const name = getRouterParam(event, 'name'); // ... return { // ... }; }); ``` ## `server/routes` * 用途和 `server/api` 一樣,但無前綴 * 範例:`server/routes/user.js` 的路徑為 `/user` * 若檔名和 `pages/` 內的檔案相同,在點擊 `NuxtLink` 的連結會顯示 `pages/` 內同檔名的頁面,在網址列直接輸入網址則會顯示 `server/routes/` 內同檔名的 return 內容 ## `server/middleware` * 攔截 `server/` 所有 Request * 不應回傳任何內容,也不能中斷或回應請求,只能檢查或增加 `request context` 或拋出錯誤 ## `server/plugins` * 會自動註冊為 Nitro plugins ## `server/utils` * 可以添加更多 helper ## Server Types :::warning Nuxt 版本 >= 3.5 ::: ## 使用範例 ### 取得 Request 的 Query Parameters 使用 `getQuery(event: H3Event)` ```javascript <script setup> const { data } = await useFetch('/api/user', { query: { id: route.params.id } }); </script> ``` ```javascript export default defineEventHandler((event) => { const query = getQuery(event); const id = query.id; // ... return { // ... }; }); ``` ### 取得 Request 的 Body 使用 `readBody(event: H3Event)` ```javascript <script setup> const { data } = await useFetch('/api/user', { method: 'post', body: { id: '1234', name: 'Ann', }, }); </script> ``` ```javascript export default defineEventHandler(async (event) => { const body = await readBody(event); console.log(body); // { id: '1234', name: 'Ann' } return { // ... }; }); ``` :::warning 若在 Get Request 使用 `readBody` 會拋錯 405 Method Not Allowed ::: ### 處理錯誤 * 若沒錯誤,會返回 status code 200 * 任何未捕獲的錯誤會返回 status code 500 * 要返回其他錯誤代碼,使用 `createError` ```typescript export default defineEventHandler((event) => { const id = parseInt(event.context.params.id) as number; if (!Number.isInteger(id)) { throw createError({ statusCode: 400, statusMessage: 'ID should be an integer', }) } return 'All good'; }); ``` ### 返回其他 status codes :::info * [Returning other status codes](https://nuxt.com/docs/guide/directory-structure/server#returning-other-status-codes "server/ · Nuxt Directory Structure") * [setResponseStatus](https://nuxt.com/docs/api/utils/set-response-status "setResponseStatus · Nuxt Utils") ::: * 使用 `setResponseStatus(event: H3Event, code?: number | undefined, text?: string | undefined)` * 只能在 setup functions、plugins 和 route middleware 內調用 ```javascript export default defineEventHandler((event) => { setResponseStatus(event, 202); }); ``` ```javascript const event = useRequestEvent(); setResponseStatus(event, 404, 'Page Not Found'); ``` ### 取得 Runtime Config 使用 `useRuntimeConfig(event?: H3Event | undefined)` ### 取得 Request Cookies 使用 `parseCookies(event: H3Event)` ## 參考資料 * [官方文件](https://nuxt.com/docs/guide/directory-structure/server "server/ · Nuxt Directory Structure") --- :::info 建立日期:2023-08-31 更新日期:2023-09-01 :::