Stateful Web Primitives.
The service exposes two primitives over HTTP: atomic counters under /c
and concurrent locks under /k. The live deployment is at
stateful.co; generated Javadoc lives at
doc.stateful.co; the in-app pages at
stateful.co/counters and
stateful.co/k render the same documentation
shown below.
Sign in once on stateful.co through the
GitHub OAuth flow. Open stateful.co/u to
read your URN (in the form urn:github:<id>) and your security token,
and to rotate the token through the refresh link. Every REST call must
carry both as request headers:
X-Sttc-URN: urn:github:526301
X-Sttc-Token: B28F-38E4-B305-C3A3Requests without the two headers, or with a token that no longer matches the one stored against the URN, receive HTTP 401.
Counter names are 1 to 32 characters from [0-9a-zA-Z-]. An account is
capped at 64 counters. Create a counter with a form-encoded POST to
/counters/add:
curl -X POST https://www.stateful.co/counters/add \
-H "X-Sttc-URN: urn:github:526301" \
-H "X-Sttc-Token: B28F-38E4-B305-C3A3" \
-H "Content-Type: application/x-www-form-urlencoded" \
--data "name=test"Set the value to a signed integer of up to 32 digits with a PUT to
/c/<name>/set?value=<int>; the response is empty. Read the current
value or move it by an arbitrary delta with a GET to
/c/<name>/inc?value=<int>; the response body is the new value as
plain text, so a value=0 increment reads the counter without mutating
it, and a negative value subtracts. Delete a counter with /counters/delete?name=<name>.
curl -X PUT "https://www.stateful.co/c/test/set?value=123" \
-H "X-Sttc-URN: urn:github:526301" \
-H "X-Sttc-Token: B28F-38E4-B305-C3A3"
curl "https://www.stateful.co/c/test/inc?value=0" \
-H "X-Sttc-URN: urn:github:526301" \
-H "X-Sttc-Token: B28F-38E4-B305-C3A3" \
-H "Accept: text/plain"Lock names are 1 to 256 characters from [0-9a-zA-Z._$-]. An account
is capped at 4096 locks. Acquire a lock with a form-encoded POST to
/k/lock, passing the lock name and a label that identifies the
holder. The server replies HTTP 303 on success and HTTP 409 when the
lock is held by another label:
curl -X POST https://www.stateful.co/k/lock \
-H "X-Sttc-URN: urn:github:526301" \
-H "X-Sttc-Token: B28F-38E4-B305-C3A3" \
-H "Content-Type: application/x-www-form-urlencoded" \
--data "name=deploy&label=worker-7"Release the lock with /k/unlock?name=<name> and, optionally, a
matching &label=<label> that has to equal the holder label or the
call replies HTTP 409. Read the current holder label without releasing
with /k/label?name=<name>; the body is the label as plain text.
The build runs on Java 21 with Maven. Clone the repository and execute the full Qulice profile that gates pull requests in CI:
mvn --batch-mode clean install -Pqulice