4. Try it#
What this step does. Exercises the full API with
curl— seeding, querying, updating, upserting by natural key, deleting — to confirm the handlers are wired correctly before any frontend code exists.
Restart the app and hit the endpoints with curl.
Seed a few departments#
curl -sX POST http://localhost:8080/api/department \
-H 'Content-Type: application/json' \
-d '{"code":"HR", "name":"Human Resources"}'
curl -sX POST http://localhost:8080/api/department \
-H 'Content-Type: application/json' \
-d '{"code":"ENG", "name":"Engineering"}'
curl -sX POST http://localhost:8080/api/department \
-H 'Content-Type: application/json' \
-d '{"code":"SALES", "name":"Sales"}'List them back:
curl -s 'http://localhost:8080/api/department?_orderBy=code&_total=true'{
"result": [
{ "id": 2, "code": "ENG", "name": "Engineering", "description": null },
{ "id": 1, "code": "HR", "name": "Human Resources", "description": null },
{ "id": 3, "code": "SALES", "name": "Sales", "description": null }
],
"limit": 15,
"offset": 0,
"total": 3
}Create an employee#
curl -sX POST http://localhost:8080/api/employee \
-H 'Content-Type: application/json' \
-d '{
"loginName": "ada@example.com",
"firstName": "Ada",
"lastName": "Lovelace",
"department": { "id": 2 },
"joiningDate": "2025-11-03",
"status": "ACTIVE"
}'Query employees#
Filter by flattened parent column (Palmyra adds the JOIN automatically):
curl -s 'http://localhost:8080/api/employee?departmentCode=ENG&_orderBy=lastName'{
"result": [
{
"id": 1,
"loginName": "ada@example.com",
"firstName": "Ada",
"lastName": "Lovelace",
"department": { "id": 2, "code": "ENG", "name": "Engineering" },
"departmentCode": "ENG",
"joiningDate": "2025-11-03",
"status": "ACTIVE"
}
],
"limit": 15,
"offset": 0
}Update by primary key#
curl -sX POST http://localhost:8080/api/employee/1 \
-H 'Content-Type: application/json' \
-d '{ "status": "RESIGNED" }'Upsert by natural key#
preferredKey = "loginName" lets the same POST route either insert or update:
curl -sX POST http://localhost:8080/api/employee \
-H 'Content-Type: application/json' \
-d '{ "loginName": "ada@example.com", "lastName": "Lovelace-Byron" }'The row is matched on loginName, so this updates employee 1 — no need to know the surrogate id on the client.
Delete#
curl -sX DELETE http://localhost:8080/api/employee/1Backend is done. The frontend track consumes exactly these endpoints.
More queries to try#
- Sort by multiple columns. Comma-separate — prefix with
-for DESC:curl -s 'http://localhost:8080/api/employee?_orderBy=status,-joiningDate' - Exact-match filter on a joined column. The flattened
departmentCodeworks, but you can also filter on the full path:Palmyra adds the JOIN automatically — same ascurl -s 'http://localhost:8080/api/employee?department.code=ENG'departmentCode=ENG. - Large page with total count. For admin dashboards that need the total even on a big page:
curl -s 'http://localhost:8080/api/employee?_limit=200&_total=true' - Single-record read. Identity lookup by primary key:
Returns the bare object, no envelope.
curl -s http://localhost:8080/api/employee/1