Skapa egna API endpoints 🔌
Modulsmål 🎯
Efter denna modul kan du:
- ✅ Bygga egna API endpoints med
+server.ts
- ✅ Hantera HTTP methods: GET, POST, PUT, DELETE
- ✅ Returnera JSON responses och hantera fel
- ✅ Förstå vad som händer "under huven" innan vi lär oss SvelteKit:s shortcuts
- ✅ Integrera frontend och backend på riktigt
I förra modulen använde du fetch()
för att prata med andras API:er. Nu bygger du dina egna! Detta ger dig förståelsen för vad som händer bakom kulisserna innan vi lär oss SvelteKit:s "magiska" shortcuts.
Vad är en API endpoint? 🌐
En endpoint är en URL på din server som kan ta emot requests och skicka tillbaka data:
GET /api/todos → Hämta alla todos
POST /api/todos → Skapa ny todo
PUT /api/todos/123 → Uppdatera todo 123
DELETE /api/todos/123 → Ta bort todo 123
SvelteKit:s +server.ts magi ✨
I SvelteKit skapar du API endpoints genom att skapa +server.ts
filer:
src/routes/
├── api/
│ ├── todos/
│ │ ├── +server.ts # /api/todos
│ │ └── [id]/
│ │ └── +server.ts # /api/todos/123
│ └── users/
│ └── +server.ts # /api/users
Projekt: Todo API Backend 📝
Vi bygger en komplett todo-API som du sedan kan använda med fetch från frontend!
Steg 1: Skapa projektet 🛠️
npm create svelte@latest todo-api
cd todo-api
npm install
npm run dev
Steg 2: Grundläggande datalagring 💾
Skapa src/lib/todo-store.ts
:
// src/lib/todo-store.ts
export type Todo = {
id: number;
text: string;
completed: boolean;
createdAt: Date;
};
let todos: Todo[] = [];
let nextId = 1;
export function getAllTodos(): Todo[] {
// Din kod här - returnera alla todos
}
export function getTodoById(id: number): Todo | undefined {
// Din kod här - hitta specifik todo
}
export function createTodo(text: string): Todo {
// Din kod här - skapa ny todo och lägg till i listan
}
export function updateTodo(id: number, updates: Partial<Todo>): Todo | null {
// Din kod här - uppdatera befintlig todo
}
export function deleteTodo(id: number): boolean {
// Din kod här - ta bort todo, returnera true/false
}
Använd bara arrays i minnet först. Databaser kommer senare!
Steg 3: GET endpoint - Lista todos 📥
Skapa src/routes/api/todos/+server.ts
:
// src/routes/api/todos/+server.ts
import { json } from '@sveltejs/kit';
import type { RequestHandler } from './$types';
// Importera dina funktioner här
export const GET: RequestHandler = async () => {
// Din kod här
// Tips: använd getAllTodos() och returnera json(...)
};
Testa det! Gå till http://localhost:5173/api/todos
i browsern
Steg 4: POST endpoint - Skapa todos ✏️
Lägg till i samma fil:
// Fortsättning i +server.ts
export const POST: RequestHandler = async ({ request }) => {
// Få JSON-data från request body
const body = await request.json();
// Validera input
if (!body.text || typeof body.text !== 'string') {
// Returnera fel - använd json() med status
}
// Skapa todo
// Returnera den nya todon som JSON
};
Steg 5: Frontend som använder ditt API 🎨
Skapa src/routes/+page.svelte
:
<!-- src/routes/+page.svelte -->
<script>
import { onMount } from 'svelte';
let todos = [];
let newTodoText = '';
let loading = false;
// Ladda todos när sidan laddas
onMount(async () => {
await loadTodos();
});
async function loadTodos() {
// Din kod här - fetcha från /api/todos
// Tips: samma som i modul 1, men nu från ditt eget API!
}
async function addTodo() {
if (!newTodoText.trim()) return;
loading = true;
try {
// Din kod här - POST till /api/todos
// Skicka { text: newTodoText } som JSON
// Kom ihåg headers: { 'Content-Type': 'application/json' }
// Efter framgång:
newTodoText = '';
await loadTodos(); // Ladda om listan
} catch (error) {
console.error('Fel:', error);
} finally {
loading = false;
}
}
</script>
<h1>Min Todo App med eget API! 🚀</h1>
<!-- Formulär för ny todo -->
<div>
<input
bind:value={newTodoText}
placeholder="Vad ska du göra?"
disabled={loading}
/>
<button on:click={addTodo} disabled={loading}>
{loading ? 'Sparar...' : 'Lägg till'}
</button>
</div>
<!-- Lista todos -->
{#if todos.length > 0}
<ul>
{#each todos as todo}
<li>
{todo.text}
{#if todo.completed}✅{/if}
</li>
{/each}
</ul>
{:else}
<p>Inga todos än!</p>
{/if}
HTTP Status Codes 📊
Lär dig använda rätt statuskoder:
// Framgång
return json(data); // 200 OK (default)
return json(newTodo, { status: 201 }); // 201 Created
// Fel
return json({ error: 'Not found' }, { status: 404 }); // 404 Not Found
return json({ error: 'Bad input' }, { status: 400 }); // 400 Bad Request
return json({ error: 'Server error' }, { status: 500 }); // 500 Internal Error
Utmaningar att lösa själv 💪
Grundnivå:
-
Få GET endpoint att fungera
- Returnera alla todos som JSON
- Testa i browsern:
/api/todos
-
Få POST endpoint att fungera
- Ta emot JSON från request body
- Skapa ny todo och returnera den
-
Koppla ihop frontend och backend
- Visa todos från ditt API
- Lägg till nya todos via formulär
Mellannivå:
-
Lägg till PUT endpoint (
src/routes/api/todos/[id]/+server.ts
)- Uppdatera befintlig todo
- Hantera om todo inte finns
-
Lägg till DELETE endpoint (samma fil)
- Ta bort todo
- Returnera lämplig status
-
Förbättra frontend
- Knapp för att markera som klar/inte klar
- Ta bort-funktion
- Felhantering med try/catch
Expertnivå:
- Avancerad funktionalitet
- Filtrera todos (completed/incomplete)
- Sortering (datum, alfabetisk)
- Bulk operations (markera alla som klara)
Viktiga koncept 🧠
1. HTTP Methods
export const GET: RequestHandler = async () => { ... }; // Hämta data
export const POST: RequestHandler = async () => { ... }; // Skapa data
export const PUT: RequestHandler = async () => { ... }; // Uppdatera data
export const DELETE: RequestHandler = async () => { ... }; // Ta bort data
2. Request handling
export const POST: RequestHandler = async ({ request, params, url }) => {
// JSON body
const data = await request.json();
// URL params (/api/todos/[id])
const id = params.id;
// Query params (?filter=completed)
const filter = url.searchParams.get('filter');
};
3. Response types
// JSON response (vanligast)
return json({ message: 'Success' });
// Plain text
return new Response('Hello world');
// Med custom headers
return json(data, {
status: 201,
headers: { 'X-Custom': 'value' }
});
Vanliga problem 🔧
❌ "404 Not Found" på API endpoints
Kontrollera:
- Filen heter
+server.ts
(inteserver.ts
) - Mappstrukturen stämmer
- Servern är igång (
npm run dev
)
❌ "SyntaxError: Unexpected token" i JSON
Lösning:
// ✅ Rätt Content-Type
fetch('/api/todos', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ text: 'My todo' })
});
❌ CORS-fel när du testar
Vanligtvis inga problem i SvelteKit development, men kolla att du använder relativa URLs (/api/todos
, inte http://localhost:5173/api/todos
)
Debugging Tips 🔍
export const POST: RequestHandler = async ({ request }) => {
console.log('POST request received!');
const body = await request.json();
console.log('Request body:', body);
// Din logik här
console.log('Sending response...');
return json(result);
};
Kolla terminalen för server-loggar!
Varför denna approach? 🎓
Efter denna modul förstår du:
- Hur HTTP requests fungerar på riktigt
- Vad en REST API är och hur du bygger en
- Request/Response cycle mellan frontend och backend
- Varför SvelteKit:s shortcuts är användbara (nästa modul!)
Detta är samma sätt som stora företag bygger API:er. Du lär dig industri-standard patterns!
Nästa steg 🚀
I nästa modul lär vi oss SvelteKit:s load functions och form actions - men nu förstår du vad som händer bakom kulisserna! Du kommer att uppskatta hur mycket enklare det blir.
Resurser 📚
- SvelteKit API Routes: kit.svelte.dev/docs/routing#server
- HTTP Status Codes: developer.mozilla.org/en-US/docs/Web/HTTP/Status
- REST API Design: restfulapi.net