Zum Inhalt springen

TypeScript-Client (@dustid/apid-client)

@dustid/apid-client ist der typisierte TypeScript-Client für die DUST API. Es handelt sich um denselben Client, den die DICE-Webanwendung in der Produktion verwendet. Seine Anfrage- und Antworttypen werden direkt aus der OpenAPI-Spezifikation der API generiert, sodass er stets mit dem Server übereinstimmt.

Das Paket wird nicht in der öffentlichen npm-Registry veröffentlicht. Es wird von DUST vertrieben und steht Integrationskunden auf Anfrage zur Verfügung (kontaktieren Sie support@dustidentity.com). npm install @dustid/apid-client wird es nicht finden.

Wenn Sie diese Abhängigkeit lieber nicht übernehmen möchten, können Sie dieselbe Typsicherheit erreichen, indem Sie Typen aus der OpenAPI-Spezifikation generieren — genau so werden auch die Typen dieses Clients erzeugt — und die API mit einfachem fetch aufrufen. Der Schnellstart verwendet diesen Ansatz, sodass er ohne Installation ausgeführt werden kann.

Prüfen Sie Folgendes, bevor Sie den Client einplanen:

AnforderungDetails
LaufzeitumgebungEin globales fetch: Node.js 18+, Bun oder Deno. Über die Option fetcher können Sie Ihre eigene Implementierung bereitstellen (Proxys, Wiederholungsversuche, Test-Doubles).
TypeScript-ToolchainDie Einstiegspunkte des Pakets werden zu TypeScript-Quellcode aufgelöst, nicht zu kompiliertem JavaScript. Ihr Bundler oder Ihre Laufzeitumgebung muss ihn transpilieren — einfaches node dist/app.js funktioniert mit nicht transpiliertem Quellcode nicht.
LaufzeitabhängigkeitenDer Client ist nicht frei von Abhängigkeiten: Er deklariert arktype (zur Validierung von Fehlernutzdaten) sowie DUST-interne Hilfspakete, die in der Distribution enthalten sind. Berücksichtigen Sie diese bei der Übernahme in eigene Systeme, bei Lizenzprüfungen und bei Installationen in isolierten Umgebungen.
AusführungsortNur serverseitig — beachten Sie den Warnhinweis am Ende dieser Seite.
import { ApidClient } from "@dustid/apid-client";
const client = new ApidClient({
baseUrl: "https://apid.dustid.io",
bearerToken: token, // Authorization: Bearer <token>
organizationId: orgId, // sent as Dust-Ctx-Org-Id
teamId: teamId, // sent as Dust-Ctx-Team-Id
});

Der vollständige Optionstyp:

type ApidClientOptions = {
baseUrl: string;
bearerToken?: string;
organizationId?: string; // Dust-Ctx-Org-Id header
teamId?: string; // Dust-Ctx-Team-Id header
fetcher?: typeof globalThis.fetch; // custom fetch (proxies, testing)
defaultHeaders?: HeadersInit | (() => HeadersInit); // e.g. Dust-Ctx-Locale
logger?: Logger; // debug/error request logging
};

organizationId und teamId werden den Kontext-Headern zugeordnet. Wenn teamId nicht angegeben wird, verwendet der Server standardmäßig das Root-Team der Organisation. Verwenden Sie defaultHeaders für alle zusätzlichen Angaben, die Sie mit jeder Anfrage senden möchten — beispielsweise für lokalisierte Fehlermeldungen:

const client = new ApidClient({
baseUrl,
bearerToken,
organizationId,
defaultHeaders: { "Dust-Ctx-Locale": "zh-CN" },
});

Client-Instanzen sind unveränderlich. Zwei Hilfsmethoden geben eine neu konfigurierte Kopie zurück, wodurch die Festlegung des Geltungsbereichs pro Anfrage oder Benutzer kostengünstig ist:

const asOtherTeam = client.withContext({ teamId: otherTeamId });
const asFreshToken = client.withToken(newBearerToken);

Der Client gruppiert Endpunkte in Ressourcen: client.me, client.threads, client.bundles, client.files, client.tags (Kennungsoperationen — die Endpunkte unter /api/v1/tags/*), client.teams, client.sharing, client.templates, client.events, client.relations, client.threadLinks, client.assemblies, client.transfers, client.slices, client.imports, client.fabric, client.users, client.certificates und client.certificateForms.

Die Methodennamen entsprechen der Referenz. Zwei echte Beispiele mit Datensätzen:

// GET /api/v1/threads — cursor-paginated list
const page = await client.threads.list({ pageSize: 50, q: "tire" });
for (const thread of page.threads) {
console.log(thread.threadId, thread.name);
}
if (page.next) {
const nextPage = await client.threads.list({ pageSize: 50, cursor: page.next });
}
// POST /api/v1/threads — create, unwrapped to the single created record
const created = await client.threads.createOne({
type: "single",
thread: { name: "Tire SZ3J-11-ZJ17" },
data: [{ name: "Serial Number", type: "text", value: { text: "SZ3J-11-ZJ17" } }],
});
// GET /api/v1/threads/{thread_id}
const record = await client.threads.get(created.threadId);
console.log(record.thread.name, record.events.length);

threads.create gibt die unverarbeitete Batch-Antwort zurück ({ created, uploadResponses }). threads.createOne ist eine Hilfsmethode, die created[0] zurückgibt und einen Fehler auslöst, wenn der Server nichts erstellt hat.

Alle Anfrage- und Antworttypen werden aus dem Paketstamm exportiert (ThreadCreateRequest, ThreadQueryResponse, ThreadGetResponse, …), ebenso wie die unverarbeiteten generierten Typen paths / components / operations aus der Spezifikation.

Methoden geben bei Erfolg die geparste JSON-Antwort zurück und lösen bei jedem Status außerhalb des 2xx-Bereichs einen ApiError aus. ApiError enthält den standardmäßigen Fehlertext der API:

import { ApiError } from "@dustid/apid-client";
try {
await client.threads.get(threadId);
} catch (error) {
if (error instanceof ApiError) {
// error.code stable error code, e.g. "NOT_FOUND", "UNAUTHORIZED"
// error.status HTTP status number
// error.message localized human-readable message
// error.detail optional extra context (validation issues, etc.)
// error.body the full { code, message, status, detail } payload
if (error.code === "UNAUTHORIZED") {
// token expired — re-exchange the API key and retry
}
} else {
throw error; // network failure or non-JSON response
}
}

Zwei Sonderfälle sollten Sie kennen: Antworten mit 204/205 werden zu undefined aufgelöst, und eine Antwort, die kein gültiges JSON enthält, löst einen einfachen Error aus (keinen ApiError). Wenn Sie einen logger übergeben, wird jede fehlgeschlagene Anfrage zusammen mit ihrer x-request-id protokolliert, damit der Support sie zuordnen kann.

Die API stellt ihre OpenAPI-3-Spezifikation unter https://apid.dustid.io/api/openapi.json bereit. openapi-typescript wandelt sie in eine vollständig typisierte paths-/components-Definition um, die Sie mit einfachem fetch oder einem beliebigen spezifikationsbasierten Fetch-Wrapper verwenden können:

Terminal-Fenster
npx openapi-typescript@7 https://apid.dustid.io/api/openapi.json -o <generated-types-file>
import type { paths } from "./dust-api";
type ThreadList =
paths["/api/v1/threads"]["get"]["responses"]["200"]["content"]["application/json"];

Denken Sie daran, die Header Authorization, Dust-Ctx-Org-Id und Dust-Ctx-Team-Id selbst festzulegen — siehe Anfragekonventionen. Generieren Sie die Typen erneut, sobald Sie neue API-Funktionen übernehmen. Die Spezifikation unter /api/openapi.json ist für den Server, von dem Sie sie abgerufen haben, stets aktuell.