Skip to content
Written with Claude

SINGLE

Also known as

single_record, single_result (with or without @ prefix)

Return a single record as a JSON object instead of a JSON array.

Syntax

code
@single

Default Behavior vs Single

By default, all endpoints return results as a JSON array, even when only one row is returned. With the @single annotation, the result is returned as a plain JSON object.

Without @single:

json
json
[{"id": 1, "name": "Alice"}]

With @single:

json
json
{"id": 1, "name": "Alice"}

Examples

PostgreSQL Function

sql
sql
create function get_user(_id int)
returns table(id int, name text, email text)
language sql
begin atomic;
select id, name, email from users where id = _id;
end;

comment on function get_user(int) is 'HTTP GET /users/{_id}
@single';

GET /users/1

json
json
{"id": 1, "name": "Alice", "email": "alice@example.com"}

SQL File

sql
sql
-- sql/get_user.sql
-- HTTP GET
-- @single
-- @param $1 user_id
SELECT id, name, email FROM users WHERE id = $1;

GET /api/get-user?user_id=1

json
json
{"id": 1, "name": "Alice", "email": "alice@example.com"}

Single Unnamed Column

When the result has a single unnamed column, the bare JSON value is returned:

sql
sql
-- sql/get_username.sql
-- HTTP GET
-- @single
-- @param $1 user_id
SELECT name FROM users WHERE id = $1;

GET /api/get-username?user_id=1"Alice"

Multi-Command Files (Positional)

In multi-command SQL files, @single is positional — it applies to the next statement below it:

sql
sql
-- sql/process_user.sql
-- HTTP POST
-- @param $1 id
-- @single
SELECT id, name FROM users WHERE id = $1;
UPDATE orders SET status = 'done' WHERE id = $1;
-- @single
SELECT id, status FROM orders WHERE id = $1;

Result:

json
json
{
  "result1": {"id": 1, "name": "alice"},
  "result2": 1,
  "result3": {"id": 1, "status": "done"}
}
  • First and third commands return objects (@single above them)
  • Second command returns rows-affected count (void, unaffected)
  • Empty per-command @single results render as null

Behavior

  • Multi-column results return a JSON object (no array wrapping)
  • Single unnamed column results return a bare JSON value (e.g., "hello", 42)
  • If the query returns multiple rows, only the first row is returned
  • Works across all endpoint sources: functions, procedures, and SQL files
  • In multi-command files, @single is positional — applies to the next statement below
  • TypeScript client generates Promise<IResponse> instead of Promise<IResponse[]>

Empty Results

When the query returns no rows, the behavior depends on the @response_null annotation:

SettingResponse
empty_string (default)Empty response body
null_literalnull
no_contentHTTP 204 No Content

In multi-command files, empty per-command @single results render as null.

Comments