Writing1 min read

Engineering Notes

API Endpoints That Stay Small

One route that did validation, mapping, and side effects.

One route handled validation, mapping, and side effects

PATCH /orders/:id grew every sprint. It validated input, recalculated tax, wrote audit logs, and fired webhooks.

Tests needed six mocks to assert one branch. Nobody wanted to touch it.


Shipping through the handler

Feature pressure was high. The handler was the fastest place to ship. The cost showed up in regressions.


Six mocks for one branch

When a route cannot be described in one sentence, it is doing too many jobs.

Failures were hard to classify because layers were fused together.


One job per route

Validate at the edge. Keep handlers thin. Let services own rules and repositories own persistence.

One job per endpoint makes tests small and failures obvious.


Thin handler shape

Request flow
After split
async updateStatus(id: string, dto: StatusDto) {
  const order = await this.orders.find(id);
  const next = this.statusRules.apply(order, dto.status);
  await this.orders.save(next);
  await this.events.publish('order.status_changed', { id });
}

Split before conditionals win

If you cannot describe the endpoint in one sentence, split it before the conditionals win.


References