Cealaltă față a API-ului
Programele TypeScript nu sunt doar servere — ele apelează la rândul lor API-uri: preiau date, comunică cu servicii, integrează terți. Clientul este fetch, inclus în Node.js, plus trei obiceiuri:
1. fă cererea (await fetch(url) pentru un GET sau fetch(url, { method, headers, body }) pentru control deplin),
2. verifică res.status înainte de a te încrede în corpul răspunsului — fetch nu aruncă o eroare la 404 sau 500,
3. citește corpul o singură dată, cu await res.json() sau await res.text() — niciodată ambele.
Demonstrațiile de mai jos apelează un mic server local pornit în același program, așa că rezultatele sunt stabile — codul clientului este exact cel pe care l-ai îndrepta către o adresă reală.
GET și decodare
Sarcina de zi cu zi: faci GET la o adresă, verifici starea și transformi corpul JSON în date cu await res.json(). Acel apel întoarce any, așa că un as UserRecord[] îi spune verificatorului de tipuri ce te aștepți să primești.
Preia o listă în obiecte
Corpul răspunsului devine un UserRecord[], iar de acolo sunt date TypeScript obișnuite — parcurse în buclă și afișate câmp cu câmp.
Ieșire: program TypeScript și rezultatul capturat
import { createServer } from "node:http"
interface UserRecord {
id: number
name: string
}
async function main(): Promise<void> {
// Un mic server local ține locul API-ului pe care îl apelează acest client.
const server = createServer((req, res) => {
res.writeHead(200, { "Content-Type": "application/json" })
res.end('[{"id": 1, "name": "Ana"}, {"id": 2, "name": "Ben"}]')
})
await new Promise<void>(resolve => server.listen(0, () => resolve()))
const base = `http://localhost:${(server.address() as { port: number }).port}`
const res = await fetch(`${base}/users`)
// Verifică starea înainte de a te încrede în corpul răspunsului.
if (res.status !== 200) {
console.log("stare neașteptată:", res.status, res.statusText)
server.close()
return
}
const users = (await res.json()) as UserRecord[]
for (const user of users) {
console.log(`utilizator ${user.id}: ${user.name}`)
}
server.close()
}
main()
POST cu un corp JSON
Trimiterea datelor este imaginea în oglindă: transformi obiectul în text, îl dai ca body cu tipul de conținut potrivit — apoi citești răspunsul serverului, care aici poartă id-ul atribuit de server.
Trimite un obiect, citește răspunsul
Obiectul pleacă sub formă de JSON, iar înregistrarea creată se întoarce cu noul său id 7 — întreaga cale de scriere a unui client de API într-un singur program mic. Node.js afișează obiectul analizat ca { id: 7, name: 'Cleo' }.
Ieșire: program TypeScript și rezultatul capturat
import { createServer, type IncomingMessage } from "node:http"
interface UserRecord {
id: number
name: string
}
async function readBody(req: IncomingMessage): Promise<string> {
const chunks: Buffer[] = []
for await (const chunk of req) chunks.push(chunk as Buffer)
return Buffer.concat(chunks).toString()
}
async function main(): Promise<void> {
// Un mic server local ține locul API-ului: el atribuie id-ul.
const server = createServer(async (req, res) => {
const incoming = JSON.parse(await readBody(req)) as { name: string }
const created: UserRecord = { id: 7, name: incoming.name }
res.writeHead(201, { "Content-Type": "application/json" })
res.end(JSON.stringify(created))
})
await new Promise<void>(resolve => server.listen(0, () => resolve()))
const base = `http://localhost:${(server.address() as { port: number }).port}`
const res = await fetch(`${base}/users`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ name: "Cleo" }),
})
const created = (await res.json()) as UserRecord
console.log("stare:", res.status, res.statusText)
console.log("creat:", created)
server.close()
}
main()