
Api Add Route
- 1 installs
- 108 repo stars
- Updated May 20, 2026
- coleam00/helpline
Adds or changes an HTTP route under services/api following Helpline's gateway conventions: handler, validation, repo call, registration, and test.
About
Walks the exact steps for adding a Helpline API route: write a (request)->dict handler, validate inputs, delegate business logic to a repo, register in routes.py, and add a test. A developer uses it when adding an API route in services/api.
- Handlers orchestrate only; business logic lives in repos
- Unregistered routes do not exist; a test is required
Api Add Route by the numbers
- 1 all-time installs (skills.sh)
- Ranked #3,818 of 4,348 Backend & APIs skills by installs in the Skillselion catalog
- Data as of Jul 29, 2026 (Skillselion catalog sync)
npx skills add https://github.com/coleam00/helpline --skill api-add-routeAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 1 |
|---|---|
| repo stars | ★ 108 |
| Last updated | May 20, 2026 |
| Repository | coleam00/helpline ↗ |
What it does
Adds or changes an HTTP route under services/api following Helpline's gateway conventions: handler, validation, repo call, registration, and test.
Files
Adding an API route
Activates for work in services/api. Follow these steps in order.
1. Write the handler in the matching module (tickets.py for ticket routes, a new module for a new noun). Signature is (request: dict) -> dict. 2. Validate inputs first. Missing/!bad input raises ValidationError — never return an error dict by hand. 3. Do no business logic here. Call a repo (packages/db) or another service. The handler only orchestrates and shapes the response. 4. Register the route in routes.py inside build_app() — app.route("METHOD /path", handler). A route not registered there does not exist. 5. Add a test in tests/ that builds the app and dispatches the route.
Full checklist with a worked example: references/route-checklist.md.
Route checklist — full reference
Worked example — GET /tickets/{id}
# services/api/tickets.py
def get_ticket(request: dict[str, Any]) -> dict[str, Any]:
ticket_id = request.get("ticket_id")
if not ticket_id:
raise ValidationError("ticket_id is required")
ticket = TicketRepo(get_connection()).get(str(ticket_id)) # raises NotFoundError
return {"id": ticket.id, "status": ticket.status.value, "subject": ticket.subject}# services/api/routes.py — inside build_app()
app.route("GET /tickets/{id}", get_ticket)Checklist
- [ ] Handler signature is
(request: dict) -> dict - [ ] Inputs validated; bad input raises
ValidationError - [ ] Missing rows surface as
NotFoundError(repos already do this) - [ ] No pricing/hashing/indexing logic in the handler
- [ ] Route registered in
build_app() - [ ] Test added that builds the app and dispatches the route
- [ ]
uv run pytest services/apipasses
Why errors are raised, not returned
App.dispatch wraps every handler call in a try/except HelplineError and maps .status_code to the response. A handler that returns {"status": 404} by hand bypasses that and will drift out of sync with the error contract in packages/core/errors.py.