JSON-RPC & Hello World

2 min read

JSON-RPC & Hello World

This example creates a simple API endpoint associated with a database user. Two authentication approaches are shown: the classic JWT flow and the simpler direct-credentials flow.

1. Create User and Function

In your database (my_database):

-- 1. Create a user who will log in to the API
CREATE ROLE demo_user WITH LOGIN PASSWORD 'user_password';
GRANT USAGE ON SCHEMA api TO demo_user;

-- 2. Create the Hello World function
-- Input: empty jsonb, Output: json
CREATE OR REPLACE FUNCTION api.hello_world(payload jsonb)
RETURNS json
LANGUAGE sql
AS $$
    SELECT '"Hello World"'::json;
$$;

-- 3. Grant permission to the user
GRANT EXECUTE ON FUNCTION api.hello_world(jsonb) TO demo_user;
Which authentication approach should you use?
Choose Option A (JWT) for browser-based or end-user sessions. Choose Option B (direct credentials) for local development, scripts, or internal services — no token management is required.

Option A: JWT Token Flow

JWT authentication requires the PgArachne system user (pgarachne) to be able to switch to demo_user:

-- Required for JWT auth only: allow PgArachne to switch to demo_user
GRANT demo_user TO pgarachne;

Step 1 — Obtain a JWT

Call the get_jwt JSON-RPC method with the user’s credentials:

curl -X POST http://localhost:8080/db/my_database/jsonrpc \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","method":"get_jwt","params":{"login":"demo_user","password":"user_password"},"id":1}'

Response:

{"jsonrpc":"2.0","result":{"token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."},"id":1}

Step 2 — Call the Function

Use the JWT in the Authorization header:

export TOKEN="YOUR_JWT_TOKEN_HERE"

curl -X POST http://localhost:8080/db/my_database/jsonrpc \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","method":"api.hello_world","params":{},"id":1}'

Response:

{"jsonrpc":"2.0","result":"Hello World","id":1}

Option B: Direct Credentials (No JWT Required)

Send the PostgreSQL username and password directly with every request using HTTP Basic Authentication. PgArachne opens a connection pool as that user — no GRANT … TO pgarachne is needed.

curl -X POST http://localhost:8080/db/my_database/jsonrpc \
  -u demo_user:user_password \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","method":"api.hello_world","params":{},"id":1}'

Response:

{"jsonrpc":"2.0","result":"Hello World","id":1}

The -u user:password flag in curl automatically sets the Authorization: Basic … header. Both options produce identical responses.

See Security & Authentication — Direct Credentials for a full comparison of all authentication methods.