Typed CRUD

Insert users and notes

Insert typed values, let the database own generated columns, and use returned rows instead of making a fragile second lookup.

8 minute lesson

~~~

An insert should contain the values the caller owns. IDs, timestamps, and defaults can stay with the database.

Drizzle derives the accepted insert shape from the table. Required values are required by TypeScript, while generated and defaulted columns may be omitted. SQLite supports returning(), so we can receive the row created by this statement.

const [user] = await db
  .insert(users)
  .values({
    email: '[email protected]',
    name: 'Flavio',
  })
  .returning()

A unique email conflict is an expected database outcome. Translate it into a useful application error without exposing raw SQL or assuming every database error means the same thing.

Never spread an untrusted request object directly into .values(). Build the allowed object field by field after runtime validation. TypeScript checks your code, not the JSON sent by a browser.

Insert one user and one note for that user, then save the returned rows. Attempt a duplicate email and an unknown author ID, and record which database rule rejects each write.

Lesson completed

Take this course offline

Get every free book and course as PDF and EPUB files.

Get the download library →