Skip to Content
How-To GuidesTypeScriptMaking Outgoing HTTP Requests (TypeScript)

Making Outgoing HTTP Requests (TypeScript)

Overview

Golem TypeScript agents run in a WebAssembly environment with a built-in fetch API. Use the standard fetch() function for all outgoing HTTP requests — it is fully supported and works with WASI HTTP under the hood.

Note: The node:http and node:https modules are also available with comprehensive client-side support (the client API passes the majority of Node.js compatibility tests). They can be used as an alternative, especially when porting existing Node.js code. Server-side APIs (http.createServer, net.listen) are not available in WASM.

GET Request

const response = await fetch('https://api.example.com/data'); const data = await response.json(); console.log(data);

GET with Headers

const response = await fetch('https://api.example.com/secure', { headers: { 'Authorization': 'Bearer my-token', 'Accept': 'application/json', }, }); if (!response.ok) { throw new Error(`HTTP ${response.status}: ${response.statusText}`); } const result = await response.json();

POST with JSON Body

const payload = { name: 'Alice', email: 'alice@example.com' }; const response = await fetch('https://api.example.com/users', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Accept': 'application/json', }, body: JSON.stringify(payload), }); const created = await response.json();

PUT / DELETE

// PUT const response = await fetch('https://api.example.com/users/123', { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ name: 'Updated Name' }), }); // DELETE await fetch('https://api.example.com/users/123', { method: 'DELETE', });

Reading Response

const response = await fetch(url); // Status response.status; // e.g. 200 response.ok; // true if 2xx response.statusText; // e.g. "OK" // Headers response.headers.get('Content-Type'); // Body (choose one) const text = await response.text(); // as string const json = await response.json(); // parsed JSON const buffer = await response.arrayBuffer(); // raw bytes

Error Handling

try { const response = await fetch('https://api.example.com/data'); if (!response.ok) { const errorBody = await response.text(); throw new Error(`API error ${response.status}: ${errorBody}`); } return await response.json(); } catch (error) { console.error('Request failed:', error); throw error; }

Complete Example in an Agent

import { BaseAgent, agent, endpoint } from '@golemcloud/golem-ts-sdk'; type WeatherReport = { temperature: number; description: string }; @agent({ mount: '/weather/{city}' }) class WeatherAgent extends BaseAgent { constructor(readonly city: string) { super(); } @endpoint({ get: '/current' }) async getCurrent(): Promise<WeatherReport> { const response = await fetch( `https://api.weather.example.com/current?city=${encodeURIComponent(this.city)}`, { headers: { 'Accept': 'application/json' }, } ); if (!response.ok) { throw new Error(`Weather API error: ${response.status}`); } return await response.json(); } }

Calling Golem Agent HTTP Endpoints

When making HTTP requests to other Golem agent endpoints (or your own), the request body must match the Golem HTTP body mapping convention: non-binary body parameters are always deserialized from a JSON object where each top-level field corresponds to a method parameter name. This is true even when the endpoint has a single body parameter.

For example, given this endpoint definition:

@endpoint({ post: '/record' }) async record(body: string): Promise<void> { ... }

The correct HTTP request must send a JSON object with a body field — not a raw text string:

// ✅ CORRECT — JSON object with field name matching the parameter await fetch('http://my-app.localhost:9006/recorder/main/record', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ body: 'a' }), }); // ❌ WRONG — raw text body does NOT match Golem's JSON body mapping await fetch('http://my-app.localhost:9006/recorder/main/record', { method: 'POST', headers: { 'Content-Type': 'text/plain' }, body: 'a', });

Rule of thumb: If the target endpoint is a Golem agent, always send application/json with parameter names as JSON keys. See the golem-http-params-ts skill for the full body mapping rules.

Key Constraints

  • Use fetch() as the primary HTTP client — it is the standard and recommended API
  • node:http and node:https are available with comprehensive client-side support — useful when porting Node.js code or when npm packages depend on them
  • Server-side APIs (http.createServer, net.listen) are not available in WASM
  • Third-party HTTP client libraries that use fetch or node:http internally (e.g., axios) generally work; libraries that depend on native C/C++ bindings will not
  • All HTTP requests go through the WASI HTTP layer, which provides durable execution guarantees
  • Requests are async — always use await
Last updated on