GeodeStore — Apache Geode distributed in-memory data grid
Read this page in the documentation
GeodeStore — Apache Geode distributed in-memory data grid Overview Apache Geode (the engine behind Pivotal/VMware GemFire) is a distributed in-memory data grid. Data lives in named regions — its distributed maps. There is no SQL-shaped query(sql) surface for this key/value access, so GeodeStore implements the minimal NoSqlStore marker interface (src/nosql/store.ts) — connection lifecycle plus a getClient() escape hatch — and exposes Geode's region operations (getMap/put/get/remove/keys/size) as a typed, promise-based API. Identity: Property | Value | --------- | ----------- | name | 'geode' | library | 'fetch' | Transport: the Geode Developer REST API over fetch Geode has no canonical Node.js driver; it ships a language-neutral "Developer REST API". This store talks to it with the global fetch, so library is 'fetch' and no npm driver is required. A tiny internal fetch client is built at connect() time (from baseURL + headers) unless one is injected. Endpoints wrapped (all under /geode/v1): Method | HTTP request / behavior | ----------- | -------------------------------------------------------------------------------- | mapPut | PUT /geode/v1/<region>/<key> | mapGet | GET /geode/v1/<region>/<key> | mapRemove | DELETE /geode/v1/<region>/<key> | mapKeys | GET /geode/v1/<region>/keys | mapSize | derived from mapKeys (the Developer REST API exposes no direct size endpoint) | Injected client GeodeStoreOptions accepts a pre-built client implementing GeodeHttpClient (get/put/delete). When provided it is used verbatim and baseURL is ignored. This is how the test suite injects a mock HTTP client (no network), and how callers can supply a custom transport. Connection Build a store from connection options and call connect(): Connection options (all optional): Option | Type | Purpose | --------- | -------------------------- | ------------------------------------------------------------------------------- | baseURL | string | Base URL of the Geode REST server. Defaults to http://localhost:8080. | client | GeodeHttpClient | Pre-built HTTP client; when given it is used verbatim and baseURL is ignored. | headers | Record<string, string> | Extra HTTP headers sent with every internal-client request (e.g. auth). | The default REST base URL is also exported as DEFAULTGEODEBASEURL. The internal fetch client factory is exported as createFetchClient(baseURL, headers?). Injected-client form Supply your own client (or a mock) to bypass the internal fetch client: Methods Client failures are wrapped in a DatabaseError (preserving the original error); using getMap() or getClient() before connect() (or after disconnect()) throws a ConnectionError. The map methods take a resolved GeodeRegion handle (from getMap) as their first argument. Region and key path segments are URL-encoded. Lifecycle Method | Signature | Behavior | ------------- | ---------------------------------- | ------------------------------------------------------------------------------------------------------------------ | connect | connect(): Promise<void> | Uses an injected client if provided, otherwise builds an internal fetch client from baseURL + headers. Idempotent. | disconnect | disconnect(): Promise<void> | Clears the client, the cached region handles, and connection state. | isConnected | isConnected(): boolean | true only when connected and a client is present. | getClient | getClient(): GeodeHttpClient | Returns the underlying (internal or injected) HTTP client. Throws ConnectionError if not connected. | Distributed region operations Method | Signature | Behavior | ----------- | ----------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- | getMap | getMap(name: string): Promise<GeodeRegion> | Resolves (and caches) a named-region handle { name }. Requires a live connection. Idempotent per name. | mapPut | mapPut(map: GeodeRegion, key: string, value: unknown): Promise<void> | PUTs JSON.stringify(value) to /geode/v1/<region>/<key>. | mapGet | mapGet(map: GeodeRegion, key: string): Promise<any> | GETs /geode/v1/<region>/<key>; returns the parsed body, or null if absent (404). | mapRemove | mapRemove(map: GeodeRegion, key: string): Promise<any> | DELETEs /geode/v1/<region>/<key>. | mapKeys | mapKeys(map: GeodeRegion): Promise<any[]> | GETs /geode/v1/<region>/keys; normalizes Geode's { keys: [...] } (or a bare array) to an array, [] otherwise. | mapSize | mapSize(map: GeodeRegion): Promise<number> | Derived: returns (await mapKeys(map)).length — the Developer REST API has no direct size endpoint. | Example Verification status Unit / mock-verified only. The tests in tests/nosql/geode.test.ts are fully mock-driven: an in-memory HTTP client implementing GeodeHttpClient is injected via GeodeStoreOptions.client. It records every request (method + path + body) and returns canned bodies, so there is no network in the test run. What this proves: name/library identity ('geode' / 'fetch'). Each method issues the correct Developer REST request — verified against the recorded (method, path, body): mapPut → PUT /geode/v1/<region>/<key> with the serialized body; mapGet → GET .../<key> returning the parsed body; mapRemove → DELETE .../<key>; mapKeys → GET .../keys normalizing { keys: [...] } to an array; mapSize deriving the count from that keys endpoint. getMap caches handles by name (a === b, a.name === 'orders'). Lifecycle: not connected before connect(), idempotent connect, clean disconnect(), injected client exposed via getClient(), and ConnectionError from getClient() / getMap() before connect(). Error handling: client failures wrapped in DatabaseError. What this does not prove: live execution against a real Geode/GemFire Developer REST server. The request shapes are verified against the REST API's documented paths, but end-to-end execution over the wire has not been exercised here. Related reading All data stores — the full catalogue, grouped by purpose Database types — where this sits among the 22 categories