Martini HTTP Functions
Overview
Martini HTTP Functions let your services and workflows send outbound HTTP and SOAP requests, write ad hoc HTTP responses, and inspect request/response headers — without writing low-level HTTP client code.
What You Will Learn
- How to send an HTTP request with
sendRequestand choose the rightreturnAs/responseTypecombination - How to reuse a previously cached response for
sendRequestcalls withcacheName,cacheMode, andcacheKey - How to send a SOAP request with
sendSoapRequest - How to write an ad hoc HTTP response with
writeResponseand signal$requestHandled - How to read individual headers from an HTTP Filter trigger's request/response with
getRequestHeader/getResponseHeader - How to check whether a request is authenticated with
IdentityMethods.isAuthenticated
When To Use This
Use Martini HTTP Functions when you need to:
- Call an external REST API from a workflow or service and map its response into a data model
- Reuse a successful response from a rate-limited third-party API instead of resending an idempotent request, such as a
GET - Call an external SOAP web service without hand-building the SOAP envelope
- Write a custom HTTP response body, status code, and headers for an ad hoc REST service, instead of relying on the default response mapping
- Read a specific header from the request or response of an HTTP Filter trigger, for example to implement custom authentication
- Check whether the current request is authenticated before continuing a workflow or service
Prerequisites
- Martini Designer installed and running
- A Martini package in the current workspace
- A service or workflow to invoke the functions from
- Basic understanding of the following:
- Invoke Function Node for workflows
- Function Step for services
- HTTP Filter Trigger if using the header access functions
Sending HTTP Requests with sendRequest
sendRequest sends a RESTful HTTP request and returns the response, replacing the deprecated HttpMethods.http.
Getting Started
Using a Function Node or a Function Step, invoke sendRequest, providing at minimum a request with the target method and url:
1 2 3 4 5 | |
Expected result: the JSON response body is deserialized directly onto a data model property in your workflow or service.
Parameters
| Property | Type | Description |
|---|---|---|
request |
io.toro.martini.http.Request Data Model |
Details of the HTTP request, including method, URL, headers, and body. Multipart file uploads are represented in the request body using the io.toro.martini.http.MultipartFile data model — not a generic data model. |
auth |
io.toro.martini.http.Auth Data Model |
Authentication information for the request. |
returnAs |
String |
Determines how the response body is returned. See returnAs values below. |
responseType |
String |
Determines how the response body is parsed before being returned. See responseType values below. |
throwHttpExceptions |
Boolean |
Whether to throw an exception for 5xx HTTP responses. |
cacheName |
String |
Name of a cache declared in the owning package's caches.conf. When blank, no caching is attempted and sendRequest behaves exactly as it did without caching. See Reusing Cached Responses below. |
cacheMode |
String |
How the named cache is used: eager or fallback. Required whenever cacheName is provided; an IllegalArgumentException is thrown if cacheName is set and cacheMode is missing or unrecognized. See cacheMode values below. |
cacheKey |
String |
A custom cache key expression. When blank, the key is derived by default from the request's HTTP method, URL, and query parameters. |
trackable |
io.toro.martini.tracker.Trackable Data Model |
Tracking options for the call, recorded in Martini's Tracker. |
returnAs values
| Value | Use case |
|---|---|
InputStream |
Stream the raw response body, for example when forwarding a large payload or binary file without buffering it fully in memory. |
String |
Return the raw response body as text, useful when the caller wants to inspect or further parse the payload itself. |
byte[] |
Return the raw response body as a byte array, useful for binary payloads that are not streamed. |
Data Model Property |
Deserialize the response body directly into a data model property on the workflow/service, based on responseType. This is the current preferred option for structured (JSON/XML) responses. |
responseType values
| Value | Use case |
|---|---|
JSON |
The response body is JSON and should be parsed as such when returnAs is Data Model Property. |
XML |
The response body is XML and should be parsed as such when returnAs is Data Model Property. |
Auto-detect |
Martini inspects the response's Content-Type header to determine whether to parse the body as JSON or XML. Use this when the target endpoint may return either format. |
cacheMode values
| Value | Behavior |
|---|---|
eager |
Return the cached response if one is present. On a cache miss, send the HTTP request and, if the response is 2xx, cache it under the resolved cache key. |
fallback |
Send the HTTP request first. If the response has an HTTP status code of 429 (Too Many Requests), return a cached response for the resolved cache key if one exists. |
Return Value
Returns a io.toro.martini.http.Response data model with the server's response data.
Reusing Cached Responses with sendRequest
sendRequest can optionally reuse a previously cached response through a named cache declared in the
owning package's caches.conf, instead of always calling the target web service. This is
primarily intended for idempotent requests, such as GET, against rate-limited third-party APIs where a
recent successful response can safely be reused.
Caching is only attempted when cacheName is provided:
- Only responses with a
2xxstatus code are cached. - The full HTTP response is cached — not only the response body — so a cache hit returns the same headers, status code, and body as the original response.
- Caching is always skipped when
returnAsisInputStream, because the response body can't be replayed from the cache.sendRequestdoes not buffer or otherwise makeInputStreamresponses cacheable. - If the owning package has no cache configured under the given
cacheName, caching is skipped, a warning is logged, and the request is sent as if nocacheNamehad been provided. - Cache entry expiry (TTL) is controlled by the named cache's
caches.confconfiguration (for example,expireAfterWrite/expireAfterAccess). - Manual invalidation is handled through Cache Functions, such as
cacheInvalidateandcacheInvalidatePattern.sendRequesthas no separate expiry or invalidation settings of its own.
Prerequisites for Caching
Before calling sendRequest with cacheName, configure a named cache
in the caches.conf file of the package that calls sendRequest.
Cache Key Derivation
By default, the cache key includes only the request's HTTP method, URL, and query parameters. Headers (including authorization) and the request body are not included. If the response varies by a header, authenticated identity, or body, do not use the default key; provide a cacheKey that includes the relevant safe tenant or request context.
Eager Mode Example
Use eager mode to avoid resending a request when a cached response is already available:
1 2 3 4 5 6 7 | |
Expected result: on the first call, sendRequest sends the request, receives a 2xx response, and
caches it under a key derived from the method, URL, and query parameters. On subsequent calls with the
same method, URL, and query parameters, sendRequest returns the cached response immediately, without
sending a new request, until the cache entry expires per caches.conf or is manually invalidated.
Fallback Mode Example (HTTP 429)
Use fallback mode to keep calling the live service under normal conditions, but fall back to a cached
response when the target API starts rate-limiting requests with HTTP 429:
1 2 3 4 5 6 7 | |
Expected result: sendRequest sends the request every time. If the response is 2xx, it's returned
and cached (replacing any previous entry for the same key). If the response is HTTP 429, sendRequest
returns a previously cached response for the same key, if one exists, instead of the 429 response.
Default and Custom Cache Key Examples
Without cacheKey, two requests to the same URL and method with the same query parameters share a cache
entry:
1 2 3 4 5 6 | |
Provide cacheKey to control the cache key explicitly — for example, to include a tenant or other response-varying context that is not part of the default key, or to share a cache entry only when differing headers do not affect the response:
1 2 3 4 5 6 7 8 | |
Expected result: each distinct cacheKey value gets its own cache entry, regardless of the
request's method, URL, or query parameters.
Troubleshooting
| Symptom | Cause and Resolution |
|---|---|
sendRequest always calls the web service, even repeatedly with the same request |
No cache entry exists yet for the resolved key (cache miss), the entry expired, or cacheName doesn't match a cache declared in caches.conf. Check for a "cache not found" warning in the logs and confirm the name in caches.conf. |
| Cached responses are returned longer/shorter than expected | Expiry is controlled by the named cache's expireAfterWrite/expireAfterAccess settings in caches.conf, not by sendRequest. Adjust those settings on the cache, not the sendRequest call. |
| A stale response keeps being returned | Invalidate or update the entry using the Cache Functions (for example cacheInvalidate/cacheInvalidatePattern), or shorten the cache's expireAfterWrite/expireAfterAccess in caches.conf. sendRequest has no per-call invalidation option. |
A 4xx or 5xx response (other than 429 in fallback mode) is never cached and never served from cache |
Only 2xx responses are cached. Non-2xx responses always pass through as-is; a 4xx/5xx response is never written to the cache and, outside of the 429/fallback case, never replaced by a cached response. |
Caching doesn't seem to work when returnAs is InputStream |
This is expected: caching is always skipped for InputStream responses, since the response body can't be replayed from the cache. Use String, byte[], or Data Model Property for returnAs if you need caching. |
IllegalArgumentException is thrown when calling sendRequest |
cacheMode is required and must be eager or fallback whenever cacheName is provided. Supply a valid cacheMode, or omit cacheName if caching isn't needed. |
Sending SOAP Requests with sendSoapRequest
sendSoapRequest sends a SOAP request and returns the response, replacing the deprecated HttpMethods.soap.
Getting Started
Invoke sendSoapRequest, providing at minimum a url and soapAction:
1 2 3 4 5 6 7 | |
Parameters
| Property | Type | Description |
|---|---|---|
url |
String |
URL of the SOAP web service. |
auth |
io.toro.martini.http.Auth Data Model |
Authentication info for the request. |
soapAction |
String |
Name of the SOAP action. |
style |
String |
SOAP message style, one of Document or RPC, indicating how the SOAP body is structured. This is a choice value, not a boolean flag. |
soapProtocol |
String |
SOAP version to use for the envelope, one of SOAP 1.1 or SOAP 1.2. |
messageHeader |
Data Model | SOAP message header data. |
messageBody |
Data Model | SOAP message body. |
trackable |
io.toro.martini.tracker.Trackable Data Model |
Tracking options for the call, recorded in Martini's Tracker. |
Return Value
Returns a io.toro.martini.http.Response data model with the server's response data.
Required Properties
Requires url and soapAction properties for successful request sending.
Writing Ad Hoc HTTP Responses with writeResponse
writeResponse writes a custom HTTP response for an ad hoc REST service, replacing the deprecated
HttpMethods.prepareResponse. In addition to the former response-writing parameters, writeResponse accepts a
headers parameter for setting explicit response headers.
Parameters
| Property | Type | Description |
|---|---|---|
responseCode |
int |
HTTP status code to write to the response. |
content |
Object |
Content to write as the response body. |
format |
String |
Format used to serialize content (for example JSON or XML) when it is not already a raw string/byte payload. |
headers |
array of io.toro.martini.http.Header Data Model |
Explicit response headers to set. Each entry is a header name/value reference model. Explicit headers here take precedence over any header Martini would otherwise derive from the content type. |
Return Value and Exceptions
Unlike the deprecated prepareResponse, which swallowed and logged failures while returning a boolean success
flag, writeResponse returns void and throws:
IOException— if the response could not be written to the underlying output stream.IllegalArgumentException— if the supplied arguments are invalid, for example an unsupportedformat.
Callers must handle these exceptions explicitly; errors are no longer silently logged.
Using writeResponse with $requestHandled
For ad hoc REST services, invoke writeResponse and set the $requestHandled output property in the same
invoke step/node, so Martini knows the response has already been written and should not generate one
automatically:
1 2 3 4 5 6 7 | |
Expected result: on success, the client receives the custom response you wrote and Martini does not attempt
to generate its own; on failure, the exception is caught, logged, and $requestHandled reflects that the
response was not written.
Reading Request/Response Headers with getRequestHeader/getResponseHeader
getRequestHeader and getResponseHeader are new functions for reading a single header value from the
HttpServletRequest/HttpServletResponse objects made available by an HTTP Filter trigger — for example, the $__request and $__response parameters.
1 2 | |
| Function | Parameters | Return Value |
|---|---|---|
getRequestHeader |
request (HttpServletRequest, required), name (String, required) |
The value of the named request header, or null if the header is not present. |
getResponseHeader |
response (HttpServletResponse, required), name (String, required) |
The value of the named response header, or null if the header is not present. |
request, response, and name must not be null. Neither function throws an exception when the requested
header is simply absent — it returns null in that case.
1 2 3 4 | |
Checking Authentication with IdentityMethods.isAuthenticated
IdentityMethods.isAuthenticated replaces the deprecated HttpMethods.authenticated methods for checking
whether an incoming request is authenticated. It accepts the same request and throwException parameters as
the former method. For the full parameter reference, return value, and exception details, see
Checking Authentication with isAuthenticated in
the Identity Functions reference. That page also documents the new IdentityMethods.isAuthorized function for
scope-based authorization checks outside REST API scope enforcement.
Migrating from Deprecated HttpMethods Functions
Martini Runtime v2.8.0 hid the following methods from the Functions view's content assist in favor of new, more discoverable replacements:
| Deprecated method | Replacement | Notes |
|---|---|---|
HttpMethods.authenticated(...) |
IdentityMethods.isAuthenticated(...) |
Same request and throwException parameters. throwException defaults to false. |
HttpMethods.http(...) |
HttpMethods.sendRequest(...) |
http delegates to sendRequest for backward compatibility. |
HttpMethods.sendRequest(...) (without cacheName/cacheMode/cacheKey) |
HttpMethods.sendRequest(...) (with cacheName/cacheMode/cacheKey) |
The prior sendRequest overload is hidden from the Functions view in favor of the version documented in Sending HTTP Requests with sendRequest, which adds the cacheName, cacheMode, and cacheKey parameters described in Reusing Cached Responses with sendRequest. The prior overload delegates to the new one, passing a blank cacheName, so existing calls behave exactly as before and are never cached. |
HttpMethods.soap(...) |
HttpMethods.sendSoapRequest(...) |
soap delegates to sendSoapRequest for backward compatibility. |
HttpMethods.prepareResponse(...) |
HttpMethods.writeResponse(...) |
Adds a headers parameter; returns void and throws IOException/IllegalArgumentException instead of returning a boolean success flag. |
Deprecated does not mean unavailable
Deprecated methods and overloads are hidden from the Functions view's search results, but they are not
removed. Workflows and services that already call HttpMethods.authenticated, HttpMethods.http,
HttpMethods.soap, HttpMethods.prepareResponse, or the prior sendRequest overload without cache
parameters keep working, because each deprecated method or overload delegates to its replacement.
Migrate to the replacement names — and to the cache-aware sendRequest parameters, if useful — the next
time you touch these workflows or services, since the deprecated methods no longer appear when searching
for functions and may be removed in a future release.
Helpful Resources
- Identity Functions — Full reference for
IdentityMethods.isAuthenticatedandIdentityMethods.isAuthorized - HTTP Filter Trigger — Configure triggers that expose
HttpServletRequest/HttpServletResponseto your workflows and services - Martini Services Authentication & Authorization — Secure your services and APIs
- Martini Package Cache Configuration — Declare the named caches referenced by
sendRequest'scacheNameparameter - Cache Functions — Inspect, invalidate, or manually manage cache entries used by
sendRequest - Invoke Function Node — Call HTTP Functions from within a workflow
- Function Step — Call HTTP Functions from within a service
- Community Q&A: Martini Community Have a question? Post or search it here.