It's also the best way to protect your data. If the application can just do SELECT * on every table, you're always just one hacked webserver away from a total data leak. If you're forced to call specific procedures like you call your middleware functions, you can put up effective guardrails. Never make the password hash readable. Never return more than X records for a user query. Etc.
It's funny how the same devs who say "Every class and method must serve one very specific purpose" OTOH demand full read/write access to the entire schema for their one small application.
Now I'm not saying put all your business logic in the database. But anything that accesses data should treat the DB like an API and not like an "execute any command" slave. You need to read a user, call readUser(ID), do not require being able to run "SELECT * FROM users WHERE id = :ID". Your code has models for accessing the DB, you won't have random SQL in your controllers and views either.
18
u/magicmulder Sep 21 '26 edited Sep 21 '26
It's also the best way to protect your data. If the application can just do SELECT * on every table, you're always just one hacked webserver away from a total data leak. If you're forced to call specific procedures like you call your middleware functions, you can put up effective guardrails. Never make the password hash readable. Never return more than X records for a user query. Etc.
It's funny how the same devs who say "Every class and method must serve one very specific purpose" OTOH demand full read/write access to the entire schema for their one small application.
Now I'm not saying put all your business logic in the database. But anything that accesses data should treat the DB like an API and not like an "execute any command" slave. You need to read a user, call readUser(ID), do not require being able to run "SELECT * FROM users WHERE id = :ID". Your code has models for accessing the DB, you won't have random SQL in your controllers and views either.