28. REST Web Client
MALDA includes native support for making HTTP requests to external REST APIs. This includes both a RestClient class for advanced usage and static convenience functions for simple cases.
28.1 RestClient Class
The RestClient class provides a full-featured HTTP client for making REST API requests.
Constructor
var client = new RestClient(); // No base URL
var client = new RestClient("https://api.example.com"); // With base URL
var client = new RestClient("https://api.example.com", 60000); // With base URL and timeout (ms)
Parameters
baseUrl(string, optional): Base URL for all requests. If provided, relative URLs in requests will be prepended with this base URL.timeout(int, optional): Request timeout in milliseconds. Default: 30000 (30 seconds).
Properties
baseUrl(string): The base URL for all requeststimeout(int): Request timeout in milliseconds
HTTP Request Methods
get(url, headers?, queryParams?)- Make a GET requestpost(url, body?, headers?, queryParams?)- Make a POST requestput(url, body?, headers?, queryParams?)- Make a PUT requestdelete(url, headers?, queryParams?)- Make a DELETE requestpatch(url, body?, headers?, queryParams?)- Make a PATCH request
Method Parameters
url(string): Request URL (relative if baseUrl is set, absolute otherwise)body(object/string, optional): Request body for POST, PUT, PATCH. Objects are automatically serialized to JSON.headers(object, optional): Custom headers as an object (e.g.,{"Authorization": "Bearer token"})queryParams(object, optional): Query parameters as an object (e.g.,{"limit": "10", "offset": "0"})
Configuration Methods
setHeader(name, value)- Set a default header for all requestssetAuth(type, credentials)- Set authentication (type: "Bearer" or "Basic", credentials: token or username:password)setTimeout(ms)- Set request timeout in millisecondssetBaseUrl(url)- Set base URL for all requests
Response Format
All HTTP methods return an object with the following properties:
status(int): HTTP status code (200, 404, 500, etc.)statusText(string): HTTP status text ("OK", "Not Found", etc.)headers(object): Response headers as an objectbody(object/string): Response body. Automatically parsed as JSON if Content-Type is application/json, otherwise returned as string.ok(bool): True if status code is 200-299 (success)
Error Handling
If an error occurs (network error, timeout, etc.), the response object will have:
error(string): Error messagestatus(int): HTTP status code if available, otherwise 0ok(bool): false
28.2 Static HTTP Functions
For simple cases, you can use static convenience functions without creating a RestClient instance:
httpGet(url, headers?, queryParams?)- Simple GET requesthttpPost(url, body?, headers?, queryParams?)- Simple POST requesthttpPut(url, body?, headers?, queryParams?)- Simple PUT requesthttpDelete(url, headers?, queryParams?)- Simple DELETE requesthttpPatch(url, body?, headers?, queryParams?)- Simple PATCH request
These functions create a temporary RestClient internally and return the same response format as RestClient methods.
28.3 Examples
Using RestClient Class
// Create client with base URL
var client = new RestClient("https://api.example.com");
// Set authentication
client.setAuth("Bearer", "your-token-here");
// GET request
var response = client.get("/users");
if (response.ok) {
print("Users: " + toJSON(response.body));
} else {
print("Error: " + response.error);
}
// GET with query parameters
var response = client.get("/users", null, {"limit": "10", "offset": "0"});
// POST request with JSON body
var body = parseJSON("{\"name\": \"Alice\", \"email\": \"alice@example.com\"}");
var response = client.post("/users", body);
if (response.status == 201) {
print("User created: " + toJSON(response.body));
}
// PUT request
var updateData = parseJSON("{\"name\": \"Alice Updated\"}");
var response = client.put("/users/123", updateData);
// DELETE request
var response = client.delete("/users/123");
Using Static Functions
// Simple GET request
var response = httpGet("https://api.example.com/users");
if (response.ok) {
print("Users: " + toJSON(response.body));
}
// GET with headers
var headers = {"Authorization": "Bearer token123"};
var response = httpGet("https://api.example.com/users", headers);
// GET with query parameters
var response = httpGet("https://api.example.com/users", null, {"limit": "10"});
// POST with JSON body
var body = parseJSON("{\"name\": \"Alice\"}");
var response = httpPost("https://api.example.com/users", body);
// POST with custom headers
var headers = {"Content-Type": "application/json", "X-API-Key": "key123"};
var body = parseJSON("{\"name\": \"Alice\"}");
var response = httpPost("https://api.example.com/users", body, headers);
Error Handling
var response = httpGet("https://api.example.com/users/999");
if (!response.ok) {
if (response.status == 404) {
print("User not found");
} else if (response.error != null) {
print("Error: " + response.error);
} else {
print("HTTP Error: " + response.status + " " + response.statusText);
}
}
Working with Response Data
var response = httpGet("https://api.example.com/users");
if (response.ok) {
var users = response.body; // Already parsed as object/array if JSON
if (users.length > 0) {
print("First user: " + users[0].name);
}
// Access response headers
var contentType = response.headers["Content-Type"];
print("Content-Type: " + contentType);
}
28.4 Authentication
Bearer Token Authentication
var client = new RestClient("https://api.example.com");
client.setAuth("Bearer", "your-token-here");
var response = client.get("/protected-endpoint");
Basic Authentication
var client = new RestClient("https://api.example.com");
client.setAuth("Basic", "username:password");
var response = client.get("/protected-endpoint");
Custom Authorization Header
var headers = {"Authorization": "Custom token123"};
var response = httpGet("https://api.example.com/endpoint", headers);
28.5 Timeouts
// Set timeout to 60 seconds
var client = new RestClient("https://api.example.com", 60000);
client.setTimeout(10000); // Change to 10 seconds
var response = client.get("/slow-endpoint");
if (response.error != null && response.error.contains("timeout")) {
print("Request timed out");
}
28.6 Complete Example
// Create REST client
var client = new RestClient("https://jsonplaceholder.typicode.com");
// GET all posts
var response = client.get("/posts");
if (response.ok) {
var posts = response.body;
print("Total posts: " + posts.length);
// GET specific post
var postResponse = client.get("/posts/1");
if (postResponse.ok) {
var post = postResponse.body;
print("Post title: " + post.title);
}
// POST new post
var newPost = parseJSON("{\"title\": \"My Post\", \"body\": \"Content\", \"userId\": 1}");
var createResponse = client.post("/posts", newPost);
if (createResponse.ok) {
print("Created post ID: " + createResponse.body.id);
}
// PUT update post
var update = parseJSON("{\"title\": \"Updated Title\"}");
var updateResponse = client.put("/posts/1", update);
// DELETE post
var deleteResponse = client.delete("/posts/1");
if (deleteResponse.ok) {
print("Post deleted");
}
}
See Also
- 27. REST API Server - Creating REST API servers
- 24. Web UI Server Components - Web UI + API integration patterns
- 29. Full-Stack Development with MALDA - End-to-end architecture and API calls from UI
- 12. Input/Output — console, files, paths, environment