std.net.rest
Session-basierter REST-Client auf Basis von std.net.http. Nimmt eine vollständige Base-URL (https://api.example.com/v1), hält Host, Pfad und Auth-Header sitzungsweit und baut alle Request-Pfade automatisch zusammen. HTTP und HTTPS werden transparent unterstützt – das Protokoll wird aus der URL-Scheme erkannt.
import std.net.rest;
var client: int64 := alloc(REST_SIZE);
RestClientInit(client, "https://api.example.com/v1" as int64,
"my-bearer-token" as int64);
var resp: HTTPResponse := RestGet(client, "/items" as int64);
if (RestIsSuccess(resp.statusCode)) {
PrintLn(resp.bodyPtr as pchar);
}
HTTPResponseFree(resp);
RestClientFree(client);
free(client, REST_SIZE);
Imports
std.net.httpstd.net.socketstd.net.dnsstd.net.tlsstd.net.typesstd.alloc
RestClient-Struct
Der Caller alloziert REST_SIZE Bytes und gibt den Zeiger an RestClientInit weiter. Die Felder werden intern verwaltet – niemals direkt schreiben.
| Konstante | Offset | Inhalt |
|---|---|---|
REST_OFF_HOST | 0 | Zeiger auf allozierte Host-Kopie (null-terminiert) |
REST_OFF_HOSTLEN | 8 | Länge des Host-Strings |
REST_OFF_BASEPATH | 16 | Zeiger auf allozierte BasePath-Kopie (null-terminiert) |
REST_OFF_PATHLEN | 24 | Länge des BasePath-Strings |
REST_OFF_AUTHHDRS | 32 | Zeiger auf Auth-Header-String (mmap'd) oder 0 |
REST_OFF_HTTPS | 40 | 0 = HTTP, 1 = HTTPS |
REST_OFF_PORT | 48 | TCP-Port; 0 = Default (80 / 443) |
REST_SIZE | — | 56 Bytes |
Funktionen
Client-Verwaltung
| Signatur | Beschreibung |
|---|---|
RestClientInit(client: int64, baseUrl: int64, token: int64): void | Parst baseUrl (Scheme, Host, BasePath), übernimmt optionalen Bearer-Token (token=0 für kein Auth) |
RestClientSetBearerToken(client: int64, token: int64): void | Setzt/ersetzt den Authorization: Bearer-Header |
RestClientSetApiKey(client: int64, name: int64, value: int64): void | Fügt beliebigen Header hinzu (z. B. X-API-Key) |
RestClientFree(client: int64): void | Gibt Host, BasePath und Auth-Header-Puffer frei |
HTTP-Methoden
Alle Methoden hängen BasePath + path zusammen und setzen automatisch die gespeicherten Auth-Header.
| Signatur | Beschreibung |
|---|---|
RestGet(client: int64, path: int64): HTTPResponse | HTTP GET |
RestPost(client: int64, path: int64, body: int64, bodyLen: int64): HTTPResponse | HTTP POST mit beliebigem Body |
RestPut(client: int64, path: int64, body: int64, bodyLen: int64): HTTPResponse | HTTP PUT mit beliebigem Body |
RestDelete(client: int64, path: int64): HTTPResponse | HTTP DELETE |
RestPatch(client: int64, path: int64, body: int64, bodyLen: int64): HTTPResponse | HTTP PATCH mit beliebigem Body |
JSON-Convenience
Wie RestPost / RestPut, setzen aber zusätzlich Content-Type: application/json.
| Signatur | Beschreibung |
|---|---|
RestJsonPost(client: int64, path: int64, json: int64, jsonLen: int64): HTTPResponse | POST mit Content-Type: application/json |
RestJsonPut(client: int64, path: int64, json: int64, jsonLen: int64): HTTPResponse | PUT mit Content-Type: application/json |
URL-Helfer
| Signatur | Beschreibung |
|---|---|
RestBuildPath(client: int64, path: int64, out: int64, outMax: int64): int64 | Hängt BasePath und path zusammen (mit Slash-Deduplication); gibt resultierende Länge zurück |
RestQueryAppend(buf: int64, bufMax: int64, key: int64, value: int64): int64 | Hängt ?key=value bzw. &key=value an; der Wert wird percent-kodiert (RFC 3986 unreserved chars); gibt neue String-Länge zurück |
Statuscodes prüfen
| Signatur | Rückgabe |
|---|---|
RestIsSuccess(statusCode: int64): int64 | 1 wenn 2xx |
RestIsClientError(statusCode: int64): int64 | 1 wenn 4xx |
RestIsServerError(statusCode: int64): int64 | 1 wenn 5xx |
Codebeispiele
JSON POST mit Bearer-Token
import std.net.rest;
var client: int64 := alloc(REST_SIZE);
RestClientInit(client, "https://api.example.com/v2" as int64,
"eyJhbGci..." as int64);
var body: pchar := "{\"name\":\"Alice\",\"active\":true}";
var resp: HTTPResponse := RestJsonPost(
client, "/users" as int64,
body as int64, StrLen(body));
if (RestIsSuccess(resp.statusCode)) {
PrintLn("Erstellt: " + IntToStr(resp.statusCode));
} else {
PrintLn("Fehler: " + IntToStr(resp.statusCode));
}
HTTPResponseFree(resp);
RestClientFree(client);
free(client, REST_SIZE);
Query-String aufbauen
import std.net.rest;
var client: int64 := alloc(REST_SIZE);
RestClientInit(client, "https://search.example.com" as int64, 0);
// Pfad mit Query-Parametern aufbauen
var buf: int64 := alloc(512);
var blen: int64 := 0;
poke8(buf, 0); // leerer String als Ausgangspunkt
// /products?category=tools&q=schrauber
var pathStart: pchar := "/products";
var pi: int64 := 0;
while (peek8(pathStart as int64 + pi) != 0) {
poke8(buf + pi, peek8(pathStart as int64 + pi)); pi := pi + 1;
}
poke8(buf + pi, 0);
RestQueryAppend(buf, 512, "category" as int64, "tools" as int64);
RestQueryAppend(buf, 512, "q" as int64, "schrauber" as int64);
var resp: HTTPResponse := RestGet(client, buf);
HTTPResponseFree(resp);
free(buf, 512);
RestClientFree(client);
free(client, REST_SIZE);
API-Key als Custom-Header
import std.net.rest;
var client: int64 := alloc(REST_SIZE);
RestClientInit(client, "https://api.service.io/v1" as int64, 0);
RestClientSetApiKey(client,
"X-API-Key" as int64,
"secret-key-12345" as int64);
var resp: HTTPResponse := RestGet(client, "/status" as int64);
HTTPResponseFree(resp);
RestClientFree(client);
free(client, REST_SIZE);
Hinweise
- Rückgabe ist
HTTPResponse: Jede Methode gibt eineHTTPResponseausstd.net.httpzurück — nach der Verarbeitung immerHTTPResponseFree(resp)aufrufen. - BasePath + path:
RestClientInitmithttps://api.example.com/v1undRestGet(client, „/items“)ergibtGET /v1/items. Doppelte Slashes an der Naht werden automatisch bereinigt. REST_SIZEBytes extern allozieren: Der Struct gehört dem Caller —alloc(REST_SIZE)vorRestClientInit,free(client, REST_SIZE)nachRestClientFree.RestQueryAppendpercent-kodiert den Wert: Erlaubte Zeichen ohne Kodierung (RFC 3986 unreserved):A-Z,a-z,0-9,-,.,_,~. Alles andere wird als%XXkodiert. Der Key-Parameter wird nicht kodiert.- Thread-Sicherheit: Jede Sitzung (
client-Zeiger) darf nur von einem Thread gleichzeitig verwendet werden. Mehrere Threads = mehrere Client-Instanzen. - HTTPS transparent: Wenn die Base-URL mit
https:beginnt, verwendetrestSendinternTLSConnect/TLSWrite/TLSRead— kein Unterschied in der aufrufenden API. —- ===== Quelldatei ===== ^ Unit ^ Datei ^ |std.net.rest|std/net/rest.lyx'' | Letzte Aktualisierung: 2026-06-15
