@@ -129,35 +129,46 @@ OpenSearch (for search/indexing), and Moqui itself.
129129
130130** Starting the Moqui server:**
131131
132- ** IMPORTANT** : Run the Moqui server in a subagent (using the Task tool with
133- general agent) so it runs in the background and can be easily stopped by
134- terminating the subagent task. This keeps server logs isolated and makes process
135- management simple.
132+ Start the server in the background and wait for it to be ready:
136133
137134``` bash
138- # In subagent - this blocks and keeps running
139- ./gradlew run
135+ # Start server in background (output goes to /tmp/moqui-server.log)
136+ nohup ./gradlew run > /tmp/moqui-server.log 2>&1 &
137+
138+ # Wait for server to be ready (typically 30-60 seconds)
139+ for i in {1..60}; do
140+ if grep -q " Started oejs.ServerConnector.*8080" /tmp/moqui-server.log 2> /dev/null; then
141+ echo " Server is ready!"
142+ break
143+ fi
144+ sleep 1
145+ done
140146```
141147
142- ** Verifying Server Startup** :
143-
144- The server typically takes 30-60 seconds to start. Monitor for this log message
145- to confirm readiness:
148+ ** Verifying Server is Running** :
146149
147150``` bash
148- # In the subagent output or runtime/log/moqui.log, look for:
149- Started oejs.ServerConnector@...{HTTP/1.1, (http/1.1)}{0.0.0.0:8080}
151+ # Test with a simple REST call
152+ curl -u john.doe:moqui http://localhost:8080/rest/s1/mantle/parties
153+
154+ # Or check the log for the startup message
155+ grep " Started oejs.ServerConnector.*8080" /tmp/moqui-server.log
150156```
151157
152- This message confirms Jetty is listening on port 8080. After seeing this, test with:
158+ ** Stopping the Server** :
159+
153160``` bash
154- curl -u john.doe:moqui http://localhost:8080/rest/s1/mantle/parties
161+ # Find and kill the Gradle process
162+ pkill -f " gradlew run"
163+
164+ # Or find the specific PID
165+ ps aux | grep " gradlew run" | grep -v grep | awk ' {print $2}' | xargs kill
155166```
156167
157168** Notes:**
158169- ` ./gradlew run ` does NOT auto-start OpenSearch - start it manually first with
159170 ` ./gradlew startElasticSearch `
160- - Server logs available in subagent output AND in ` runtime/log/moqui.log `
171+ - Server logs available in ` /tmp/moqui-server.log ` AND in ` runtime/log/moqui.log `
161172- If the server doesn't respond after seeing the log message, wait 5-10 more
162173 seconds for full initialization
163174
@@ -183,7 +194,7 @@ loaded and verified before testing.
183194** Loading Data** :
184195``` bash
185196./gradlew load # Loads all data types (safest - handles dependencies)
186- ./gradlew load -Ptypes=demo # Load only demo (requires seed to be loaded first)
197+ ./gradlew load -Ptypes=demo # Load only demo (requires other data to be loaded first)
187198```
188199
189200** Data File Format** - Use full entity names in component's ` data/ ` directory:
@@ -250,11 +261,36 @@ creates namespace `mantle.order.OrderServices`. Services defined as
250261
2512621 . ** ServiceRun UI** (Recommended for development/testing):
252263 - Test ANY service without modifying REST configuration
264+
265+ ** Browser UI** :
253266 - Navigate to: http://localhost:8080/qapps/tools/Service/ServiceRun
254- - Enter service name: ` mantle.order.OrderServices. get#OrderInfo `
267+ - Enter service name: ` org.moqui.impl.BasicServices. get#GeoRegionsForDropDown `
255268 - Fill parameters in the form and submit
256269 - See results immediately
257270
271+ ** Programmatic (curl)** :
272+ ``` bash
273+ # Basic pattern - all parameters go in JSON body
274+ curl -X POST -H " Content-Type: application/json" \
275+ -u john.doe:moqui \
276+ -d ' {"serviceName": "service.path.verb#Noun", "param1": "value1", "param2": "value2"}' \
277+ http://localhost:8080/apps/tools/Service/ServiceRun/runJson
278+
279+ # Example: Get geo regions with parameters
280+ curl -X POST -H " Content-Type: application/json" \
281+ -u john.doe:moqui \
282+ -d ' {"serviceName": "org.moqui.impl.BasicServices.get#GeoRegionsForDropDown", "geoId": "USA"}' \
283+ http://localhost:8080/apps/tools/Service/ServiceRun/runJson
284+
285+ # Example: Service with no parameters (noop)
286+ curl -X POST -H " Content-Type: application/json" \
287+ -u john.doe:moqui \
288+ -d ' {"serviceName": "org.moqui.impl.BasicServices.noop"}' \
289+ http://localhost:8080/apps/tools/Service/ServiceRun/runJson
290+ ```
291+
292+ ** Note** : The ` runJson ` endpoint accepts ANY service name and returns JSON responses - perfect for testing and automation without creating custom REST definitions.
293+
2582942 . ** Custom REST API** (For production/integration):
259295 - Define in ` *.rest.xml ` files using resource/id structure (see
260296 rest-api-3.xsd)
@@ -291,29 +327,49 @@ When implementing or modifying services, follow this iterative workflow:
291327
2923282 . ** Test immediately** (no server restart needed for service changes - changes
293329 take effect after a few seconds):
294-
330+
295331 ** Option A: ServiceRun UI** (Fastest - no REST config needed):
296332 - Navigate to: http://localhost:8080/qapps/tools/Service/ServiceRun
297- - Enter service name: ` mantle.order.OrderServices. get#OrderInfo `
333+ - Enter service name: ` org.moqui.impl.BasicServices. get#GeoRegionsForDropDown `
298334 - Fill parameters in the form and submit
299335 - View results immediately in the UI
300-
336+
337+ ** Option A (Programmatic)** : Use the ` runJson ` endpoint (see "Three Ways to Access Services" above for curl examples)
338+
301339 ** Option B: Custom REST API** (if service already exposed in ` *.rest.xml ` ):
302340 ``` bash
303341 curl -X POST -H " Content-Type: application/json" \
304342 -u john.doe:moqui \
305343 -d ' {"inputMessage": "test"}' \
306344 http://localhost:8080/rest/s1/example/testAgent
307345 ```
308-
346+
309347 ** Note** : Wait 3-5 seconds after saving service changes for cache refresh
310348 before testing.
311349
312- 3 . ** Monitor the server console output** from ` ./gradlew run ` for:
313- - Execution logs showing service calls
314- - Error messages and stack traces
350+ 3 . ** Monitor the server output** for errors and execution details:
351+
352+ ``` bash
353+ # Check server logs for errors (successful calls may not log in production mode)
354+ tail -30 /tmp/moqui-server.log
355+
356+ # Or check the runtime log file
357+ tail -30 runtime/log/moqui.log
358+
359+ # To observe both service response AND logs in one command:
360+ curl -X POST -H " Content-Type: application/json" \
361+ -u john.doe:moqui \
362+ -d ' {"serviceName": "org.moqui.impl.BasicServices.get#GeoRegionsForDropDown", "geoId": "USA"}' \
363+ http://localhost:8080/apps/tools/Service/ServiceRun/runJson \
364+ && echo " " && echo " === Checking logs ===" && tail -20 /tmp/moqui-server.log
365+ ```
366+
367+ ** What to look for in logs** :
368+ - Error messages and stack traces (logged with ERROR or WARN level)
315369 - Parameter validation failures
316370 - Transaction issues
371+ - SQL errors for entity operations
372+ - ** Note** : Successful service calls typically don't generate detailed logs in production mode
317373
3183744 . ** Examine the response** :
319375 - Check the JSON response from curl for service output parameters
@@ -330,26 +386,37 @@ When adding or modifying entities:
330386
3313872 . ** Restart the server** (entity definition changes require restart):
332388 ``` bash
333- # Stop the running server (terminate subagent task)
334- # Then start it again in a new subagent
335- ./gradlew run
389+ # Stop the running server
390+ pkill -f " gradlew run"
391+
392+ # Start it again in background
393+ nohup ./gradlew run > /tmp/moqui-server.log 2>&1 &
394+
395+ # Wait for server to be ready
396+ for i in {1..60}; do
397+ if grep -q " Started oejs.ServerConnector.*8080" /tmp/moqui-server.log 2> /dev/null; then
398+ echo " Server is ready!"
399+ break
400+ fi
401+ sleep 1
402+ done
336403 ```
337404
3384053 . ** Test entity operations** :
339-
406+
340407 ** Option A: EntityDataFind UI** (Recommended - most visual and interactive):
341408 - Navigate to:
342409 http://localhost:8080/qapps/tools/Entity/DataEdit/EntityDataFind?selectedEntity=YourEntityName
343410 - Search, create, edit, or delete records through the UI
344411 - Immediately see results and validation errors
345-
412+
346413 ** Option B: Custom REST API** (if exposed in ` *.rest.xml ` ):
347414 ``` bash
348415 # Find/list records via custom REST API (e.g., mantle.rest.xml)
349416 curl -X GET -u john.doe:moqui \
350417 http://localhost:8080/rest/s1/mantle/parties
351418 ```
352-
419+
353420 ** Note** : Entity REST API (/rest/e1/) requires special permissions not
354421 granted by default to john.doe user
355422
@@ -402,7 +469,21 @@ When developing screens (XML widget system → FreeMarker macros → HTML):
402469
403470** REST APIs** (For programmatic access):
404471
405- Three types of REST APIs are available:
472+ Four types of REST APIs are available:
473+
474+ 0 . ** ServiceRun JSON API** (` /apps/tools/Service/ServiceRun/runJson ` ):
475+ - Test ANY service programmatically without REST configuration
476+ - Pass service name and parameters in JSON body
477+ - Returns JSON response from service
478+ - Example curl:
479+ ``` bash
480+ curl -X POST -H " Content-Type: application/json" \
481+ -u john.doe:moqui \
482+ -d ' {"serviceName": "org.moqui.impl.BasicServices.get#GeoRegionsForDropDown", "geoId": "USA"}' \
483+ http://localhost:8080/apps/tools/Service/ServiceRun/runJson
484+ ```
485+ - Most flexible for agentic development and testing
486+ - Full access with john.doe credentials
406487
4074881. ** Custom REST API** (` /rest/s1/{api-name}/...` or ` /rest/s2/...` ):
408489 - Services/entities MUST be explicitly defined in ` * .rest.xml` files
@@ -524,9 +605,21 @@ grep "your-change-marker" path/to/YourService.xml
524605**Entity Changes Not Visible**:
525606```bash
526607# Entity changes REQUIRE server restart
527- # 1. Stop server (terminate subagent task)
528- # 2. Start server again: ./gradlew run
608+ # 1. Stop server
609+ pkill -f "gradlew run"
610+
611+ # 2. Start server again in background
612+ nohup ./gradlew run > /tmp/moqui-server.log 2>&1 &
613+
529614# 3. Wait for: Started oejs.ServerConnector.*8080
615+ for i in {1..60}; do
616+ if grep -q "Started oejs.ServerConnector.*8080" /tmp/moqui-server.log 2>/dev/null; then
617+ echo "Server is ready!"
618+ break
619+ fi
620+ sleep 1
621+ done
622+
530623# 4. Test with EntityDataFind UI
531624```
532625
0 commit comments