JSONPlaceholder is a public test API without authentication — well suited for trying the RestJdbc driver (read and write).
SQL files can be run directly with the driver JAR:
java -jar /path/to/restjdbc.jar jsonplaceholder.sql
The file jsonplaceholder.sql contains the connection and sample queries. Steps:
restjdbc.jar)jsonplaceholder.sql and jsonplaceholder-spec.jsonIn the JDBC client:
connect 'jdbc:rest:https://jsonplaceholder.typicode.com|spec=jsonplaceholder-spec.json'
The file ends with quit to exit the client.
jdbc:rest:https://jsonplaceholder.typicode.com
The API base URL is set in the JDBC URL.
| Part | Value |
|---|---|
| Driver prefix | jdbc:rest: |
| API base URL | https://jsonplaceholder.typicode.com |
| SQL schema | public (default) |
Connection example (Java):
Properties props = new Properties();
props.setProperty("spec", "/path/to/jsonplaceholder-spec.json");
Connection conn = DriverManager.getConnection(
"jdbc:rest:https://jsonplaceholder.typicode.com", props);
| Property | Value for JSONPlaceholder | Required |
|---|---|---|
spec |
Path to spec (see below) | Yes |
auth |
not needed (none) |
No |
user, password, token |
— | No |
keyStore, … |
— | No |
Minimal:
props.setProperty("spec", "/path/to/jsonplaceholder-spec.json");
Spec path: absolute path to your local copy of the spec file.
Spec file: jsonplaceholder-spec.json
File: jsonplaceholder-spec.json
Excerpt (posts with page pagination):
{
"entities": [
{
"name": "posts",
"path": "/posts",
"pagination": {
"type": "page",
"limitParam": "_limit",
"pageParam": "_page",
"defaultLimit": 10
},
"columns": [
{ "name": "id", "type": "BIGINT", "primaryKey": true },
{ "name": "userId", "type": "BIGINT" },
{ "name": "title", "type": "VARCHAR" },
{ "name": "body", "type": "VARCHAR" }
]
}
]
}
| SQL table | REST path | Pagination |
|---|---|---|
users |
/users |
none (single request) |
posts |
/posts |
page with _limit, _page |
comments |
/comments |
page with _limit, _page |
albums |
/albums |
none |
photos |
/photos |
page with _limit, _page |
todos |
/todos |
page with _limit, _page |
With page pagination the driver automatically fetches all pages (e.g. all 100 posts) until no data remains.
Nested fields on users (address, company) are deliberately omitted in the spec — the driver reads flat top-level fields by default.
JSONPlaceholder requires no authentication.
props.setProperty("auth", "none");
Or simply omit auth properties.
No Authorization headers are sent; client certificate (clientcert) is not required.
Quote mixed-case column names in SQL ("userId").
SELECT id, name, email FROM users;
SELECT id, title FROM posts FILTER userId=1;
SELECT id, name, email FROM comments FILTER postId=1;
SELECT id, title, completed FROM todos FILTER userId=1;
| SQL | HTTP |
|---|---|
SELECT … FROM users |
GET https://jsonplaceholder.typicode.com/users |
SELECT … FROM posts FILTER userId=1 |
GET …/posts?userId=1 |
SELECT … FROM comments FILTER postId=1 |
GET …/comments?postId=1 |
SELECT … FROM posts (all posts) |
GET …/posts?_limit=10&_page=1, then _page=2, … |
FILTER forwards filters to the API server-side (unlike local WHERE).
INSERT INTO posts ("userId", title, body)
VALUES (1, 'Test', 'Body');
→ POST https://jsonplaceholder.typicode.com/posts with JSON body {"userId":1,"title":"Test","body":"Body"}.
JSONPlaceholder simulates write operations — the API responds successfully but does not persist data.
UPDATE posts SET title = 'New title', body = 'New content' FILTER id=1;
→ PUT https://jsonplaceholder.typicode.com/posts/1 with JSON body from SET columns.
DELETE FROM posts FILTER id=1;
→ DELETE https://jsonplaceholder.typicode.com/posts/1.
Query metadata from the spec:
SELECT table_name, remarks FROM system.table_list;
SELECT column_name, type_name FROM system.column_list WHERE table_name = 'posts';
SELECT column_name FROM system.pk_list WHERE table_name = 'posts';
posts, comments, photos, and todos the spec uses "type": "page" with _limit and _page; the driver fetches all pages automatically.