Hvordan du stopper med at være bange for REST API’er

Hvordan du stopper med at være bange for REST API'er

Jeg troede jeg havde ødelagt hele internettet

Første gang jeg skulle kalde et REST API, sad jeg og stirrede på dokumentationen i en time og tænkte: “Det her er jo ikke skrevet til mennesker”. Jeg copy-pastede en tilfældig URL, trykkede enter i browseren, fik en kryptisk fejl og var 90 % sikker på, jeg lige havde ødelagt noget på en server et sted.

Jeg havde ikke ødelagt noget. Jeg havde bare ingen proces. Jeg læste docs som en roman i stedet for som et slags opslagsværk, og jeg anede ikke, hvad jeg skulle kigge efter først.

I dag gør jeg det anderledes: hver gang jeg møder et nyt REST API, følger jeg nogle faste trin. Det er dem, jeg vil gå igennem med dig nu, så du kan gå fra “hvad er en API?” til “jeg kan faktisk få noget data ud af det her” uden at stresse.

Hvad er en REST API i én brugbar sætning?

Der findes mange definitioner, men den jeg selv bruger, når jeg skal forklare det til venner, er:

Et REST API er en aftalt måde, hvor din kode kan spørge en anden server: “giv mig data” eller “ændr data” via URL’er og HTTP-metoder.

Du sender en request (en forespørgsel) til en bestemt adresse (endpoint), og du får et response (svar) tilbage. Svarene er typisk i JSON-format, som ligner JavaScript-objekter.

Et meget simpelt eksempel på en request kunne være:

GET https://api.example.com/users

Her siger du i bund og grund: “Kære server, brug metoden GET til at hente alle brugere fra /users”.

Sådan aflæser du en API-dokumentation uden at drukne

Dokumentation til et REST API kan se kaotisk ud, men de fleste følger samme grundstruktur. Jeg kigger altid efter de samme ting i denne rækkefølge.

1. Base URL

Base URL er den grundadresse, alle endpoints bygger videre på. For eksempel:

Base URL: https://api.example.com/v1

Hvis dokumentationen så viser et endpoint som /users, ved du, at den fulde URL er:

https://api.example.com/v1/users

Typisk står base URL øverst eller under et “Getting started”-afsnit.

2. Endpoints

Endpoints er de “stier” du kan ramme. De beskrives ofte som tabeller eller små bokse:

GET /users
GET /users/{id}
POST /users
DELETE /users/{id}

Her er mønstret:

  • /users er samling af brugere
  • /users/{id} er én specifik bruger, hvor {id} er en variabel, du skal erstatte med et rigtigt id, fx /users/42

3. Parametre

Parametre er ekstra info, du kan sende med i URL’en eller i body’en. De typiske typer:

  • Path parametre: en del af selve stien, fx /users/42
  • Query parametre: efter ? i URL’en, fx /users?role=admin&limit=10
  • Body: data du sender i selve requesten, typisk ved POST/PUT

I dokumentationen står der ofte noget som:

GET /search
Query parameters:
  q (string, required) - søgetekst
  limit (integer, optional) - max antal resultater

Det betyder, at en gyldig URL kunne være:

GET /search?q=katte&limit=5

4. Auth (godkendelse)

Langt de fleste API’er kræver, at du identificerer dig selv. Det sker typisk med:

  • API-nøgle (API key)
  • Bearer token
  • OAuth (lidt mere avanceret flow)

Det vigtige for dig er: hvor nøglen skal placeres. Det skriver dokumentationen som regel under “Authentication”. Det kan fx være:

Authorization: Bearer <YOUR_API_KEY>

eller som query parameter:

?api_key=DIN_NØGLE

Hvis du får mange 401- og 403-fejl (vi kommer til koderne om lidt), er auth et godt sted at kigge først.

5. Rate limits

Rate limits er grænser for, hvor mange requests du må sende per minut/time/dag. Det står ofte som:

You can make up to 60 requests per minute.

Hvis du spammer et API for hårdt, får du typisk fejlkoden 429. Mere om det i statuskode-afsnittet.

HTTP-metoder i praksis: GET, POST, PUT, PATCH, DELETE

HTTP-metoder er lidt som “verberne” i API-sproget. De vigtigste fem:

  • GET – hent data
  • POST – opret noget nyt
  • PUT – erstat hele ressourcen
  • PATCH – opdatér dele af ressourcen
  • DELETE – slet ressourcen

Lad os sige, vi har et todo-API. Typiske kald kunne være:

GET    /todos           // hent alle todos
GET    /todos/1         // hent todo med id 1
POST   /todos           // opret ny todo
PUT    /todos/1         // erstat todo 1 med ny version
PATCH  /todos/1         // opdatér kun nogle felter på todo 1
DELETE /todos/1         // slet todo 1

Det er ret logisk, når man først har set det i et par API’er. Det gode er, at denne struktur går igen stort set overalt.

Statuskoder: din hurtige fejlsøgnings-radar

HTTP-statuskoder er tal, som serveren sender tilbage for at fortælle, hvordan det gik. Her er en lille “oversættelse” af de mest almindelige:

  • 200 OK – alt gik godt, her er dit svar
  • 201 Created – noget blev oprettet
  • 400 Bad Request – din request er forkert formet (mangler felter, ugyldig JSON, osv.)
  • 401 Unauthorized – du mangler auth eller din nøgle/token er forkert
  • 403 Forbidden – du er logget ind, men har ikke lov til det du prøver
  • 404 Not Found – endpointet findes ikke, eller id’et du bruger gør ikke
  • 429 Too Many Requests – du har ramt rate limit, ro på
  • 500 Internal Server Error – noget gik galt på serveren

En simpel måde at bruge dem på, når du fejlsøger:

  • 4xx-fejl: kig på din request (URL, body, auth)
  • 5xx-fejl: problemet er oftest på serveren, prøv igen eller tjek status-siden

Trin for trin: din første API-request med et værktøj

Før jeg skriver kode, tester jeg næsten altid API’et i et værktøj. Mange bruger Postman, men hvis du vil have noget lettere, kan du prøve fx Thunder Client (en VS Code extension) eller bare curl i terminalen.

Eksempel med curl

Forestil dig, at dokumentationen siger:

Base URL: https://api.example.com/v1
GET /users
Authentication: API key in header: X-API-Key: <YOUR_KEY>

Så kunne en request med curl se sådan ud:

curl -X GET "https://api.example.com/v1/users" 
  -H "X-API-Key: DIN_API_NØGLE"

Hvis alt virker, får du et svar tilbage i JSON, fx:

[
  { "id": 1, "name": "Ida" },
  { "id": 2, "name": "Sara" }
]

Når du først har et fungerende eksempel i et værktøj, er det meget nemmere at oversætte til JavaScript.

JSON: formatet du næsten altid møder

Næsten alle moderne REST API’er svarer med JSON (JavaScript Object Notation). Det ligner JavaScript-objekter, men med et par regler:

  • Nøgler er i anførselstegn
  • Ingen trailing kommaer

Eksempel på JSON:

{
  "id": 1,
  "title": "Lær REST API'er",
  "done": false
}

Når du sender data til et API (fx med POST), bruger du ofte også JSON. Dokumentationen viser normalt både et eksempel på body og response.

Brug et REST API fra JavaScript med fetch

Nu til det sjove: at kalde et API direkte fra din frontend. Moderne browsere har fetch indbygget, som du kan bruge til at lave HTTP-requests.

Simpel GET-request

Vi starter med det mest basale: hent data og vis det i konsollen.

fetch('https://api.example.com/v1/users')
  .then(response => response.json())
  .then(data => {
    console.log(data);
  })
  .catch(error => {
    console.error('Noget gik galt', error);
  });

Her sker der tre ting:

  • fetch sender en GET-request
  • response.json() læser svaret som JSON
  • data er dit parse-de JSON-objekt/array

Med fejlhåndtering og statuskoder

fetch kaster ikke automatisk fejl ved 4xx/5xx. Det er lidt snyd. Så vi skal selv tjekke response.ok.

fetch('https://api.example.com/v1/users')
  .then(response => {
    if (!response.ok) {
      // Her kan du logge statuskoden
      console.error('Statuskode:', response.status);
      throw new Error('Request fejlede med status ' + response.status);
    }
    return response.json();
  })
  .then(data => {
    console.log('Brugere:', data);
  })
  .catch(error => {
    console.error('Fejl i fetch:', error.message);
  });

Nu har du både data og en klar fejlmelding, hvis noget går galt.

POST-request med JSON-body

Lad os sige, dokumentationen for at oprette en todo siger:

POST /todos
Body (JSON):
{
  "title": "string",
  "done": boolean
}

Så kunne en JavaScript-request se sådan ud:

const newTodo = {
  title: 'Lær REST API'er',
  done: false
};

fetch('https://api.example.com/v1/todos', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-API-Key': 'DIN_API_NØGLE'
  },
  body: JSON.stringify(newTodo)
})
  .then(response => {
    if (!response.ok) {
      throw new Error('Fejl: ' + response.status);
    }
    return response.json();
  })
  .then(createdTodo => {
    console.log('Oprettet todo:', createdTodo);
  })
  .catch(error => {
    console.error(error);
  });

Bemærk to ting her:

  • Body skal være stringified med JSON.stringify
  • Content-Type skal typisk sættes til application/json

Sikkerhed: API-nøgler og hvorfor de ikke hører til i frontend

Nu en hurtig (men vigtig) sikkerhedssnak. Mange API’er bruger nøgler, som giver adgang til din konto eller dine data. Hvis du skriver den nøgle direkte i din frontend, kan alle, der åbner din side, i princippet se den.

Tommelregel: API-nøgler, der giver adgang til noget følsomt, hører til på serveren, ikke i browseren.

Typisk løsning:

  • Din frontend kalder din egen backend (fx et lille Node.js API)
  • Backenden kalder tredjeparts-API’et med nøglen
  • Backenden sender kun det nødvendige data videre til frontenden

Hvis du kun leger med åbne, offentlige API’er uden login og uden persondata (fx et kattebillede-API), er det mindre kritisk. Men hvis du vil lave noget seriøst, skal du have backend med i billedet.

Hvis du er nysgerrig på at bygge små backend-endpoints, kan du på et tidspunkt kigge på simple Node.js-projekter eller frameworks som Express og kombinere det med det, du allerede kan fra frontend. Vi har fx indhold om webudvikling og full stack, der giver et godt næste skridt.

Mini-case: lille søge-UI der kalder et API

Nu samler vi det hele i et mini-projekt. Vi laver en simpel søgeboks, der kalder et (fiktivt) bog-API og viser resultater på siden.

Forudsætninger

  • Et åbent API, fx:
GET https://api.example.com/v1/books/search?q=<QUERY>
  • Response (JSON):
[
  { "title": "Eloquent JavaScript", "author": "Marijn Haverbeke" },
  { "title": "You Don't Know JS", "author": "Kyle Simpson" }
]

HTML

<input id="search-input" placeholder="Søg efter bog" />
<button id="search-btn">Søg</button>
<div id="results"></div>

JavaScript

const input = document.getElementById('search-input');
const button = document.getElementById('search-btn');
const resultsDiv = document.getElementById('results');

button.addEventListener('click', () => {
  const query = input.value.trim();
  if (!query) {
    resultsDiv.textContent = 'Skriv noget at søge på.';
    return;
  }

  resultsDiv.textContent = 'Søger...';

  const url = `https://api.example.com/v1/books/search?q=${encodeURIComponent(query)}`;

  fetch(url)
    .then(response => {
      if (!response.ok) {
        throw new Error('Fejl: ' + response.status);
      }
      return response.json();
    })
    .then(books => {
      if (!books.length) {
        resultsDiv.textContent = 'Ingen resultater.';
        return;
      }

      resultsDiv.innerHTML = '';

      books.forEach(book => {
        const p = document.createElement('p');
        p.textContent = `${book.title} - ${book.author}`;
        resultsDiv.appendChild(p);
      });
    })
    .catch(error => {
      resultsDiv.textContent = 'Noget gik galt. Prøv igen.';
      console.error(error);
    });
});

Her har du:

  • En simpel UI
  • En GET-request med query-parameter
  • Brug af JSON-response direkte i DOM’en
  • Basic fejltekster til brugeren

Hvis du vil lege videre, kan du prøve at style det med CSS, tilføje loading-animation eller debounce input, så den ikke kalder API’et ved hvert eneste tastetryk.

En lille proces du kan bruge hver gang

Hvis du gerne vil gøre “REST API for begyndere” til noget, du faktisk føler dig tryg i, så kan du bruge denne mini-tjekliste næste gang du møder et nyt API:

  • Find base URL og ét simpelt GET-endpoint
  • Tjek om der kræves auth, og hvordan den sendes
  • Test endpointet i et værktøj (curl, Thunder Client, Postman)
  • Notér et fungerende request-eksempel
  • Oversæt det til fetch i JavaScript
  • Læg statuskoderne i konsollen, så du ser hvad der sker ved fejl

Hvis du kun gør én ting anderledes efter at have læst det her, så lad det være at tage ét offentligt API, åbne dokumentationen, finde et simpelt GET-endpoint og få det til at virke i enten et værktøj eller med fetch. Bare det ene lille gennembrud gør resten utrolig meget mindre skræmmende.

Ida Balslev er den type ven, der pludselig dukker op i din messenger med et link til en lille web-app, hun lige har bygget for sjov – og bagefter gerne viser dig, hvordan du selv kan lave den. Hendes passion for kodning startede med en hjemmebygget hjemmeside til en hestestald og er langsomt vokset gennem aftener med tutorials, fejlmeldinger og små, hjemmelavede projekter.

På Codingclass.dk deler Ida den viden, hun selv manglede i starten: konkrete eksempler, tydelige forklaringer og ærlige historier om, hvad der typisk går galt første, anden og tredje gang. Hun elsker at tage et abstrakt begreb som fx "API" eller "asynkron JavaScript" og koge det ned til noget, du kan se, klikke på og lege med i browseren. For hende handler kodning ikke om at være perfekt, men om at turde prøve, bryde ting og bygge dem op igen.

Ida skriver især om webudvikling med HTML, CSS og JavaScript, små Python-scripts og grundlæggende koncepter som debugging, versionsstyring og struktur i din kode. Hun tænker altid i næste skridt: når du først forstår idéen, viser hun dig, hvordan du kan udvide det med en ekstra funktion, lidt pænere styling eller en smartere måde at tænke din kode på.

Gennem sine artikler på Codingclass.dk vil Ida gerne give dig følelsen af, at du ikke sidder alene med koden – men at der faktisk er en, der har kæmpet med de samme fejlmeddelelser og nu gerne vil vise dig en vej igennem dem, i et tempo hvor alle kan være med.

1 kommentar

comments user
Sofie

hos os herhjemme troede min datter jeg havde ødelagt INTERNET fordi jeg sagde API 😂 nu vil hun bruge mig til gruppearbejde

Send kommentar

You May Have Missed