Client TypeScript (@dustid/apid-client)
@dustid/apid-client è il client TypeScript tipizzato per l’API DUST. È lo stesso client utilizzato in produzione dall’applicazione web DICE e i relativi tipi di richiesta/risposta vengono generati direttamente dalla specifica OpenAPI dell’API, quindi rimane perfettamente sincronizzato con il server.
Disponibilità
Sezione intitolata “Disponibilità”Il pacchetto non è pubblicato nel registro npm pubblico. Viene distribuito da DUST ed è disponibile su richiesta per i clienti che effettuano integrazioni (contatta support@dustidentity.com). npm install @dustid/apid-client non riuscirà a trovarlo.
Se preferisci non aggiungere questa dipendenza, puoi ottenere la stessa sicurezza dei tipi generando i tipi dalla specifica OpenAPI — è esattamente così che vengono prodotti i tipi di questo client — e chiamare l’API con il semplice fetch. La guida introduttiva segue questo approccio, così può essere eseguita senza installare nulla.
Prerequisiti per utilizzare il pacchetto
Sezione intitolata “Prerequisiti per utilizzare il pacchetto”Verifica quanto segue prima di pianificare l’utilizzo del client:
| Requisito | Dettaglio |
|---|---|
| Runtime | Un fetch globale: Node.js 18+, Bun o Deno. Puoi fornire una tua implementazione tramite l’opzione fetcher (proxy, nuovi tentativi, oggetti simulati per i test). |
| Toolchain TypeScript | Gli entry point del pacchetto vengono risolti in codice sorgente TypeScript, non in JavaScript compilato. Il bundler o il runtime deve eseguirne la transpilazione: il semplice node dist/app.js con codice sorgente non transpilato non funzionerà. |
| Dipendenze di runtime | Il client non è privo di dipendenze: dichiara arktype (utilizzato per convalidare i payload degli errori) oltre a pacchetti helper interni di DUST, inclusi nella distribuzione. Tienine conto per qualsiasi operazione di inclusione diretta delle dipendenze, verifica delle licenze o installazione in un ambiente isolato. |
| Luogo di esecuzione | Solo lato server — consulta l’avvertenza alla fine di questa pagina. |
Creare un client
Sezione intitolata “Creare un client”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});Il tipo completo delle opzioni:
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 e teamId corrispondono alle intestazioni di contesto; quando teamId viene omesso, il server utilizza per impostazione predefinita il team radice dell’organizzazione. Usa defaultHeaders per qualsiasi elemento aggiuntivo da includere in ogni richiesta, ad esempio messaggi di errore localizzati:
const client = new ApidClient({ baseUrl, bearerToken, organizationId, defaultHeaders: { "Dust-Ctx-Locale": "zh-CN" },});Cambiare contesto o token
Sezione intitolata “Cambiare contesto o token”I client sono immutabili; due metodi helper restituiscono una copia riconfigurata, rendendo poco costosa la definizione dell’ambito per richiesta o per utente:
const asOtherTeam = client.withContext({ teamId: otherTeamId });const asFreshToken = client.withToken(newBearerToken);Risorse e chiamate
Sezione intitolata “Risorse e chiamate”Il client raggruppa gli endpoint in risorse: client.me, client.threads, client.bundles, client.files, client.tags (operazioni sugli Identificatori — gli endpoint /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 e client.certificateForms.
I nomi dei metodi rispecchiano la documentazione di riferimento. Ecco due esempi reali con le schede:
// GET /api/v1/threads — cursor-paginated listconst 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 recordconst 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 restituisce la risposta batch non elaborata ({ created, uploadResponses }); threads.createOne è un metodo di utilità che restituisce created[0] e genera un’eccezione se il server non ha creato alcun elemento.
Tutti i tipi di richiesta e risposta vengono esportati dalla radice del pacchetto (ThreadCreateRequest, ThreadQueryResponse, ThreadGetResponse, …), insieme ai tipi paths / components / operations non elaborati generati dalla specifica.
Gestione degli errori
Sezione intitolata “Gestione degli errori”In caso di esito positivo, i metodi restituiscono la risposta JSON analizzata e, per qualsiasi stato diverso da 2xx, generano un’eccezione ApiError. ApiError contiene il corpo dell’errore standard dell’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 }}È utile conoscere due comportamenti nei casi limite: le risposte 204/205 vengono risolte in undefined, mentre una risposta che non contiene JSON valido genera un semplice Error (non un ApiError). Se specifichi un logger, ogni richiesta non riuscita viene registrata insieme al relativo x-request-id, per consentire al supporto di correlarla.
Alternativa: genera autonomamente i tipi
Sezione intitolata “Alternativa: genera autonomamente i tipi”L’API espone la propria specifica OpenAPI 3 all’indirizzo https://apid.dustid.io/api/openapi.json. openapi-typescript la converte in una definizione paths/components completamente tipizzata, utilizzabile con il semplice fetch o con qualsiasi wrapper per fetch basato sulla specifica:
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"];Ricorda di impostare autonomamente le intestazioni Authorization, Dust-Ctx-Org-Id e Dust-Ctx-Team-Id; consulta le Convenzioni per le richieste. Rigenera i tipi ogni volta che adotti nuove funzionalità dell’API; la specifica disponibile in /api/openapi.json è sempre aggiornata per il server dal quale viene recuperata.
Vedi anche
Sezione intitolata “Vedi anche”- Guida introduttiva all’API — lo stesso flusso completo con il semplice
fetch, così puoi eseguirlo prima di decidere se aggiungere una dipendenza. - Convenzioni per le richieste — le intestazioni e il contratto degli errori implementati dal client.
- Errori ed esiti delle scansioni — i codici alla base di
ApiErrore le tabelle degli esiti delle scansioni. - Documentazione di riferimento completa dell’API — tutti gli endpoint e gli schemi.