A JavaScript client extends access to rqlite's HTTP API
Justin Morant's JavaScript client supports browser and Node.js applications. The underlying rqlite API retains its SQL result format, request-scoped transactions and selectable read consistency.
An HTTP database interface makes a new language client possible without changing the storage engine. The client still has useful work to do, because the application needs to turn language-level calls into requests and interpret database results. On 23 July, Philip O'Toole announced Justin Morant's JavaScript client for rqlite, with support for browser and Node.js applications.
The announcement is brief and makes no claim of a new database protocol. Its contribution is another way for JavaScript applications to reach rqlite. The existing HTTP interface remains the place where SQL execution, transaction choices and read consistency acquire their server-side meaning.
I value this kind of client because rqlite's appeal depends partly on being easy to integrate. A relational store behind HTTP should be usable from the languages surrounding it. That convenience is most useful when it preserves the database's explicit choices instead of making every operation look like an undifferentiated remote call.
Requests carry SQL and results carry structure
The data API documentation available with rqlite 4.0.0 describes writes as POST requests containing a JSON array of SQL statements. A successful modification result can include the last inserted identifier and the number of affected rows. Optional timing output reports execution information in seconds.
A query returns a different structure. It identifies columns and their types, then supplies row values in arrays. A language client can make that response easier to consume, but the association between the column list and each row remains part of understanding the result.
For example, the documented query interface can be used directly as follows when the foo table already exists.
curl -G http://localhost:4001/db/query --data-urlencode 'q=SELECT * FROM foo'
This illustrates the protocol the JavaScript ecosystem can access without requiring a native SQLite binding in every application process. The database lives behind rqlite's service. The application sends SQL and receives JSON through the HTTP interface.
The announcement does not specify individual library method signatures. Its historical claim is browser and Node.js access, so examples of the server protocol are a firmer basis here than attributing an unverified convenience API to the announced client.
Statement errors differ from request failures
The data API shows statement errors inside the returned results. A malformed insert can produce a result containing an error field with SQLite's syntax message. An application therefore needs to interpret the database response in addition to determining whether it received an HTTP response.
That distinction is useful for a client abstraction. Transport failure means the request did not complete normally as an HTTP exchange. A statement error describes the database's attempt to process a particular SQL statement. Treating both as the same condition would lose information the API deliberately returns.
The JSON array also matters when one request contains several statements. Results correspond to database operations, and a request-level success is not a substitute for examining those results. The API documentation explicitly demonstrates returning an error within that structure rather than reducing every SQL outcome to one transport status.
Transactions belong to the request
rqlite's documented transaction control uses a transaction URL parameter. Statements supplied together under that option execute within a transaction. The documentation leaves manual use of BEGIN, COMMIT, ROLLBACK, SAVEPOINT and RELEASE undefined for controlling these API operations.
This differs from assuming a sequence of independent HTTP calls is one persistent interactive database session. A client must express the intended transaction in the form the server supports. The language of the calling application does not change that boundary.
I find the request-scoped model consistent with a compact HTTP database API. It makes the group of statements explicit in the request that carries it. A JavaScript client is useful when it makes that grouping convenient while retaining the distinction between a batch and an atomic transaction.
Each read has a consistency choice
The contemporary consistency guide defines none, weak and strong. With none, a node reads its local database without checking leadership. A node that has fallen behind, or stopped receiving updates, can therefore return stale state.
Weak consistency is the default. It checks local leader state before querying SQLite, but that local check leaves a window in which another leader could be elected. Strong reads go through Raft and require communication with a quorum. The API selects a level through the level parameter.
These choices belong to individual requests. A browser application and a Node.js service may need different guarantees for different queries, even when they share a client library. The network API makes the choice available instead of fixing one consistency policy for the entire deployment.
The July announcement expands the set of applications that can reach those capabilities. It credits a JavaScript implementation intended for two execution environments, while the existing rqlite documentation defines what its requests mean. SQL result handling, request-scoped transactions and read consistency remain concrete parts of integrating the database.