28. Client REST Web
MALDA include il supporto nativo alle richieste HTTP verso REST API esterne. Sono disponibili sia la classe RestClient per gli usi avanzati, sia funzioni statiche di convenienza per i casi semplici.
28.1 Classe RestClient
La classe RestClient offre un client HTTP completo per le richieste verso REST API.
Costruttore
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)
Parametri
baseUrl(string, opzionale): URL di base per tutte le richieste. Se presente, gli URL relativi nelle richieste vengono anteposti a questo URL di base.timeout(int, opzionale): Timeout della richiesta in millisecondi. Default: 30000 (30 secondi).
Proprietà
baseUrl(string): L'URL di base per tutte le richiestetimeout(int): Timeout della richiesta in millisecondi
Metodi di richiesta HTTP
get(url, headers?, queryParams?)- Esegue una richiesta GETpost(url, body?, headers?, queryParams?)- Esegue una richiesta POSTput(url, body?, headers?, queryParams?)- Esegue una richiesta PUTdelete(url, headers?, queryParams?)- Esegue una richiesta DELETEpatch(url, body?, headers?, queryParams?)- Esegue una richiesta PATCH
Parametri dei metodi
url(string): URL della richiesta (relativo se è impostato baseUrl, assoluto altrimenti)body(object/string, opzionale): Body della richiesta per POST, PUT, PATCH. Gli oggetti vengono serializzati automaticamente in JSON.headers(object, opzionale): Header personalizzati come oggetto (es.{"Authorization": "Bearer token"})queryParams(object, opzionale): Query parameter come oggetto (es.{"limit": "10", "offset": "0"})
Metodi di configurazione
setHeader(name, value)- Imposta un header di default per tutte le richiestesetAuth(type, credentials)- Imposta l'autenticazione (type: "Bearer" o "Basic", credentials: token oppure username:password)setTimeout(ms)- Imposta il timeout della richiesta in millisecondisetBaseUrl(url)- Imposta l'URL di base per tutte le richieste
Formato della risposta
Tutti i metodi HTTP restituiscono un oggetto con le proprietà seguenti:
status(int): Codice di stato HTTP (200, 404, 500, ecc.)statusText(string): Testo di stato HTTP ("OK", "Not Found", ecc.)headers(object): Header della risposta come oggettobody(object/string): Body della risposta. Parsato automaticamente come JSON se Content-Type è application/json, altrimenti restituito come stringa.ok(bool): True se il codice di stato è 200-299 (successo)
Gestione degli errori
Se si verifica un errore (errore di rete, timeout, ecc.), l'oggetto di risposta avrà:
error(string): Messaggio di errorestatus(int): Codice di stato HTTP se disponibile, altrimenti 0ok(bool): false
28.2 Funzioni HTTP statiche
Nei casi semplici puoi usare funzioni statiche di convenienza senza creare un'istanza di RestClient:
httpGet(url, headers?, queryParams?)- Richiesta GET semplicehttpPost(url, body?, headers?, queryParams?)- Richiesta POST semplicehttpPut(url, body?, headers?, queryParams?)- Richiesta PUT semplicehttpDelete(url, headers?, queryParams?)- Richiesta DELETE semplicehttpPatch(url, body?, headers?, queryParams?)- Richiesta PATCH semplice
Queste funzioni creano internamente un RestClient temporaneo e restituiscono lo stesso formato di risposta dei metodi di RestClient.
28.3 Esempi
Usare la classe RestClient
// 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");
Usare le funzioni statiche
// 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);
Gestione degli errori
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);
}
}
Lavorare con i dati della risposta
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 Autenticazione
Autenticazione Bearer Token
var client = new RestClient("https://api.example.com");
client.setAuth("Bearer", "your-token-here");
var response = client.get("/protected-endpoint");
Autenticazione Basic
var client = new RestClient("https://api.example.com");
client.setAuth("Basic", "username:password");
var response = client.get("/protected-endpoint");
Header Authorization personalizzato
var headers = {"Authorization": "Custom token123"};
var response = httpGet("https://api.example.com/endpoint", headers);
28.5 Timeout
// 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 Esempio completo
// 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");
}
}
Vedi anche
- 27. Server REST API - Creare server REST API
- 24. Componenti server Web UI - Pattern di integrazione Web UI + API
- 29. Sviluppo full-stack con MALDA - Architettura end-to-end e chiamate API dalla UI
- 12. Input/Output — console, file, path, ambiente