22 KiB
APIDash Scripting: Using the ad
Object
APIDash allows you to write JavaScript code that runs either before a request is sent (pre-request script) or after a response is received (post-response script). These scripts give you powerful control over the request/response lifecycle and allow for automation, dynamic data manipulation, and basic testing.
The primary way to interact with APIDash data and functionality within these scripts is through the global ad
object. This object provides structured access to request data, response data, environment variables, and logging utilities.
ad.request
(Available in Pre-request Scripts Only)
Use ad.request
to inspect and modify the request before it is sent.
ad.request.headers
Manage request headers. Headers are stored internally as an array of objects: [{name: "Header-Name", value: "HeaderValue"}, ...]
. Note that header name comparisons in these helper methods are case-sensitive.
-
ad.request.headers.set(key: string, value: string)
- Adds a new header or updates the value of the first existing header with the exact same
key
. Ensures thevalue
is converted to a string. - Example:
// Set an Authorization header let token = ad.environment.get("authToken"); if (token) { ad.request.headers.set("Authorization", "Bearer " + token); } // Update User-Agent ad.request.headers.set("User-Agent", "APIDash-Script/1.0");
- Adds a new header or updates the value of the first existing header with the exact same
-
ad.request.headers.get(key: string): string | undefined
- Retrieves the value of the first header matching the
key
. Returnsundefined
if not found. - Example:
let contentType = ad.request.headers.get("Content-Type"); if (!contentType) { ad.console.log("Content-Type header is not set yet."); }
- Retrieves the value of the first header matching the
-
ad.request.headers.remove(key: string)
- Removes all headers matching the exact
key
. - Example:
// Remove default Accept header if it exists ad.request.headers.remove("Accept");
- Removes all headers matching the exact
-
ad.request.headers.has(key: string): boolean
- Checks if at least one header with the exact
key
exists. - Example:
if (!ad.request.headers.has("X-Request-ID")) { ad.request.headers.set("X-Request-ID", Date.now()); // Simple example ID }
- Checks if at least one header with the exact
-
ad.request.headers.clear()
- Removes all request headers.
- Example:
// Start with a clean slate for headers (use with caution) // ad.request.headers.clear(); // ad.request.headers.set("Authorization", "..."); // Add back essential ones
ad.request.params
Manage URL query parameters. Parameters are stored internally as an array of objects: [{name: "paramName", value: "paramValue"}, ...]
. Parameter name comparisons are case-sensitive.
-
ad.request.params.set(key: string, value: string)
- Adds a new query parameter or updates the value of the first existing parameter with the exact same
key
. Ensures thevalue
is converted to a string. - Note: HTTP allows duplicate query parameter keys. This
set
method replaces the first match or adds a new one. If you need duplicates, you might need to manipulate the underlyingrequest.params
array directly (use with care) or callset
multiple times if the backend handles updates correctly. - Example:
// Add or update a timestamp parameter ad.request.params.set("ts", Date.now().toString()); // Set a user ID from the environment let userId = ad.environment.get("activeUserId"); if (userId) { ad.request.params.set("userId", userId); }
- Adds a new query parameter or updates the value of the first existing parameter with the exact same
-
ad.request.params.get(key: string): string | undefined
- Retrieves the value of the first parameter matching the
key
. Returnsundefined
if not found. - Example:
let existingFilter = ad.request.params.get("filter"); ad.console.log("Current filter:", existingFilter);
- Retrieves the value of the first parameter matching the
-
ad.request.params.remove(key: string)
- Removes all parameters matching the exact
key
. - Example:
// Remove any debug flags before sending ad.request.params.remove("debug");
- Removes all parameters matching the exact
-
ad.request.params.has(key: string): boolean
- Checks if at least one parameter with the exact
key
exists. - Example:
if (!ad.request.params.has("page")) { ad.request.params.set("page", "1"); }
- Checks if at least one parameter with the exact
-
ad.request.params.clear()
- Removes all query parameters.
- Example:
// Clear existing params if rebuilding the query string // ad.request.params.clear(); // ad.request.params.set("newParam", "value");
ad.request.url
Access or modify the entire request URL.
-
ad.request.url.get(): string
- Returns the current request URL string.
- Example:
let currentUrl = ad.request.url.get(); ad.console.log("Request URL before modification:", currentUrl);
-
ad.request.url.set(newUrl: string)
- Sets the request URL to the provided
newUrl
string. - Example:
let baseUrl = ad.environment.get("apiBaseUrl"); let resourcePath = "/users/me"; if (baseUrl) { ad.request.url.set(baseUrl + resourcePath); }
- Sets the request URL to the provided
ad.request.body
Access or modify the request body.
-
ad.request.body.get(): string | null | undefined
- Returns the current request body as a string. For
multipart/form-data
, this might return an empty or non-representative string; userequest.formData
(accessed directly for now, potential futuread.request.formData
helpers) for structured form data. - Example:
let bodyContent = ad.request.body.get(); ad.console.log("Current body:", bodyContent);
- Returns the current request body as a string. For
-
ad.request.body.set(newBody: string | object, contentType?: string)
- Sets the request body.
- If
newBody
is an object, it's automaticallyJSON.stringify
-ed. - If
newBody
is not an object, it's converted to a string. - Content-Type Handling:
- If you provide the optional
contentType
argument (e.g., 'application/xml'), that value is used. - If
contentType
is not provided:- Defaults to
application/json
ifnewBody
was an object. - Defaults to
text/plain
otherwise.
- Defaults to
- The calculated
Content-Type
is automatically added as a request header unless aContent-Type
header already exists (case-insensitive check).
- If you provide the optional
- Side Effect: Setting the body via this method will clear any existing
request.formData
entries, as they are mutually exclusive with a raw string/JSON body in the APIDash model. It also updates the internalrequest.bodyContentType
. - Example:
// Set a JSON body let userData = { name: "Test User", email: "test@example.com" }; ad.request.body.set(userData); // Automatically sets Content-Type: application/json if not already set // Set a plain text body ad.request.body.set("This is plain text content.", "text/plain"); // Set an XML body (Content-Type needed) let xmlString = "<user><name>Test</name></user>"; ad.request.body.set(xmlString, "application/xml");
ad.request.query
-
Access or modify the GraphQL query string. This applies specifically to GraphQL requests, where the body typically includes a
query
,variables
, and optionallyoperationName
. -
ad.request.query.get(): string
-
Returns the current GraphQL query string (query, mutation, or subscription). If not set, returns an empty string.
-
Example:
let gqlQuery = ad.request.query.get(); ad.console.log("Current GraphQL query:", gqlQuery);
-
-
ad.request.query.set(newQuery: string)
-
Sets the GraphQL query string.
-
Automatically sets the
Content-Type
header toapplication/json
unless it's already set, ensuring correct handling by GraphQL servers. -
Does not set the entire request body, it is up to the user to include the full GraphQL payload inside the query. (e.g.,
{ query, variables, operationName }
). -
Example:
let newQuery = ` query { user(id: 1) { id username email address { geo { lat lng } } } }`; ad.request.query.set(newQuery);
-
-
ad.request.query.clear()
-
Clears the current GraphQL query string by setting it to an empty string.
-
Example:
ad.request.query.clear();
-
ad.request.method
Access or modify the HTTP request method (verb).
-
ad.request.method.get(): string
- Returns the current request method (e.g., "get", "post"). Usually lowercase.
- Example:
let method = ad.request.method.get(); ad.console.log("Request method:", method);
-
ad.request.method.set(newMethod: string)
- Sets the request method. The provided
newMethod
string will be converted to lowercase (e.g., "PUT" becomes "put"). - Example:
// Change method based on environment setting let usePatch = ad.environment.get("usePatchForUpdates"); if (ad.request.method.get() === "put" && usePatch) { ad.request.method.set("PATCH"); }
- Sets the request method. The provided
ad.response
(Available in Post-response Scripts Only)
Use ad.response
to access details of the response received from the server. This object is read-only.
-
ad.response.status: number | undefined
- The HTTP status code (e.g.,
200
,404
). - Example:
if (ad.response.status === 201) { ad.console.log("Resource created successfully!"); } else if (ad.response.status >= 400) { ad.console.error("Request failed with status:", ad.response.status); }
- The HTTP status code (e.g.,
-
ad.response.body: string | undefined
- The response body as a string. For binary responses, this might be decoded text or potentially garbled data depending on the Content-Type and encoding. Use
bodyBytes
for raw data. - Example:
let responseText = ad.response.body; if (responseText && responseText.includes("error")) { ad.console.warn("Response body might contain an error message."); }
- The response body as a string. For binary responses, this might be decoded text or potentially garbled data depending on the Content-Type and encoding. Use
-
ad.response.formattedBody: string | undefined
- The response body pre-formatted by APIDash (e.g., pretty-printed JSON). Useful for logging structured data clearly.
- Example:
ad.console.log("Formatted Response Body:\n", ad.response.formattedBody);
-
ad.response.bodyBytes: number[] | undefined
- The raw response body as an array of byte values (integers 0-255). Useful for binary data, but be mindful of potential performance/memory impact for very large responses. Depends on Dart correctly serializing
Uint8List
toList<int>
. - Example:
let bytes = ad.response.bodyBytes; if (bytes) { ad.console.log(`Received ${bytes.length} bytes.`); // You might perform checks on byte sequences, e.g., magic numbers for file types // if (bytes[0] === 0x89 && bytes[1] === 0x50 && bytes[2] === 0x4E && bytes[3] === 0x47) { // ad.console.log("Looks like a PNG file."); // } }
- The raw response body as an array of byte values (integers 0-255). Useful for binary data, but be mindful of potential performance/memory impact for very large responses. Depends on Dart correctly serializing
-
ad.response.time: number | undefined
- The approximate time taken for the request-response cycle, in milliseconds.
- Example:
let duration = ad.response.time; if (duration !== undefined) { ad.console.log(`Request took ${duration.toFixed(2)} ms.`); if (duration > 1000) { ad.console.warn("Request took longer than 1 second."); } }
-
ad.response.headers: object | undefined
- An object containing the response headers. Header names are typically lowercase (due to processing by the underlying HTTP client). Values are strings.
- Example:
let headers = ad.response.headers; if (headers) { ad.console.log("Response Content-Type:", headers['content-type']); // Access using lowercase key ad.console.log("Response Date Header:", headers.date); }
-
ad.response.requestHeaders: object | undefined
- An object containing the headers that were actually sent with the request. Useful for debugging or verification. Header names are typically lowercase.
- Example:
let sentHeaders = ad.response.requestHeaders; if (sentHeaders) { ad.console.log("Sent User-Agent:", sentHeaders['user-agent']); }
-
ad.response.json(): object | undefined
- Attempts to parse the
ad.response.body
as JSON. - Returns the parsed JavaScript object/array if successful.
- Returns
undefined
if the body is empty or parsing fails (an error message is automatically logged to the APIDash console viaad.console.error
in case of failure). - Example:
let jsonData = ad.response.json(); if (jsonData && jsonData.data && jsonData.data.token) { ad.console.log("Found token in response."); ad.environment.set("sessionToken", jsonData.data.token); } else if (jsonData) { ad.console.log("Parsed JSON, but expected structure not found."); }
- Attempts to parse the
-
ad.response.getHeader(key: string): string | undefined
- Retrieves a specific response header's value. The lookup is case-insensitive.
- Example:
// These are equivalent because of case-insensitivity: let contentType = ad.response.getHeader("Content-Type"); let contentTypeLower = ad.response.getHeader("content-type"); ad.console.log("Response Content-Type (case-insensitive get):", contentType); let correlationId = ad.response.getHeader("X-Correlation-ID"); if (correlationId) { ad.environment.set("lastCorrelationId", correlationId); }
ad.environment
(Available in Pre & Post-response Scripts)
Use ad.environment
to get, set, or remove variables within the currently active APIDash environment. Changes made here persist after the script runs and can be used by subsequent requests or other scripts using the same environment.
-
ad.environment.get(key: string): any
- Retrieves the value of the environment variable named
key
. Returnsundefined
if not found. - Example:
let apiUrl = ad.environment.get("baseUrl"); let apiKey = ad.environment.get("apiKey"); ad.console.log("Using API URL:", apiUrl);
- Retrieves the value of the environment variable named
-
ad.environment.set(key: string, value: any)
- Sets an environment variable named
key
to the givenvalue
. Thevalue
should be JSON-serializable (string, number, boolean, object, array, null). - Example:
// In a post-response script after login: let responseData = ad.response.json(); if (responseData && responseData.access_token) { ad.environment.set("oauthToken", responseData.access_token); ad.environment.set("tokenExpiry", Date.now() + (responseData.expires_in * 1000)); ad.console.log("OAuth token saved to environment."); } // Store complex object ad.environment.set("userProfile", { id: 123, name: "Default User"});
- Sets an environment variable named
-
ad.environment.unset(key: string)
- Removes the environment variable named
key
. - Example:
// Clear temporary token after use or logout ad.environment.unset("sessionToken"); ad.console.log("Session token cleared.");
- Removes the environment variable named
-
ad.environment.has(key: string): boolean
- Checks if an environment variable named
key
exists. - Example:
if (!ad.environment.has("userId")) { ad.console.warn("Environment variable 'userId' is not set."); // Maybe set a default or fetch it? // ad.environment.set("userId", "default-001"); }
- Checks if an environment variable named
-
ad.environment.clear()
- Removes all variables from the active environment. Use with extreme caution!
- Example:
// Usually used for resetting state during testing, careful! // ad.environment.clear(); // ad.console.warn("Cleared all variables in the active environment!");
ad.console
(Available in Pre & Post-response Scripts)
Use ad.console
to log messages to the APIDash console tab for the corresponding request. This is essential for debugging your scripts.
-
ad.console.log(...args: any[])
- Logs informational messages. Accepts multiple arguments, which will be JSON-stringified and displayed in the console.
- Example:
ad.console.log("Starting pre-request script..."); let user = ad.environment.get("currentUser"); ad.console.log("Current user from environment:", user); ad.console.log("Request URL is:", ad.request.url.get(), "Method:", ad.request.method.get());
-
ad.console.warn(...args: any[])
- Logs warning messages. Typically displayed differently (e.g., yellow background) in the console.
- Example:
if (!ad.environment.has("apiKey")) { ad.console.warn("API Key environment variable is missing!"); } let responseTime = ad.response.time; if (responseTime && responseTime > 2000) { ad.console.warn("Request took over 2 seconds:", responseTime, "ms"); }
-
ad.console.error(...args: any[])
- Logs error messages. Typically displayed prominently (e.g., red background) in the console. Also used internally by methods like
ad.response.json()
on failure. - Example:
if (ad.response.status >= 500) { ad.console.error("Server error detected!", "Status:", ad.response.status); ad.console.error("Response Body:", ad.response.body); } try { // Some operation that might fail let criticalValue = ad.response.json().mustExist; } catch (e) { ad.console.error("Script failed to process response:", e.toString(), e.stack); }
- Logs error messages. Typically displayed prominently (e.g., red background) in the console. Also used internally by methods like
Key Notes:
-
Pre/Post Script Context
- Request manipulation only works in pre-request scripts
- Response access only works in post-response scripts
-
Environment Variables
- Use
{{VAR_NAME}}
syntax in values for automatic substitution - Changes to environment variables persist for subsequent requests
- Use
-
Data Types
- All values are converted to strings when set in headers/params
- Use
ad.request.body.set()
with objects for proper JSON handling
-
Error Handling
try { // Potentially error-prone operations } catch(e) { ad.console.error('Operation failed:', e.message) // Optionally re-throw to abort request throw e }
-
Best Practices
- Always check for existence before accessing values
- Use environment variables for sensitive data
- Clean up temporary variables with
ad.environment.unset()
- Use logging strategically to track script execution
Example Workflow
Example 1: Post-request - Extract Data and Check Status
// Post-response Script
// Set URL: https://api.apidash.dev/auth/login
// 1. Check response status
if (ad.response.status < 200 || ad.response.status >= 300) {
ad.console.error(`Request failed with status ${ad.response.status}.`);
ad.console.error("Response:", ad.response.body);
// Optional: Could clear a related environment variable on failure
// ad.environment.unset("last_successful_item_id");
return; // Stop processing if status indicates failure
}
ad.console.log(`Request successful with status ${ad.response.status}.`);
ad.console.log(`Took ${ad.response.time} ms.`);
// 2. Try to parse JSON response
const data = ad.response.json();
// 3. Extract and store data if available
if (data && data.access_token) {
ad.environment.set("current_session_id", data.access_token);
ad.console.log("Session ID saved to environment.");
} else {
ad.console.warn("Could not find 'access_token' in the response JSON.");
}
Example 2: Pre-request - Set Auth Header
// Pre-request Script
// Set URL : https://api.apidash.dev/profile
// 1. Get Auth token from environment
const token = ad.environment.get("access_token");
if (token) {
ad.request.headers.set("Authorization", `Bearer ${token}`);
ad.console.log("Authorization header set.");
} else {
ad.console.warn("API token not found in environment!");
}
// 2. Try to parse JSON response
const data = ad.response.json();
// 3. Extract and store final User if available
if (data && data.user && data.user.id) {
ad.environment.set("logged_in_user_id", data.user.id);
ad.console.log(`User ID ${data.user.id} saved to environment.`);
}