iT邦幫忙

2024 iThome 鐵人賽

DAY 18
0
Modern Web

Svelte 的奇妙冒險系列 第 18

[Svelte 的奇妙冒險] Day 18 - SvelteKit 中的路由 (3)

  • 分享至 

  • xImage
  •  

+server.ts

前幾天有提到 SvelteKit 是一個全端框架,也就是說它能夠寫一些簡單的 API ,關於 API 的路由控制也跟我們的頁面一樣都是跟資料夾的結構相關聯的。

在 SvelteKit 中是用 +server.ts 來做為 API 路由的檔案,寫法上跟 +page.ts+layout.ts 類似都是 export 一個特定名稱的 function

//in src/routes/api/random-number/+server.ts

import { error } from '@sveltejs/kit';
import type { RequestHandler } from './$types';

export const GET: RequestHandler = ({ url }) => {
	const min = Number(url.searchParams.get('min') ?? '0');
	const max = Number(url.searchParams.get('max') ?? '1');
	const d = max - min;
	if (isNaN(d) || d < 0) {
		error(400, 'min and max must be numbers, and min must be less than max');
	}
	const random = min + Math.random() * d;
	return new Response(String(random));
};

除了 GET 還能使用 POSTPATCHPUTDELETEOPTIONSHEAD 這些常見的 HTTP 的 request method 。

接下來我們就可以直接到 http://localhost:5173/api/random-number 看一下能否成功打 API 。

傳入 params http://localhost:5173/api/random-number?min=1&max=3

如果我們刻意的讓它觸發錯誤也能夠成功顯示錯誤頁面

要在 Svelte component 中使用它的話也很簡單,只需要跟平常打 API 一樣 fetch(/api/random-number) 就可以了。

<!-- in src/routes/day18/+page.svelte  -->
<script lang="ts">
	let min = $state(0);
	let max = $state(100);
	const getRandomNumber = async ({ min, max }: { min: number; max: number }): Promise<number> => {
		return fetch(`/api/random-number?min=${min}&max=${max}`).then((x) => x.json());
	};
</script>

<h1>Day18</h1>

<div class="flex gap-6 w-1/2">
	<label for="min">
		Min: {min}

		<input type="range" min="0" max="100" bind:value={min} class="range" />
	</label>
	<label for="max">
		Max: {max}

		<input type="range" min="0" max="100" bind:value={max} class="range" />
	</label>
</div>

{#await getRandomNumber({ min, max }) then number}
	<p>Random number: {number}</p>
{:catch error}
	<p style="color: red;">{error.message}</p>
{/await}

但如果刻意觸發錯誤,會發現根本沒有進到 {:catch} ,這是因為 error 設計上都是 return { message: string } 的物件,所以我們在外部 catch 不到它的,雖然我覺得這樣子反而更不方便使用就是了。

所以如果我們還是要在 +page.svelte catch 到錯誤我們只能這麼做

	const getRandomNumber = async ({ min, max }: { min: number; max: number }): Promise<number> => {
		const response = await fetch(`/api/random-number?min=${min}&max=${max}`);

		if (response.ok) {
			return response.json();
		}

		const error = await response.json();

		throw new Error(error.message);
	};


參考資料

source code


上一篇
[Svelte 的奇妙冒險] Day 17 - SvelteKit 中的路由 (2)
下一篇
[Svelte 的奇妙冒險] Day 19 - SvelteKit 中的路由 (4)
系列文
Svelte 的奇妙冒險30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言