Skip to content

REST API

LoomCache ships two HTTP surfaces:

  1. Spring Boot starter — bundled controllers under /api/*.
  2. Operational helpers — direct-node health checks and host-mounted management handlers.

The legacy in-node /api/v1 data REST ingress has been removed. Use LoomClient/the binary protocol for production AP cache access. Spring Boot controllers provide the bundled HTTP data/admin surfaces. In production, node-local AP data-structure REST writes, direct CP REST writes, direct data-structure reads, and operator admin mutations are disabled by default. Raft-backed REST mutations such as transactions and dynamic config stay available behind their role gates. CP access in production uses the binary protocol; direct CP HTTP lock/atomic endpoints are non-production only, and other CP extension requests are not production-supported.

All Spring Boot REST endpoints use Spring Security with three roles. The table describes role authorization before production safety filters run; loomcache.profile=production still blocks direct data-structure reads/writes, direct data-structure management reads, and operator admin mutations unless the operation is on an explicitly release-validated Raft-backed path.

RoleAccess
ADMINFull access to all endpoints including cluster management, config CRUD, and management views.
USERRead and write access to data-structure endpoints (maps, queues, sets, lists, etc.).
READONLYRead-only access to data-structure inspection and management-read endpoints.

mTLS-authenticated callers derive their principal from the TLS client certificate common name (CN). The CN is resolved through loomcache.auth.cert-permissions: ADMIN grants ADMIN, USER, and READONLY; READ_WRITE grants USER and READONLY; READ_ONLY grants READONLY. When JWT is enabled, roles are embedded in the Bearer token claims. HTTP Basic is disabled in the bundled server filter chain.

Bundled Spring Boot endpoint groups:

Endpoint groupBase pathVerbs
Maps/api/mapGET /{key}, PUT /{key}, DELETE /{key}, GET /, GET /size, DELETE /
Queues/api/queuePOST /, POST /poll, GET /peek, GET /size, POST /drain
Sets/api/setPOST /, GET /members/{element}, DELETE /members/{element}, GET /, GET /size, DELETE /
Topics/api/topicPOST /, GET /stats
Queries/api/queryPOST / (requires embedded-server beans plus loomcache.client.enabled=true smart-routing client bean and query allow-listing)
Cluster operations/api/clusterGET /status, POST /state, POST /version, POST /rebalance, GET /members, GET /health (public), GET /health/details (ADMIN), POST /raft/step-down, POST /cp-subsystem/reset, GET /cp-subsystem/groups?offset&limit, GET /cp-subsystem/sessions?offset&limit&detail (break-glass diagnostics), POST /cp-subsystem/sessions/{sessionId}/force-close (destructive break-glass mutation; admin mutations are production-fail-closed unless release-validated on a Raft-backed path)
Locks/api/lockPOST /acquire, POST /release, GET / (non-production controller; not registered under loomcache.profile=production, and still fail-closed with default write-safety settings)
Atomic values/api/atomicGET /long, PUT /long, POST /long/add, POST /long/increment, POST /long/decrement, POST /long/cas, GET /reference, PUT /reference, DELETE /reference, POST /reference/cas (non-production controller; not registered under loomcache.profile=production, and still fail-closed with default write-safety settings)
Multimaps/api/multimapPOST /{key}, GET /{key}, DELETE /{key}/values, DELETE /{key}, GET /, GET /keys, GET /size
Lists/api/listPOST /, POST /{index}, GET /{index}, PUT /{index}, DELETE /{index}, GET /, GET /size, DELETE /
Ring buffers/api/ringbufferPOST /, GET /{sequence}, GET /, GET /status, DELETE /
Reliable topics/api/topic-reliablePOST /, GET /, GET /stats
Counters/api/counterGET /, GET /details, POST /increment, POST /decrement
Transactions/api/transactionsPOST /, POST /{id}/operations, POST /{id}/commit, POST /{id}/rollback
Dynamic config/api/configGET /, GET /{key}, PUT /{key}, DELETE /{key} (ADMIN only)
Data-structure inspection/api/v1/management/data-structuresGET /?type&page&size, GET /{type}/{name}?page&size (ADMIN or READONLY; non-production diagnostics only, production rejects direct data-structure management reads)

The server validates all inputs before controller execution; invalid payloads return 400 Bad Request with a JSON error body.

GET /api/cluster/health is Spring Security permit-all and intended as a liveness probe for load balancers and orchestrators. It carries no @RolesAllowed annotation. The Spring Boot actuator health endpoints, including GET /actuator/health and GET /actuator/health/**, use the same permit-all role policy. In production these endpoints still sit behind the configured TLS/mTLS transport boundary; permit-all means no Spring role or Bearer-token check is required after the transport checks succeed. The cluster-health response body is {"status":"UP"} with HTTP 200 when the cluster is ready, or {"status":"DOWN"} with HTTP 503 otherwise.

GET /api/cluster/health/details requires the ADMIN role. In addition to the status field it includes a "leader" field ("self" when the responding node is leader, the leader node ID otherwise, or "none" when no leader is known). The 503 body adds "reason":"Unavailable".

POST /api/counter/increment and POST /api/counter/decrement accept an optional ?delta=<long> query parameter (default 1). The value must be between 1 and 1,000,000,000; values outside that range (including zero or negative) are rejected with 400. There is no request body for these endpoints.

POST /api/list (append) and PUT /api/list/{index} (set/replace) require Content-Type: text/plain. The element value is the raw text body. Other list endpoints use the default application/json.

/api/config exposes Raft-replicated cluster-wide configuration as a key/value store. All operations require the ADMIN role. Mutations are committed through the Raft log and are visible on all nodes once committed.

MethodPathDescription
GET/api/configList all config entries. Supports ?offset=<int>&limit=<int> (max 1,000 per page).
GET/api/config/{key}Fetch a single config entry by key. 404 if not found.
PUT/api/config/{key}Upsert a config entry. Body: {"value":"<string>"}. Key ≤ 256 chars; value ≤ 8,192 chars.
DELETE/api/config/{key}Remove a config entry. 404 if key absent.

/api/v1/management/data-structures provides read-only introspection over registered data structures for non-production diagnostics. Requires ADMIN or READONLY; production profiles reject these direct data-structure management reads.

MethodPathDescription
GET/api/v1/management/data-structuresList all registered data structures. Optional ?type=<type> filter. Paged via ?page=<int>&size=<int>.
GET/api/v1/management/data-structures/{type}/{name}Inspect a specific data structure; returns paged entries, items, or elements depending on type.

Supported type values: map, queue, topic, set, multimap, ringbuffer, list, priorityqueue, reliabletopic, pncounter, gset, orset, lwwregister, idgenerator, cqc, executor. Hyphenated aliases (e.g., multi-map, ring-buffer) are also accepted.

Mutating endpoints in the following endpoint groups accept an optional Idempotency-Key request header:

Queues, topics, multimaps, lists, ring buffers, reliable topics, direct atomic endpoints (non-production only), counters, and transactions.

The header value is an arbitrary client-chosen string (max 512 characters). The server retains completed responses for replay for up to 10 minutes and up to 10,000 retained responses. It also caps concurrent keyed requests at 10,000 in-flight entries. Concurrent requests with the same key block for up to 30 seconds waiting for the in-flight result. Response replay survives restarts only when the public loomcache.rest.idempotency.persistence-file setting is configured as a JVM system property or Spring application property, or when server persistence/WAL is enabled with a non-blank loomcache.server.persistence.wal-directory; otherwise the REST idempotency store is in-memory only. Restart replay also requires the completed response to fit the retained response and persisted-field caps; over-cap responses can replay from memory until restart but are not written to the durable idempotency file. When durable REST idempotency persistence is configured and the response snapshot cannot be persisted after a completed action, the request fails closed instead of silently claiming durable replay; in-memory dedupe remains available until restart. The legacy camelCase spelling remains accepted as a fallback for existing deployments, but the public kebab-case setting is always preferred when both are present. Resolution order is public JVM property, public Spring Environment property, legacy fallback, then the WAL-derived path.

LoomCache’s grouped OpenAPI document is opt-in for dependency consumers. Add org.springdoc:springdoc-openapi-starter-webmvc-api, then set loomcache.openapi.enabled=true and springdoc.api-docs.enabled=true to publish the /api/** controller group and /token at GET /v3/api-docs/loomcache-api. Host applications that include SpringDoc may still expose their own default /v3/api-docs endpoint; set springdoc.api-docs.enabled=false when no docs endpoint should exist. The LoomCache group is ADMIN-gated by default, matching the documented HTTP surfaces. Development deployments can explicitly opt into public OpenAPI exposure for client generation or gateway validation, but production rejects that unauthenticated-docs opt-in. Direct LoomApplication launches keep Swagger UI disabled through the executable default springdoc.swagger-ui.enabled=false; dependency consumers should set that key explicitly, or omit the optional UI dependency, unless UI tooling is exposed only behind an approved internal gateway.

The loom-cli module packages com.loomcache.cli.LoomCli with a manifest main class. It calls the same HTTP surfaces described above.

The CLI rejects credentials passed directly on the command line (--basic / --bearer) because argv leaks to ps(1). Pass the name of an environment variable with --bearer-env for the Spring REST server. --basic-env exists for generic HTTPS targets and legacy tooling, but the bundled Spring Security configuration disables HTTP Basic; production operators should use mTLS and, when JWT is enabled, Bearer tokens. The following example builds a protected TLS argfile and runs CLI commands with a Bearer token taken from the environment:

Terminal window
export LOOM_URL=https://node-1:8080
export LOOM_ADMIN_TOKEN="${LOOM_ADMIN_TOKEN:?set to a JWT Bearer token}"
export LOOMCACHE_VERSION="<loomcache-version>"
loom_tls_args="$(mktemp)"
chmod 600 "$loom_tls_args"
trap 'rm -f "$loom_tls_args"' EXIT
{
printf '%s\n' '-Djavax.net.ssl.keyStore=/etc/loomcache/client.p12'
printf '%s\n' "-Djavax.net.ssl.keyStorePassword=${LOOM_CLIENT_KEYSTORE_PASSWORD:?set}"
printf '%s\n' '-Djavax.net.ssl.trustStore=/etc/loomcache/truststore.p12'
printf '%s\n' "-Djavax.net.ssl.trustStorePassword=${LOOM_TRUSTSTORE_PASSWORD:?set}"
} > "$loom_tls_args"
java @"$loom_tls_args" \
-jar "loom-cli/target/loom-cli-${LOOMCACHE_VERSION}.jar" --bearer-env LOOM_ADMIN_TOKEN cluster state
java @"$loom_tls_args" \
-jar "loom-cli/target/loom-cli-${LOOMCACHE_VERSION}.jar" --bearer-env LOOM_ADMIN_TOKEN cp-admin list-groups
java @"$loom_tls_args" \
-jar "loom-cli/target/loom-cli-${LOOMCACHE_VERSION}.jar" --bearer-env LOOM_ADMIN_TOKEN \
cp-admin list-sessions --detail --offset 0 --limit 100

The CLI uses the JDK HttpClient; for production mTLS, configure client-key and trust material with standard javax.net.ssl.* JVM properties or an equivalent JVM-wide SSL setup before calling HTTPS operator endpoints.

cp-admin list-sessions is a break-glass diagnostic for CP session reconciliation. cp-admin force-close-session --session-id <session-id> --force is a destructive break-glass mutation that terminates the target CP session and releases session-bound locks and semaphore permits. It does not mutate atomic values and is not the normal production workflow for CP primitives. Application code should use the typed Java client CP APIs.

Non-production diagnostics can also inspect direct host-mounted management endpoints:

Terminal window
java -jar "loom-cli/target/loom-cli-${LOOMCACHE_VERSION}.jar" \
data-structures list --type priority-queue --page 0 --size 100
java -jar "loom-cli/target/loom-cli-${LOOMCACHE_VERSION}.jar" \
data-structures inspect --type map --name default --page 0 --size 50

cluster state and CP list commands call ADMIN-gated /api/cluster Spring endpoints and forward the documented pagination query parameters. cp-admin list-sessions --detail also forwards ?detail=true for owner, held-lock, and held-permit diagnostics. force-leader-step-down and cp-admin force-close-session --session-id <session-id> --force are cluster-admin mutations; production profiles keep them fail-closed because the REST write-safety guard blocks operator admin mutations and rejects enabling loomcache.rest.write-safety.operator-admin-mutations-enabled under production. The data-structures commands use the host-mounted management JSON endpoints (/api/v1/management/data-structures) exposed by the hosting application; production profiles also block these direct data-structure reads and reject the loomcache.rest.write-safety.direct-reads-enabled opt-in. The production REST write guard applies to node-local AP data-structure paths such as maps, queues, sets, lists, ringbuffers, counters, topics, and multimaps; Raft-backed transaction and dynamic-config endpoints remain available behind their role gates. Direct CP REST paths (/api/atomic/** and /api/lock/**) are non-production only; production CP access uses the binary protocol. Local break-glass WAL diagnostics strictly validate the input WAL and write JSONL metadata or a migration-safe diagnostic copy for offline analysis.

The Spring Boot starter uses Spring Security for /api/** and /token. HTTP Basic is disabled in the bundled server filter chain. mTLS-authenticated callers are identified by certificate CN and authorized through loomcache.auth.cert-permissions; mTLS-authenticated callers with the token-issuer authority and either the ADMIN or USER role can request a short-lived JWT from POST /token when loomcache.security.jwt.enabled=true, loomcache.security.jwt.signing-secret is a high-entropy, non-placeholder UTF-8 secret of at least 32 bytes (for example, generated with openssl rand -base64 32), and production JWT deployments keep loomcache.security.jwt.local-revocation-enabled=false; use short token TTLs, signing-key rotation, or configured deny-list entries for emergency revocation. The default token TTL is 15 minutes. Bearer-token validation for protected Spring REST resources runs when JWT support is enabled; production deployments must enable certificate binding, while explicit verification secrets are only for validating tokens signed by rotated or retired keys and must meet the same strength requirement. Bearer tokens cannot mint fresh tokens from /token.

Spring Security permit-all health endpoints are GET /api/cluster/health, GET /actuator/health, and GET /actuator/health/**. In production they still sit behind the configured TLS/mTLS transport boundary; “permit-all” means no Spring role or Bearer-token check is required after the client certificate / transport checks succeed. The optional /actuator/info and OpenAPI document endpoints remain ADMIN-gated unless their explicit exposure opt-in properties are enabled; production rejects those opt-ins.

Error response bodies are not a single universal shape. Two patterns are in use:

Unhandled exception responses (for errors caught across all controllers):

{
"error": "<human-readable message>",
"code": "<MACHINE_TOKEN>",
"timestamp": "<ISO-8601>",
"correlationId": "<request-correlation-id>"
}

Endpoint-specific inline responses (returned directly by selected endpoint groups, e.g., list-conflict and config-validation responses):

{
"error": "<human-readable message>",
"code": "<MACHINE_TOKEN>",
"detail": "<per-call context>",
"timestamp": "<ISO-8601>"
}

List-conflict 409 responses additionally include "index" (for LIST_INDEX_CHANGED) or "offset", "limit", and "size" (for LIST_PAGE_CHANGED). There is no message field in any response body.

HTTPMeaningExample trigger
400Bad Request — validation failureMissing required field, value out of range, blank idempotency key
403Forbidden — role check failedUSER calling an ADMIN-only endpoint; query on a map not in the allow-list; TX commit from non-owner
404Not Found — resource absentKey not present, unknown data-structure name
405Method Not AllowedWrong HTTP verb
409Conflict — concurrent modificationLIST_INDEX_CHANGED / LIST_PAGE_CHANGED (concurrent list mutation during request)
500Internal Server ErrorUnexpected server-side exception
503Service Unavailable — Raft not readyNo Raft leader elected; node is rebalancing and cannot serve mutations

LoomCache is an independent open-source project. It is not affiliated with, endorsed by, or sponsored by Hazelcast, Inc. or by any other company whose products are named in this documentation. “Hazelcast” is a trademark of Hazelcast, Inc.; references to it are nominative and describe only migration and comparison. All other product and company names are trademarks of their respective owners and are used for identification purposes only.