Hoppa till huvudinnehåll

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
Varför börja här? 🤔

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
}
Start enkelt! 💡

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å:

  1. Få GET endpoint att fungera

    • Returnera alla todos som JSON
    • Testa i browsern: /api/todos
  2. Få POST endpoint att fungera

    • Ta emot JSON från request body
    • Skapa ny todo och returnera den
  3. Koppla ihop frontend och backend

    • Visa todos från ditt API
    • Lägg till nya todos via formulär

Mellannivå:

  1. Lägg till PUT endpoint (src/routes/api/todos/[id]/+server.ts)

    • Uppdatera befintlig todo
    • Hantera om todo inte finns
  2. Lägg till DELETE endpoint (samma fil)

    • Ta bort todo
    • Returnera lämplig status
  3. Förbättra frontend

    • Knapp för att markera som klar/inte klar
    • Ta bort-funktion
    • Felhantering med try/catch

Expertnivå:

  1. 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 (inte server.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!)
Du bygger riktig fullstack-kompetens! 💪

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 📚