</>
APIGuiden.se
REST12 min2026-03-05

REST API: Komplett guide till design och implementation

Lär dig bygga robusta REST-API:er med rätt HTTP-metoder, statuskoder och säkerhetsrutiner. Från grunderna till produktionsklar kod.

RESTHTTPAPI DesignBackend

Vad är ett REST API?

REST (Representational State Transfer) är en arkitekturstil för att bygga webbtjänster som kommunicerar via HTTP. Ett väldesignat REST-API använder resurser, HTTP-metoder och statuskoder på ett förutsägbart sätt. Till skillnad från äldre tekniker som SOAP erbjuder REST en enklare och mer flexibel approach som passar moderna webbapplikationer och mobilappar.

Grundprinciperna inkluderar statslöshet (varje request innehåller all nödvändig information), enhetliga gränssnitt (konsekvent URL-struktur och HTTP-metoder) och separation mellan klient och server. Dessa principer gör API:et skalbart och enkelt att underhålla.

endpoints.txt
http
// Grundläggande REST-endpoints
GET    /api/users          // Hämta alla användare
GET    /api/users/:id      // Hämta en specifik användare
POST   /api/users          // Skapa ny användare
PUT    /api/users/:id      // Uppdatera en användare
DELETE /api/users/:id      // Ta bort en användare

HTTP-metoder och statuskoder

Varje HTTP-metod har en specifik semantisk betydelse. GET hämtar data utan sidoeffekter, POST skapar nya resurser, PUT ersätter hela resursen och PATCH uppdaterar delar av den. DELETE tar bort resursen. Att använda rätt metod är avgörande för att API:et ska vara förutsägbart.

Statuskoder kommunicerar resultatet tillbaka till klienten. 2xx-koder indikerar framgång, 4xx-koder pekar på klientfel och 5xx-koder signalerar serverproblem. Använd alltid den mest specifika koden: 201 Created vid ny resurs, 204 No Content vid delete, 422 Unprocessable Entity vid valideringsfel.

routes/products.ts
typescript
// Express.js: CRUD-operationer med korrekta statuskoder
import express from "express";
const router = express.Router();

// GET - Hämta alla produkter
router.get("/products", async (req, res) => {
  const products = await db.products.findMany();
  res.status(200).json({ data: products });
});

// POST - Skapa ny produkt (201 Created)
router.post("/products", async (req, res) => {
  const product = await db.products.create({
    data: req.body,
  });
  res.status(201).json({ data: product });
});

// PUT - Uppdatera produkt (200 OK)
router.put("/products/:id", async (req, res) => {
  const product = await db.products.update({
    where: { id: req.params.id },
    data: req.body,
  });
  res.status(200).json({ data: product });
});

// DELETE - Ta bort produkt (204 No Content)
router.delete("/products/:id", async (req, res) => {
  await db.products.delete({
    where: { id: req.params.id },
  });
  res.status(204).send();
});

Autentisering och säkerhet

API-säkerhet börjar med autentisering. JSON Web Tokens (JWT) är standard för statslös autentisering. Varje request skickar med en token i Authorization-headern, som servern validerar utan att behöva lagra sessiondata.

Utöver autentisering behöver du rate limiting (för att förhindra missbruk), CORS-konfiguration (för att kontrollera vilka domäner som får anropa API:et) och input-validering (för att skydda mot injection-attacker). Använd alltid HTTPS i produktion.

middleware/auth.ts
typescript
// JWT-autentisering middleware
import jwt from "jsonwebtoken";

const authenticate = (req, res, next) => {
  const token = req.headers.authorization?.split(" ")[1];

  if (!token) {
    return res.status(401).json({
      error: "Ingen token angiven",
    });
  }

  try {
    const decoded = jwt.verify(token, process.env.JWT_SECRET);
    req.user = decoded;
    next();
  } catch {
    return res.status(403).json({
      error: "Ogiltig eller utgången token",
    });
  }
};

// Skyddad route
router.get("/profile", authenticate, async (req, res) => {
  const user = await db.users.findUnique({
    where: { id: req.user.id },
  });
  res.json({ data: user });
});

Paginering och filtrering

Ett produktions-API behöver paginering för att hantera stora datamängder effektivt. Cursor-baserad paginering (med en unik identifierare som startpunkt) är mer robust än offset-baserad, särskilt vid data som uppdateras frekvent. Filtrering och sortering ger klienten kontroll utan att exponera databasstrukturen.

routes/products.ts
typescript
// Cursor-baserad paginering
router.get("/products", async (req, res) => {
  const { cursor, limit = 20, sort = "createdAt" } = req.query;

  const products = await db.products.findMany({
    take: Number(limit) + 1,
    cursor: cursor ? { id: cursor } : undefined,
    orderBy: { [sort]: "desc" },
  });

  const hasMore = products.length > Number(limit);
  const data = hasMore ? products.slice(0, -1) : products;

  res.json({
    data,
    pagination: {
      hasMore,
      nextCursor: hasMore ? data[data.length - 1].id : null,
    },
  });
});

Letar du efter pålitlig hosting för dina API-projekt?

Kolla in mehosting.com