TT Lab
Get started
Learn Learning paths Courses

Node.js Backend — What the Framework Hides

The Shape You Store Is Not the Shape You Return

Continue in TT Lab

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.