Node.js Backend — What the Framework Hides
The Shape You Store Is Not the Shape You Return
In one line
The shape you store and the shape you send out are different. A large share of backend incidents come from not keeping to this one line.
Why it is needed: incidents happen silently
Say you add one more column, internal_memo, to the orders table. The handler stays the same.
The single line return order is still there, and all the tests pass. But from that moment,
the internal memo goes out in the API response.
Nobody sees an error. The logs are normal too. Nobody realizes that adding one column was an API change.
Decide it in one place
The place to fix is not the handler. Keep the fields to send out in one place and let only those through.
const publicItem = ({ id, name, qty }) => ({ id, name, qty });
What matters is that this is an allowlist. If you write it the removing way, like delete item.secret,
the next time a column is added it leaks again. Instead of counting what to remove,
you should count what to send out.
In the field
What Nest's ClassSerializerInterceptor and FastAPI's response_model do is
exactly this. The names differ, but the judgment is the same: make fields get filtered without touching
the handler code.
There is also one thing to look for in code review. In a PR that adds a new column, check whether the output shape was changed together with it, or whether it was left to flow out automatically. In the latter case, that PR is an API change that nobody has called one.