1REST to SQL
The connection between REST APIs and SQL is one-to-one.
HTTP POST = SQL INSERT
HTTP GET = SQL SELECT
HTTP PUT/PATCH = SQL UPDATE
HTTP DELETE = SQL DELETE.
Understanding this makes backend development intuitive.
2Step-by-Step Breakdown
Beyond Reading. So far, we have only looked at DQL (Data Query Language) using SELECT. We haven't actually changed any data. Now we shift to DML.
The 3 DML Commands. There are three primary commands to mutate state: INSERT (Create), UPDATE (Modify), and DELETE (Destroy). Together with SELECT (Read), they form CRUD.
DML and Node.js. When a user submits a registration form in React, Node receives it via POST, and executes an INSERT command. When they change their password via PUT, Node executes an UPDATE command.
The Danger of DML. A SELECT query is perfectly safe. If you mess up, you just get an error. If you mess up an UPDATE query, you can permanently overwrite 100,000 passwords. There is no 'Undo' button.
Knowledge Check. Why are DML commands (UPDATE, DELETE) considered vastly more dangerous than DQL commands (SELECT)?
- →Because DML permanently mutates data on the hard drive, while DQL only reads it
- →Because DML commands bypass security passwords
Transactions. Because DML is dangerous, enterprise databases use 'Transactions'. You start a transaction, run your DML commands, check if everything looks okay, and then 'COMMIT' to save them.
RETURNING Data. Normally, DML commands just return 'Success'. But in Postgres, you can add 'RETURNING *' to an INSERT or UPDATE statement to immediately get the newly created/modified row back in Node.
Constraints checking. When you execute DML, the engine checks all DDL constraints. If you try to INSERT an age of -5, and a 'CHECK (age > 0)' constraint exists, the DML command is rejected.
Triggers. Databases can have 'Triggers'. These are automated functions that run whenever DML happens. E.g., 'If a user runs an UPDATE on salary, automatically log it in the audit table'.
Summary. DML is the engine behind every POST, PUT, and DELETE API route.
Level Up 🚀
Advanced cheat sheets, SEO tricks, and interview prep for this topic.
Browser Support
Fully supported.
Fully supported.
Fully supported.
Fully supported.
Accessibility (A11y)
1Every Mutating Form Submission Needs Clear Success/Failure Feedback
When a form submission triggers an INSERT or UPDATE, the resulting success or validation-error message must be announced via an aria-live region, since a screen reader user has no other way to know their DML operation actually committed or was rejected by a constraint.
SEO Implications
- 1
DML Performance Affects Perceived Page Speed After User Actions
An UPDATE or INSERT that's slow because it lacks a proper index on its WHERE clause directly delays the response a user sees after submitting a form, which factors into Google's interaction-focused Core Web Vitals like Interaction to Next Paint.
Best Practices
Wrap Multi-Step Mutations in a Transaction
Any time an API request needs to run more than one DML statement that must succeed or fail together (e.g. deducting stock and creating an order), wrap them in BEGIN/COMMIT with a ROLLBACK in the catch block, so a failure partway through never leaves the database in an inconsistent state.
Use RETURNING Instead of a Second Round-Trip Query
After an INSERT or UPDATE in PostgreSQL, add RETURNING * (or specific columns) to get the resulting row back immediately, instead of running a separate SELECT afterward to fetch the same data.
Frequent Bugs
An UPDATE or INSERT succeeds in the database but the API route still throws an unhandled error and returns a 500.
This usually happens when a database CHECK or NOT NULL constraint rejects part of a batch operation, or when the driver's promise rejection isn't caught — always wrap DML calls in try/catch and inspect the database error code to distinguish a constraint violation from a connection failure.
Real-World Examples
Mapping a REST PATCH Request to a Safe SQL UPDATE
A Node.js API route needed to update a user's profile and immediately return the updated row to the frontend, without a second query.
UPDATE users
SET name = $1, bio = $2, updated_at = NOW()
WHERE id = $3
RETURNING id, name, bio, updated_at;