Dokumentation
Erstellen Sie eine API-Client-Integration
Verwenden Sie das Promise SDK, den vollständigen Effect-Vertragsclient oder generierte Effect-Adapter mit ihren tatsächlichen Eingaben und Fehlerverhalten.
Automatisch aus dem Englischen übersetzt. Englisches Original ansehen
Wählen Sie einen Kunden
Das Repository verfügt über drei zugehörige Clientoberflächen. Sie haben dieselben Endpunktdeklarationen, aber ihre Konstruktion, Eingabeformen, Laufzeitabhängigkeiten und Fehlerkanäle unterscheiden sich. Wählen Sie bewusst eines aus und halten Sie Beispiele von dieser Oberfläche zusammen.
| Oberfläche | Einstiegspunkt | Ausführung |
|---|---|---|
| Versprechen SDK | @cadcamfun/api/sdk, exportiert CadCam.make | Versprechen für gewöhnliche Ergebnisse; Asynchrone Iterables für SSE. Verwendet einen bereitgestellten oder globalen Abruf. |
| Vollvertragskunde | ApiClient aus @cadcamfun/api | Effektdienst mit Transport- und Träger-Middleware, die von seiner Schicht bereitgestellt wird. |
| Generierte Effektadapter | packages/api/src/client/generated/index.ts | Abgeflachte Methoden rund um den Vertragskunden; Der Anrufer stellt die erforderliche Transport- und Middleware bereit. |
Das API-Paket ist ein privater Arbeitsbereich mit Quellexporten. Die folgenden Importe sind für dieses Monorepo oder eine Distribution gedacht, die diese Exporte tatsächlich bereitstellt; Diese Seite erhebt keinen Anspruch auf ein separat verfügbares öffentliches NPM-Paket. Unabhängige Kunden können das nutzen OpenAPI-Dokument oder einfaches HTTP.
Beginnen Sie für eine erste Anfrage ohne Einrichtung der Client-Bibliothek mit dem erfasste HTTP-Komplettlösung. Es legt fest, wie sich Erfolgs- und Misserfolgskörper zwischen Operationen unterscheiden.
Lösen Sie die Verbindung
Verwenden Sie die URL und das Anwendungs-Bearer-Token, die zum aktuellen Sidecar-Start gehören. Tauri erhält sie durch get_sidecar_endpoint. Ein manueller Entwicklungsprozess gibt den zugewiesenen Port in einem Ready-Ereignis aus. Der Ursprung muss auf den Sidecar oder das zugelassene Companion-Gateway verweisen und nicht auf die Dokumentationsseite oder die Vite-Assets.
Lösen Sie die Verbindung nach einem Sidecar-Neustart erneut auf. Die Wiederverwendung des vorherigen Ports kann zur Verbindungsverweigerung führen oder versehentlich einen anderen Prozess ansprechen. Die Wiederverwendung eines veralteten Starttokens führt zu einem Autorisierungsfehler. Eine erfolgreiche Reaktion der öffentlichen Gesundheit beweist nicht, dass einem geschützten Antrag stattgegeben wird.
Kontoauswahl, Anwendungszulassung, Gerätezulassung und externer Agentenzugriff sind unterschiedlich. Die Wahl x-session-token wählt nach der Zulassung zur Bewerbung ein Konto aus. Ein projektbezogenes Bridge-Token ist auf seine Aktions-Bridge-Endpunkte beschränkt. Ein Telefon-Token funktioniert über die Zulassungsliste des Gateways. Folgen Sie dem authentifizierungsreferenz bevor Sie die Verbindung für eine Integration auswählen.
Versprechen SDK
Der exportierte Namespace ist CadCamund sein Konstruktor ist make. Geben Sie eine Basis-URL und Standard-Header an. Die folgenden Methoden zum Erstellen und Abrufen verwenden abgeflachte Felder anstelle einer verschachtelten payload oder params objekt.
import { CadCam } from "@cadcamfun/api/sdk"
const client = CadCam.make({
baseUrl,
headers: { Authorization: "Bearer " + token },
})
const projects = await client.projects.list()
const created = await client.projects.create({
name: "Fixture plate",
description: "An integration-created project",
})
const detail = await client.projects.get({ id: created.id })
console.log(projects.length, detail.name, detail._count.drawings) Jeder Aufruf wird direkt in die Erfolgsnutzlast dieses Endpunkts aufgelöst. projects.list() gibt ein Array zurück; projects.create() gibt eine Projektzeile zurück. Es gibt kein Universelles { data, error } wrapper und Nr throwOnError konstruktoroption in diesem SDK. Einige Endpunktnutzlasten selbst enthalten data oder success denn das ist ihr HTTP-Vertrag.
Das SDK bereitet eine URL aus dem Endpunktpfad und der konfigurierten Basis-URL vor, codiert Pfadkennungen, serialisiert deklarierte JSON-Eingaben und überprüft den genauen deklarierten Erfolgsstatus des Vorgangs. Anschließend wird JSON analysiert und der typisierte Wert zurückgegeben. Die Promise-Laufzeit wendet keinen Effektschemadecoder auf jede zurückgegebene Nutzlast an. TypeScript-Ausgabetypen validieren keine beliebige Serverimplementierung.
Deklarierte und Transportfehler
Deklarierte HTTP-Fehler werden mit dem dekodierten Antworttext abgelehnt. Dieser Wert kann ein getaggtes einfaches Objekt und keine Instanz von JavaScript Error sein. Transport- und Protokollfehler nutzen die SDKs ClientError.
import { ClientError } from "@cadcamfun/api/sdk"
try {
await client.projects.create({})
} catch (error) {
if (error instanceof ClientError) {
console.error(error.reason, error.message)
} else if (error && typeof error === "object" && "message" in error) {
console.error(String(error.message))
} else {
console.error("Unrecognized API failure", error)
}
} | ClientError-Grund | Interpretation |
|---|---|
Transport | Fehler bei Aufbau, Verbindung, Abbruch oder Stream-Lesevorgang. Überprüfen Sie die Ursache und die aktuelle Verbindung. |
UnexpectedStatus | Der Server hat einen Status zurückgegeben, der außerhalb der deklarierten Erfolgs- und Fehlerstatus des Vorgangs liegt. |
UnsupportedContentType | Eine Stream-Antwort hatte nicht den erwarteten Event-Stream-Inhaltstyp. |
MalformedResponse | JSON oder ein erwarteter Antwortstream konnten nicht dekodiert werden. |
SseEventTooLarge | Der Ereignisstrompuffer hat den Frameschutz der generierten Laufzeit überschritten. |
Beispielsweise ist ein fehlender Projektname ein HTTP-400-Geschäftsfehler, obwohl der Eingabetyp „Erstellen“ das Auslassen zulässt. Ein Verbindungs-Reset während der Erstellung eines Projekts ist anders: Es lässt den Client unsicher, ob der Schreibvorgang abgeschlossen ist. Lesen Sie den Ressourcenstatus, bevor Sie eine Mutation wiederholen. Das SDK fügt kein anwendungsweites Idempotenzprotokoll hinzu und versucht nicht automatisch, jeden abgelehnten Anruf erneut zu versuchen.
Stornierung und Überschriften
ClientOptions akzeptiert baseUrl, eine optionale Fetch-Implementierung und Standardheader. Pro Anruf RequestOptions akzeptiert ein Signal und zusätzliche Header. Bei Methoden ohne Endpunkteingabe sind Anforderungsoptionen das erste Argument; Methoden mit Eingabe nehmen anschließend Anforderungsoptionen entgegen.
const controller = new AbortController()
const pending = client.projects.get(
{ id: projectId },
{
signal: controller.signal,
headers: { "x-session-token": accountSessionToken },
},
)
// Call controller.abort() when the operation is no longer needed.
const project = await pending Der Anforderungsgenerator wendet Standardheader, vom Endpunkt deklarierte Header und dann Header pro Aufruf an. Ein Wert pro Aufruf kann einen Standardwert überschreiben. Vermeiden Sie das versehentliche Ersetzen der Autorisierung beim Hinzufügen von Konto- oder Tracing-Headern. Fügen Sie keine Anmeldeinformationen in Endpunkt-URLs ein, die in Protokolle kopiert wurden.
Injizieren fetch unterstützt einen prozessbegleitenden Testtransport oder einen kontrollierten Adapter. Der Adapter muss weiterhin Anforderungsheader, Text, Stornierung, Inhaltstypen und Antwortstatussemantik berücksichtigen. Die eigene Effektintegration des Desktops und der angeheftete native Transport des Telefons machen zusätzliche Arbeit; Durch das Ersetzen eines willkürlichen Abrufs werden diese nativen Grenzen nicht reproduziert.
Full Effect-Client
ApiClient.layer konstruiert den vollständigen HttpApi-Client, den Abruftransport und die Träger-Middleware. Es macht Endpunktmethoden mit der zugrunde liegenden HttpApi-Anforderungsform verfügbar. Die Nutzlast einer Mutation geht unter payload, und Pfadwerte gehen darunter params.
import { ApiClient } from "@cadcamfun/api"
import { Effect } from "effect"
const createProject = Effect.gen(function* () {
const api = yield* ApiClient
return yield* api.projects.create({
payload: { name: "Fixture plate" },
})
}).pipe(Effect.provide(ApiClient.layer({ baseUrl, token })))
const project = await Effect.runPromise(createProject) Dieser Client leitet sich von der gesamten API-Deklaration ab und ist die Option für Endpunkte, die in generierten Zielen weggelassen werden. Der typisierte Fehlerkanal und der schemabewusste Transport von Effect bleiben erhalten. Ressourcenlebensdauer, Stream-Unterbrechung und Layer-Bereitstellung gehören zum aufrufenden Effektprogramm. Beim Erstellen eines Effekts wird dieser nicht ausgeführt.
Die wiederverwendbare Schicht stellt das Anwendungstoken bereit. Der Desktop baut eine eigene Ebene ein apps/desktop/src/app/client.ts um optionalen Kontositzungsstatus und injizierten Transport anzuhängen. Verwenden Sie diese Integration wieder, wenn Sie innerhalb des Desktops arbeiten, anstatt eine zweite Verbindung/Laufzeit pro Komponente zu erstellen.
Generierte Effektadapter
Der generierte Effect-Client importiert die echten Schemata und passt Methoden in abgeflachte Felder an. Es ist CadCam.make gibt einen Effekt zurück, der den angepassten Client erstellt. Es stellt keine eigene Abruftransport- oder Anwendungsautorisierungsschicht bereit, daher muss der Aufrufer die entsprechenden Dienste und Middleware bereitstellen.
Der generierte Fehleradapter ordnet Transport-/Schema-/SSE-Fehler einem Tag zu ClientError unter Beibehaltung deklarierter Domänenfehler. Diese Fehlerklasse ist durch a von der JavaScript-Fehlerklasse des Promise SDK getrennt reason zeichenfolge. Namensähnlichkeit macht ihre Handhabung nicht austauschbar.
Halten Sie Eingabebeispiele explizit. Die Formulare „Promise“ und „Generated Effect“ werden verwendet projects.get({ id }); das Rohvertragsformular verwendet projects.get({ params: { id } }). Vermeiden Sie die Übergabe des Eingabeobjekts einer Oberfläche an eine andere durch eine ungeprüfte Typzusicherung.
Streaming
Promise SSE-Vorgänge geben asynchrone Iterables zurück. Die Netzwerkeinrichtung erfolgt, wenn die Iteration beginnt. Die Laufzeit prüft den Erfolgsstatus und den Inhaltstyp des Ereignisstroms, liest inkrementelle UTF-8-Daten, normalisiert Frame-Grenzen und dekodiert Datenframes per JSON. Ein fehlerhafter Frame schlägt die Iteration fehl; Die Reader-Bereinigung wird ausgeführt, wenn die Iteration endet oder beendet wird.
Der Wächter der Laufzeit ist 16 * 1024 * 1024 gepufferte JavaScript-String-Einheiten. Es begrenzt die Akkumulation vor einer Frame-Grenze; Es ist kein Versprechen, dass jede beliebige Nutzlast von 16 MB für die Ereignisschemata der Anwendung nützlich oder gültig ist.
Verarbeiten Sie KI-Ereignisse gemäß ihren Unterscheidungsmerkmalen und behalten Sie die Sitzungskennung bei. Ein beendeter Transport ist kein Beweis für ein Terminal-Konversationsereignis. Verwenden KI-Streaming und -Wiederherstellung für Warteschlangen-, Abbruch-, Berechtigungs-, Frage- und Statuswiederherstellungsverhalten. EventSource ist kein direkter Ersatz für eine POST-Anfrage mit Autorisierungsheadern und einem JSON-Body.
Abdeckung und Regeneration
Der Generator verfügt über explizite Auslassungslisten für Formen, die er nicht darstellen kann. Zu den gemeinsamen Auslassungen gehören mehrteilige Profil-/Plugin-Uploads, MCP-Erstellung mit mehreren Erfolgsschemata, kollidierende Eingabenamen und Plugin-Bereitstellung mit Antwortheadern in seinem Stream. Weitere Promise-Auslassungen umfassen unformatierte signierte Webhooks, JavaScript-Plugin-Bootstrap, Binär-Download und Freiform-Generator-Anfragen.
Lesen Sie die genauen aktuellen Listen in packages/api/scripts/generate-clients.ts und die API-Übersicht. Eine nicht generierte Methode stellt nicht sicher, dass der Serverendpunkt nicht verfügbar ist. Nutzen Sie für diesen Vorgang den vollständigen Vertragskunden oder einen geeigneten Rohtransport.
bun run generate
bun run generate:check
bun run --filter @cadcamfun/web generate:api-reference
bun run --filter @cadcamfun/web check:api-reference Client-Neugenerierung und Dokumentations-Neugenerierung sind separate Ausgaben desselben Vertrags. Halten Sie beide nach Endpunktänderungen auf dem neuesten Stand. Bearbeiten Sie generierte Methodenkörper nicht, um die Eingabeanforderungen des Servers zu ändern.
Generierter Code wird beschrieben packages/api/src/client/generated und packages/api/src/sdk/generated. Bearbeiten Sie diese Dateien nicht manuell; Ändern Sie den Vertrag und generieren Sie ihn neu.
Integrationsüberprüfung
Das hier gezeigte Verhalten beim Erstellen/Lesen/Plain-Ergebnis von Promise und das Auslösen eines deklarierten Fehlers wurden mithilfe einer migrierten Einwegdatenbank auf den echten Sidecar-Handler-Stack angewendet. Die HTTP-Komplettlösung enthält die entsprechenden beobachteten Antworten. Wiederholen Sie gezielte Prüfungen, wenn Sie den Generator, die Authentifizierung oder die Endpunktschemata ändern.
For an integration acceptance check, verify public health; a protected request without a token; the same request with the current token; a valid create/read cycle; a declared validation failure; a cancelled request; and a stream whose terminal state is checked. Use a disposable project and never infer successful persistence from a frontend fixture alone.
Implementierungsquellen sind packages/api/src/sdk/generated/client.ts, es ist client-error.ts, packages/api/src/client.ts, packages/api/src/client/generated, und packages/httpapi-codegen/src/index.ts. Der Generator und die festgeschriebenen Ausgaben bestimmen zusammen das tatsächliche Clientverhalten.
Referenz zu Promise SDK-Optionen
| Option | Wo | Effect |
|---|---|---|
baseUrl | CadCam.make | Gelöst mit new URL(path, baseUrl); schließen Sie das Schema und den Port ein. |
fetch | CadCam.make | Ersetzen Sie den Transport, um beispielsweise die Protokollierung hinzuzufügen oder ein Test-Double einzufügen. Standardmäßig ist globalThis.fetch. |
headers | CadCam.make | Wird mit jeder Anfrage verschickt. Setzen authorization hier. |
signal | pro Anruf | Bricht die Anfrage ab; Die Ablehnung ist ClientError("Transport"). |
headers | pro Anruf | Überschreiben oder fügen Sie Header für einen Anruf hinzu, z x-session-token. Die Werte pro Anruf überzeugen gegenüber den Kundenwerten. |
Wenn ein Körper vorhanden ist und nein content-type header gesetzt wurde, legt das SDK fest application/json und serialisiert mit JSON.stringify. Pfadparameter werden immer durchgereicht encodeURIComponent, also ein Schlüssel wie docs.walkthrough.units oder eines, das enthält / bleibt ein einzelnes Segment.
ClientError-Gründe
| Grund | Aufgewachsen wann | Typische Reaktion |
|---|---|---|
Transport | fetch ausgelöst (abgelehnt, zurückgesetzt, DNS, Abbruch) oder ein Stream-Lesen ist fehlgeschlagen | Lösen Sie die Sidecar-URL erneut auf. Leseversuch wiederholen; Lesen Sie den Status erneut, bevor Sie den Schreibvorgang wiederholen. |
UnexpectedStatus | Der Status ist weder der Erfolgsstatus noch ein deklarierter Fehlerstatus. Die Ursache gilt { status }. | Als Vertragsinkongruenz wird häufig eine andere Serverversion behandelt. |
UnsupportedContentType | Eine Stream-Operation antwortete mit etwas anderem als text/event-streamoder eine JSON-Operation mit einem Nicht-JSON-Typ | Überprüfen Sie Proxys und die Serverversion. |
MalformedResponse | Leeres oder ungültiges JSON, ein fehlender Text oder ein SSE data: block, der nicht JSON ist | Protokollieren Sie die Rohantwort. berichten Sie. |
SseEventTooLarge | Der nicht geparste SSE-Puffer hat 16 MiB überschritten | Die Veranstaltung wird abgelehnt; Starten Sie den Stream neu. |
Die Botschaft von a ClientError ist der Grund, gefolgt von der Ursachenmeldung (z. B Transport: fetch failed), also Protokollierung error.message allein ist bereits diagnostisch.
import { CadCam, ClientError } from "@cadcamfun/api/sdk"
async function withRetry<T>(read: () => Promise<T>, attempts = 3): Promise<T> {
for (let attempt = 1; ; attempt++) {
try {
return await read()
} catch (error) {
const transient = error instanceof ClientError && error.reason === "Transport"
if (!transient || attempt >= attempts) throw error
await new Promise((resolve) => setTimeout(resolve, 250 * 2 ** attempt))
}
}
}
const projects = await withRetry(() => client.projects.list()) Wiederholen Sie Schreibvorgänge nicht blindlings
Ein Schreibvorgang, der mit fehlgeschlagen ist Transport möglicherweise angewendet worden. Lesen Sie die Ressource erneut und übermitteln Sie sie nur dann erneut, wenn sie nicht vorhanden ist. Die API verfügt über keine Idempotenzschlüssel.
Einen Stream mit dem SDK konsumieren
const controller = new AbortController()
const events = client.ai.chatStream(
{ message: "Pocket the 40 x 30 rectangle, 3 mm deep", projectId },
{ signal: controller.signal },
)
for await (const event of events) {
switch (event.type) {
case "delta": render(event); break
case "permission_request": askUser(event); break
case "done": finish(event); break
case "error": showError(event); break
}
} Der Iterator analysiert jeden SSE-Block: Er verbindet ihn data: zeilen des Blocks, analysiert den JSON und gibt ihn aus. Kommentare und Blöcke ohne data: werden übersprungen. Frühzeitiges Verlassen der Schleife (break, eine Ausnahme oder ein Abbruch) bricht den Reader ab und gibt die Verbindung frei. Die Veranstaltung type die Werte sind diejenigen, die im Assistenten-Streaming-Leitfaden aufgeführt sind. Überprüfen Sie das generierte AiChatStreamOutput typ für die genaue Vereinigung.
Beispiel: Einstellungen über das SDK
const key = "docs.walkthrough.units"
try {
await client.kv.get({ key })
} catch (error) {
if ((error as { _tag?: string })._tag !== "NotFound") throw error // first run: 404
}
const saved = await client.kv.set({ key, value: { units: "mm" } })
// saved: { key, value: { units: "mm" }, updatedAt: "2026-…" }
const { entries } = await client.kv.list({ prefix: "docs." })
await client.kv.remove({ key }) // { message: "…" } Schlüssel sind auf 512 Zeichen beschränkt und müssen Text enthalten, der kein Leerzeichen ist. Werte müssen JSON-kompatibel sein (keine Zyklen, Funktionen oder nicht endliche Zahlen).