FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index mod_harbour Web-based Cashbook – JSON version β†’ DBF/Microservice or SQL
Posts: 6983
Joined: Fri Oct 07, 2005 07:07 PM
Web-based Cashbook – JSON version β†’ DBF/Microservice or SQL
Posted: Mon Nov 17, 2025 01:30 AM

I started with a very simple web-based cashbook in PHP where all data was stored in a local JSON file.
Later I switched the backend to a DBF file via a microservice – and the same pattern would also work with SQL.

The nice part: the UI code did not change, only loadData().

  1. Original JSON-based version
    // Old: JSON file "data.json" as backend
    // {
    // "users": [...],
    // "transactions": [...]
    // }
function loadData() {
    $file = __DIR__ . '/data.json';

$data = json_decode(@file_get_contents($file), true);

if (!is_array($data)) {
    $data = ['users' => [], 'transactions' => []];
}

return $data;
}

Everywhere else I just used:

$data = loadData();
$transactions = $data['transactions'];

  1. DBF backend via microservice (same UI)

Now the data lives in a DBF file (Kasse.DBF).
Instead of reading data.json, I call a microservice endpoint xWH_hub_readdbf.php which returns JSON.

2.1 Minimal helper to call the microservice

function hubRequest(string $endpoint, array $payload): array
{
    $url = $endpoint; // e.g. "xWH_hub_readdbf.php" in the same directory

$context = stream_context_create([
    'http' => [
        'method'  => 'POST',
        'header'  => "Content-Type: application/json\r\n",
        'content' => json_encode($payload, JSON_UNESCAPED_UNICODE),
        'timeout' => 30,
    ]
]);

// For demo purposes: no error handling, expect valid JSON
$response = file_get_contents($url, false, $context);

return json_decode($response, true) ?? [];
}

2.2 New loadData() using DBF field names 1:1

function loadData() {

// DBF field names 1:1 – no mapping layer in PHP
$payload = [
    'databasePath' => 'x:\\xwhdaten\\datawin\\Kasse.DBF',
    'start'        => 1,
    'end'          => 500,
    'fields'       => [
        'TEXT',      // description
        'EINNAHMEN', // income (N, 11,2)
        'AUSGABEN',  // expense (N, 11,2)
        'DATUM',     // date (D)
        'USER',      // user code
    ],
];

$response = hubRequest('xWH_hub_readdbf.php', $payload);

// Adjust this key to your real microservice output: "records", "rows", "data", ...
$rows = $response['records'] ?? [];

// Keep the same structure the UI expects
return [
    'users'        => [],
    'transactions' => $rows,
];
}

The HTML/JS part still works with $data['transactions'], so the UI does not care if the backend is JSON, DBF, or anything else – as long as the JSON shape is the same.

3. Same pattern with an SQL-based microservice

Architecturally, you can do exactly the same with an SQL backend:
the PHP app doesn’t talk to the database directly; it calls a microservice that runs an SQL query and returns JSON.

Example: microservice endpoint xWH_hub_sql_select.php:

function loadData() {

// The microservice will execute this SQL on its side
$payload = [
    'sql' => "
        SELECT
            text       AS TEXT,
            income     AS EINNAHMEN,
            expense    AS AUSGABEN,
            booking_at AS DATUM,
            username   AS USER
        FROM cashbook
        ORDER BY booking_at, id
        LIMIT 500
    "
];

$response = hubRequest('xWH_hub_sql_select.php', $payload);

// Again: use whatever key your microservice returns
$rows = $response['rows'] ?? [];

return [
    'users'        => [],
    'transactions' => $rows,
];
}

From the UI perspective:

Old: JSON file β†’ $data['transactions']

New: DBF/microservice β†’ $data['transactions']

Alternative: SQL/microservice β†’ $data['transactions']

Same structure, same rendering logic, just a different backend behind the microservice.

Continue the discussion