FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index mod_harbour Microservices: SQL via JSON – without DLLs, without Harbour changes
Posts: 6983
Joined: Fri Oct 07, 2005 07:07 PM
Microservices: SQL via JSON – without DLLs, without Harbour changes
Posted: Sun Jan 04, 2026 03:13 PM

Hello friends,

Harbour communicates with a microservice using JSON.
The microservice communicates with the database using SQL.

I believe SQL no longer belongs inside the Harbour process itself — not because SQL is bad, but because the environment around Harbour has fundamentally changed.

This is not a criticism of existing applications.
It is an observation based on how infrastructure, deployment, and runtime separation look today compared to 10–20 years ago.

Why this matters

In the past, embedding SQL directly into Harbour was often unavoidable:

no permanently running web servers
no lightweight local services
no clean separation between UI, business logic, and data access

The Harbour process itself was the server.

Today, this assumption no longer holds.

Web servers and microservices run continuously, SQL servers are already separate processes, and local service communication (socket / JSON / HTTP) is trivial — often on the same machine.

This opens a new option:
use SQL without embedding SQL clients into Harbour.

The idea in one sentence

Harbour talks JSON to a microservice.
The microservice talks SQL to the database.

Harbour never loads SQL DLLs.
Harbour never knows table schemas.
Harbour remains stable.

From DBF thinking to service thinking
Classic DBF code

USE kunden
GO TOP
DO WHILE !EOF()
   ? name, ort
   SKIP
ENDDO

Service-based SQL access

hRes := ServiceCall( "kunden_list", { "limit" => 10 } )

FOR EACH hRow IN hRes["rows"]
   ? hRow["name"], hRow["ort"]
NEXT

Minimal Harbour client
FUNCTION ServiceCall( cAction, hData )
   LOCAL hReq := { ;
      "action" => cAction, ;
      "data"   => hData ;
   }

   RETURN hb_jsonDecode( SendToService( hb_jsonEncode( hReq ) ) )

FUNCTION SendToService( cJson )
   LOCAL oSock := hb_socketOpen()
   hb_socketConnect( oSock, "127.0.0.1", 9001 )
   hb_socketSend( oSock, cJson + hb_eol() )
   LOCAL cRes := hb_socketRecv( oSock, 8192 )
   hb_socketClose( oSock )
RETURN cRes

Same usage pattern.
Different responsibility.

What runs where
Harbour

business logic

UI logic

JSON in / JSON out

Microservice (e.g. GraftonStreet Server)

SQL execution
prepared statements
transactions

Database
SQLite / PostgreSQL / MySQL
SQL lives behind the service boundary.

Why this is not overengineering
no SQL DLLs in Harbour
no OpenSSL, ODBC, libmysql in the core
no ABI or runtime conflicts
crash isolation by process separation

This is not adding complexity —
it is removing it from the wrong place.

Why this fits Harbour especially well

Harbour already works well with hashes and JSON
DBF-style thinking maps naturally to service calls
SQLite feels like DBF again (single file, easy backup)
migration can be incremental

For example:

USE kunden → ServiceCall( "kunden_list" )

Closing thought

SQL inside Harbour once solved an infrastructure problem.
Today, that infrastructure problem no longer exists.

What does exist today are better boundaries.

In the past, the Harbour process was the server.
Today, it can finally be just a client.

A possible role for FiveTech

I believe this is actually a task that fits very well with FiveTech’s role and experience.

Instead of every developer embedding SQL clients (libmysql, ODBC, OpenSSL, etc.) into Harbour applications, FiveTech could provide a small, built-in, service-oriented SQL layer, with the same level of quality and stability people expect from FiveWin / Harbour tools.

Conceptually, this would not replace SQL —
it would replace the built-in SQL clients.

Why this makes sense

The required surface is surprisingly small.

In practice, most applications only need a handful of well-defined operations:

execute a SELECT and get rows as hashes / JSON

execute INSERT / UPDATE / DELETE and get affected rows

insert a record from a hash

read table metadata (schema)

optionally: run multiple statements inside a transaction

That’s it.

Not an ORM.
Not a framework.
Just clean, predictable building blocks.

What FiveTech could standardize

FiveTech is in a unique position to do this once — correctly — instead of every project doing it differently.

A possible result:
a standard JSON protocol
a stable microservice reference implementation
a small Harbour client API (ServiceCall-style)
no SQL DLLs in Harbour processes

consistent behavior across platforms

Developers could then choose:
DBF backend
SQLite
PostgreSQL
MySQL

without changing application logic.

This is not about adding more abstraction.
It is about moving SQL to the right side of the boundary.

Harbour stays:

business logic

UI logic

orchestration
SQL stays:
isolated
replaceable
crash-safe

I’m not suggesting this should replace existing SQL integrations overnight.
But I do think it would be a very strong official alternative — especially for new projects.

Best regards,
Otto

Continue the discussion