Walkthrough: a namespace project¶
This walkthrough uses the executable project in lib/examples/services. It separates an API boundary
from a worker implementation, loads them by namespace, and returns persistent Hara data.
1. Describe the project¶
lib/examples/services/project.hal defines the roots searched by require:
(defproject services
{:source-paths ["src"]
:test-paths ["test"]})
Run project commands from this directory so Hara discovers the descriptor by walking upward.
2. Define the worker¶
src/services/worker.hal matches the namespace services.worker:
(ns services.worker)
(def worker-name "background")
(defn process-job [job]
{:worker worker-name
:job job
:status :processed})
The function accepts and returns persistent values. Nothing mutable or JVM-specific crosses its public boundary.
3. Require it from the API¶
src/services/api.hal uses one project namespace and one generated library namespace:
(ns services.api
(:require [services.worker :as worker]
[std.lib.string :as string]))
(defn normalize-route [route]
(string/to-lower (string/trim route)))
(defn dispatch [route job]
{:route (normalize-route route)
:result (worker/process-job job)})
The alias is local to services.api; requiring this namespace elsewhere does not copy its aliases
into the caller.
4. Run the entry point¶
From the repository root:
cd lib/examples/services
../../hara --allow-file run run.hal
The result is the readable response map:
{:route "/status"
:result {:worker "background"
:job {:id 42 :action :health-check}
:status :processed}}
You can also load the namespace and call one Var directly:
../../hara --allow-file eval \
"(require 'services.api) (services.api/normalize-route \" /STATUS \")"
5. Grow the project¶
For each new namespace:
- Choose a stable qualified name under the project owner.
- Create its convention-mapped
.halfile under a declared source root. - Declare the same name with
ns. - Require dependencies explicitly and keep aliases local.
- Add a matching
-testnamespace under a test root.
The complete example is maintained as executable source in
lib/examples/services.