rqlite accepts SQL directly in execute request bodies
rqlite 8.36.0 accepts text/plain SQL for ordinary execute requests. The new input form removes JSON wrapping while retaining the existing execution path and its policies.
Sending one SQL statement over HTTP does not inherently require wrapping it in a JSON array. rqlite 8.36.0, published on December 13, adds an input form that accepts the SQL directly as a plain-text POST body. The change is small at the transport boundary, but useful for commands and files whose natural contents are already SQL.
The release changelog places it immediately after support for raw query bodies in 8.35.0. The new release extends that convenience to ordinary execute requests. It does not introduce another database execution engine. The HTTP service converts the text into the internal statement structure and then follows its existing execution path.
I value rqlite's straightforward HTTP interface because it keeps the tools needed to operate the database small. Removing a layer of escaping is useful when the request already consists of a complete statement. The distinction between a simpler input format and different execution semantics still matters.
Content type selects the input parser
The HTTP service at 8.36.0 checks whether the request's content type begins with text/plain. If it does, the ordinary execute method reads the body and creates one internal statement containing that text. Otherwise, it passes the body to the existing JSON request parser. The header therefore determines how the server interprets the bytes.
A simple schema command can now be sent directly. The explicit content type is part of the example's meaning, because without it the service selects the other parser.
curl 'http://localhost:4001/db/execute' \
-H 'Content-Type: text/plain' \
--data-binary 'CREATE TABLE example(id INTEGER PRIMARY KEY)'
Using a SQL file has the same request shape. A caller can supply a file to curl's data option while retaining the plain-text content type. That removes the need for a shell command that converts the file's contents into a JSON string before transmission. The simplification concerns encoding the request, not automatically making an arbitrary SQL file a supported migration procedure.
The handler constructs one statement object from the entire body. It does not split the text into a JSON-style list of separate statement entries at this stage. Consequently, clients should not infer per-statement batching behaviour merely from placing several commands in one text body. The source establishes the wrapper it constructs, and downstream SQL handling determines what that text does.
Existing execution policies still apply
After reading the body, the service increments its statement counter and performs SQL processing unless parsing is disabled for the request. The same random and time rewrite options enter that processing call. Raw SQL therefore does not bypass preprocessing just because its original representation was plain text.
The service then creates its ordinary execution request with transaction selection and the database timeout. It invokes the store and uses the existing not-leader handling to redirect or forward when needed. None of those decisions depends on the SQL originally arriving inside a JSON string. The new branch ends when the internal statement list has been constructed.
Response formatting also remains JSON. The outer execute handler sets the response content type before selecting ordinary or queued execution. A plain-text request does not request a plain-text result. A client still needs to decode the database response and distinguish returned execution results from errors.
That is useful for a shell command because a successful HTTP transfer does not by itself establish successful SQL execution. The service can place a store error in its response object. Removing request wrapping does not remove the obligation to inspect that response when a command participates in automation.
Queued execution has a separate parser
Queued writes have a relevant limit in this release. The outer handler chooses that branch when the queue parameter is present, before entering the ordinary execute method. Its queued implementation still calls the JSON request parser directly. It does not contain the new content-type branch.
Authorization also remains outside the new parsing branch. Before selecting either execution form, the outer handler checks execute permission and requires POST. Sending a different content type therefore changes the accepted representation only after those request checks have succeeded.
The feature should therefore be described as support for raw bodies in ordinary execute requests. Assuming the same input works with queued writes would go beyond the implementation. This distinction is visible in the service source and follows from the routing order, rather than from an abstract limitation of HTTP or SQL.
I prefer keeping that scope explicit in client helpers. A helper for raw ordinary execution can send SQL text with the required header and retain the standard response decoder. A queued-write helper still needs the representation its handler accepts. The new convenience removes JSON wrapping where the release implements it, while the existing execution and response paths continue to determine database behaviour.