Last updated: 2026-08-03 5:32 PM PDT
Goal: Start the Gilhari microservice and verify that it is serving your data correctly before connecting an AI agent.
This phase has no script command. It uses the helper scripts generated by Phase 3, in the gilhari/ subdirectory, and standard tools (curl, Postman, or any HTTP client).
gilhari\run_docker_app.cmd :: Windows
./gilhari/run_docker_app.sh :: macOS / LinuxThe REST API will be available at http://localhost:<host_port>/gilhari/v1/.
Phase 3 generates sampleCurlCommands.cmd (Windows) and sampleCurlCommands.sh (macOS/Linux) in the gilhari/ subdirectory. Run them after the service is started to quickly test some REST APIs — responses are logged to gilhari/curl.log:
gilhari\sampleCurlCommands.cmd :: Windows
./gilhari/sampleCurlCommands.sh :: macOS / LinuxYou can also pass a non-default port as an argument:
gilhari\sampleCurlCommands.cmd 8899
./gilhari/sampleCurlCommands.sh 8899The scripts cover:
- Health check
- Object model summary (
getObjectModelSummary/now) - Deep GET for the first two mapped classes (includes related objects, limited to 5 objects)
- Shallow GET for the first two mapped classes (excludes related objects, limited to 5 objects)
GET commands use maxObjects=5 by default. Remove it to retrieve all qualifying objects, or change it to a different value (-1 to get all qualifying objects).
curl -s http://localhost:80/gilhari/v1/health/check | python -m json.toolA successful response confirms the container is running and Gilhari has loaded your ORM spec correctly.
curl -s http://localhost:80/gilhari/v1/getObjectModelSummary/nowReturns a plain-text summary of all mapped classes and their attributes as exposed by the ORM spec.
Deep retrieval (includes related objects):
curl -s "http://localhost:80/gilhari/v1/Employee?deep=true&maxObjects=5" | python -m json.toolShallow retrieval (excludes related objects — useful for complex object graphs):
curl -s "http://localhost:80/gilhari/v1/Employee?deep=false&maxObjects=5" | python -m json.toolFilter by field value:
curl -s "http://localhost:80/gilhari/v1/Employee?filter=dept='Engineering'" | python -m json.toolLook up by primary key via getObjectById: this is a genuinely distinct endpoint from the filtered query above, not just a shorthand for it — it goes through a different internal code path (a cached, reusable prepared statement, versus a fresh statement per filtered query). If you're specifically testing primary-key lookups, exercise this endpoint directly rather than assuming a filtered query on the primary key column is equivalent:
curl -s "http://localhost:80/gilhari/v1/Employee/getObjectById?filter=empId=1" | python -m json.toolThese commands require knowing the object structure (field names and primary key). Refer to the generated .jdx ORM spec in config/ for the attribute names of each class.
Create an object:
curl -s -X POST http://localhost:80/gilhari/v1/Employee ^
-H "Content-Type: application/json" ^
-d "{\"entity\": {\"empId\": 1, \"name\": \"Alice\", \"dept\": \"Engineering\"}}" ^
| python -m json.toolUpdate an object:
curl -s -X PUT http://localhost:80/gilhari/v1/Employee/updateEntity -H "Content-Type: application/json" -d "{\"entity\": {\"empId\": 1, \"name\": \"Alice\", \"dept\": \"Marketing\"}}"Update multiple specific objects in one call: entity also accepts an array — each object is matched and updated by its own primary key:
curl -s -X PUT http://localhost:80/gilhari/v1/Employee/updateEntity -H "Content-Type: application/json" -d "{\"entity\": [{\"empId\": 1, \"name\": \"Alice\", \"dept\": \"Marketing\"}, {\"empId\": 2, \"name\": \"Bob\", \"dept\": \"Sales\"}]}"PUT returns a plain-text confirmation message (e.g. Employee entity (entities) updated; result=null) for both the single- and multi-object forms — not the updated object(s) or JSON — no need to pipe the response through python -m json.tool here.
This differs from the bulk PATCH below in an important way: with PUT, you specify each object individually (by primary key, with its own full set of new values) — useful when updating a known, specific set of records. PATCH instead applies the same new values to every object matching a filter, without needing to know which records exist or their keys ahead of time.
Bulk-update objects matching a filter:
PUT above updates a single object identified by its primary key. To update every object of a class — or every object matching a filter — in one call, use PATCH instead. New attribute values are specified via newValues: a flat array of alternating name/value pairs (not an object) — ["attrib1", "value1", "attrib2", "value2", ...].
curl -s -X PATCH "http://localhost:80/gilhari/v1/Employee?filter=dept='Engineering'" -H "Content-Type: application/json" -d "{\"newValues\": [\"dept\", \"Marketing\"]}"Omit filter to update every object of the class. Multiple attributes can be set in one call by extending the array: "newValues": ["dept", "Marketing", "salary", "75000"].
PATCH returns the number of objects updated (e.g. 1), not the updated object(s) themselves — a filter matching no objects returns 0.
Delete a specific object by entity:
curl -s -X DELETE http://localhost:80/gilhari/v1/Employee/deleteEntity -H "Content-Type: application/json" -d "{\"entity\": {\"empId\": 1}}"entity accepts an array here too, the same way PUT's updateEntity does, for deleting multiple specific objects by their primary keys in one call. Returns a plain-text confirmation message (e.g. Employee entity (entities) deleted; result=null), the same shape as PUT's response.
Bulk-delete objects matching a filter (delete2):
This differs from deleteEntity above the same way PATCH/update2 differs from PUT/updateEntity: you don't need to know which records exist or their keys ahead of time — every object matching the filter is deleted in one call.
curl -s -X DELETE "http://localhost:80/gilhari/v1/Employee?filter=empId=1"Omit filter to delete every object of the class. Returns the number of objects deleted (e.g. 1), the same shape as PATCH's response — not the deleted object(s) themselves.
Piping through python -m json.tool formats JSON responses for readability and works on Windows, macOS, and Linux without any additional tools.
docker ps :: list running containers
docker logs <container-id> :: view Gilhari server logs
docker stop <container-id> :: stop the serviceIf docker logs <container> shows a database connection error, the most likely cause is a networking issue between the Gilhari container and your database.
The generated .docker.jdx uses host.docker.internal to reach the host machine's database. This works with Docker Desktop on Windows and macOS but not on Colima (common on Apple Silicon) or Linux without extra configuration.
Fix 1 — Colima: enable host resolution
colima stop && colima start --network-addressFix 2 — Run database in Docker on a shared network (works everywhere)
This is the most portable solution — no host networking dependency, works on Docker Desktop, Colima, Podman, and Linux:
# 1. Create a shared network
docker network create gilhari-net
# 2. Start your database container on that network (MySQL example)
docker run -d --name mysql-db --network gilhari-net \
-e MYSQL_ROOT_PASSWORD=secret \
-e MYSQL_DATABASE=mydb \
mysql:8
# 3. Start Gilhari on the same network
docker run -d --name my-gilhari-service --network gilhari-net \
-p 80:8081 my-gilhari-service:1.0Edit config/<n>.config.docker.jdx to use the database container name instead of host.docker.internal:
JDX_DATABASE JDX:jdbc:mysql://mysql-db:3306/mydb;...
Docker's internal DNS resolves container names on the same network automatically — no IP addresses needed.
Once your microservice is verified and serving data correctly, you are ready to connect an AI agent via ORMCP.
→ Phase 5 — ORMCP / AI Agent Integration
← Phase 3 — Gilhari Packaging | Next: Phase 5 — AI Integration →