The book is currently only available in German.
Standard-Bibliothek — `netz`
Verfügbar — implementiert in Phase B.7.10. Vollständige Spec in
docs/netz.md.
netz ist Kistes HTTP-Client: Server kontaktieren, Antworten empfangen, mit Status-Code, Header und Body arbeiten. Synchron — der Aufruf kehrt erst zurück wenn die Antwort da ist (oder das Zeitlimit zuschlägt). Die Antwort kommt als eigener Wert-Typ Antwort (analog Geld, Zeit, Bytes).
31.1 Eine GET-Anfrage
nutze netz
nimm a = netz.hole("https://example.com/")
sag a.status // 200
sag a.erfolgreich // wahr
sag a.dauer_ms // z.B. 142
sag länge(a.bytes) // Body-Größe in Bytes
sag a.header["content-type"] // "text/html; charset=UTF-8"
a.inhalt gibt den Body als text (mit UTF-8-Validierung), a.bytes als rohe Bytes (immer ok).
31.2 Antwort als eigener Wert-Typ
sag typ(a) // Antwort
sag typ(a) == Antwort // wahr
sag a // antwort(200, 528 bytes, 142ms)
Die sieben Felder einer Antwort:
| Feld | Typ | Bedeutung |
|---|---|---|
status |
ganz |
HTTP-Code (200, 404, 500, …) |
inhalt |
text |
Body als UTF-8-text (wirft bei Binär-Body) |
bytes |
Bytes |
Roher Body (geht immer) |
header |
karte<text, text> |
Antwort-Header, lower-cased Keys |
dauer_ms |
ganz |
Round-Trip-Zeit |
url |
text |
Final-URL nach Redirects |
erfolgreich |
wahrheit |
wahr wenn 2xx |
31.3 Strikte Form: hole_text für „muss klappen"
// Muss 2xx + UTF-8 sein, sonst Fehler:
nimm html = netz.hole_text("https://example.com/")
sag html // "<!doctype html>..."
Idiomatisch wenn der Aufruf auf jeden Fall klappen muss. Wer „graceful degradation" will, prüft a.status selber statt sich auf catch zu verlassen — siehe §31.7.
31.4 POST/PUT/DELETE/PATCH mit sende
// Text-Body:
nimm a = netz.sende("POST", "https://api.example.com/log",
"Skript gestartet",
{"header": {"content-type": "text/plain"}})
sag a.status
// Bytes-Body (Datei-Upload):
nutze datei
nimm bilddaten = datei.bytes_inhalt("foto.jpg")
netz.sende("PUT", "https://api.example.com/foto.jpg",
bilddaten,
{"header": {"content-type": "image/jpeg"}})
// Kein Body (DELETE):
netz.sende("DELETE", "https://api.example.com/items/42", nichts)
Erlaubte Body-Typen: text, Bytes, nichts. Andere Typen werfen einen Fehler — wer Karten/Listen senden will, nutzt sende_json.
31.5 JSON-Convenience: sende_json
nimm neuer_user = {"name": "Sascha", "land": "CH"}
nimm a = netz.sende_json("POST", "https://api.example.com/users", neuer_user)
sag a.status // 201
sende_json ruft intern json.erzeugt auf den Daten auf und setzt Content-Type: application/json.
31.5b Erreichbarkeit prüfen: pinge
netz.pinge(url) schickt eine schlanke HEAD-Anfrage und gibt nur den Status-Code (Ganz) zurück — ideal, um schnell zu prüfen ob ein Server erreichbar ist, ohne den Inhalt zu laden:
nimm status = netz.pinge("https://example.com")
wenn status == 200 {
sag "Server ist erreichbar"
}
31.6 Optionen-Karte
Alle fünf Funktionen akzeptieren als letztes Argument optional eine karte:
| Schlüssel | Default | Was es macht |
|---|---|---|
"header" |
{} |
Request-Headers |
"parameter" |
{} |
URL-Query, automatisch encoded |
"zeitlimit_ms" |
30000 |
Timeout in Millisekunden |
"folge_redirects" |
wahr |
3xx automatisch folgen (max. 10 Hops) |
"ca_datei" |
"" |
Eigene CA-Bundle, zusätzlich zum System-Trust |
"tls_pruefen" |
wahr |
falsch deaktiviert TLS-Verifikation (mit stderr-Warnung) |
nimm a = netz.hole("https://api.example.com/items", {
"header": {"authorization": "Bearer abc"},
"parameter": {"seite": "2", "pro_seite": "50"},
"zeitlimit_ms": 5000,
})
Tippfehler bei Optionen-Schlüsseln werfen einen klaren Fehler:
netz.hole: unbekannte Option "headers" (meintest du "header"?)
31.7 Status manuell prüfen statt catch
Stdlib-Fehler werden in Kiste nicht durch versuche/fange gefangen (siehe Kapitel 11) — sie beenden das Skript. Für „graceful" HTTP-Behandlung prüft man den Status selbst:
nimm a = netz.hole("https://api.example.com/item/9999")
wenn a.status == 404 {
sag "Nicht gefunden — neu anlegen"
} sonstwenn a.erfolgreich {
sag "Geladen: " + a.inhalt
} sonst {
sag "Server-Fehler " + als_text(a.status)
}
31.8 TLS — drei Sicherheits-Stufen
// Default: System-Trust (Windows Cert Store / macOS Keychain / /etc/ssl/certs)
netz.hole("https://api.example.com/")
// Corporate-CA dazuladen:
netz.hole("https://intern.firma/", {"ca_datei": "C:\\corp-ca.pem"})
// Self-Signed-Bypass für lokalen Test-Server:
netz.hole("https://localhost:8443/", {"tls_pruefen": falsch})
// → schreibt einmal pro Session auf stderr:
// "netz: TLS-Verifikation deaktiviert für localhost:8443 — nur in Tests verwenden!"
Niemals tls_pruefen: falsch in Produktions-Code lassen — der Reviewer findet's am Schlüsselnamen, das stderr-Log macht's sichtbar.
31.9 Was netz v1 NICHT kann
- Server-Seite (lauschen, Routes definieren) — eigene Phase
- Async / Parallel-Requests — Kiste hat keine Goroutinen
- WebSockets / SSE — eigene Welt
- Multipart-Upload — eigene Phase
- Cookies-Jar — wer Cookies braucht, setzt sie manuell als Header
31.10 Praxis: API-Daten holen und speichern
nutze netz
nutze json
nutze datei
funktion repo_info(besitzer, repo) {
nimm url = "https://api.github.com/repos/" + besitzer + "/" + repo
nimm a = netz.hole(url, {
"header": {"accept": "application/vnd.github+json"},
"zeitlimit_ms": 10000,
})
wenn !a.erfolgreich {
wirf "GitHub-API-Fehler: Status " + als_text(a.status)
}
nimm daten = json.geparst(a.inhalt)
nimm zusammenfassung = {
"name": daten["name"],
"sterne": daten["stargazers_count"],
"geladen_in_ms": a.dauer_ms,
}
datei.schreibe("./repo.json", json.erzeugt(zusammenfassung))
sag "Gespeichert — " + als_text(zusammenfassung["sterne"]) + " Sterne"
}
repo_info("sascha", "kiste")