Skip to content

Commit

Permalink
Merge branch 'master' into mantine7.v4
Browse files Browse the repository at this point in the history
  • Loading branch information
alodela authored Nov 2, 2024
2 parents 0104168 + 20a0904 commit ba364b7
Showing 1 changed file with 9 additions and 9 deletions.
18 changes: 9 additions & 9 deletions documentation/blog/2024-10-31-drizzle.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ In the later part of the post, we demonstrate how to configure Drizzle, set up P

## What is Drizzle ORM ?

Drizzle ORM is a TypeScript based data framework that maps database entitites to programmable objects via Object Relational Mapping. ORMs like Drizzle help connect to a database server and execute queries and operations via object based APIs. In a JavaScript / TypeScript ORM, each type of database entity is represented by a JS/TS prototype. Tables are generated for each prototype, columns are represented by fields and attributes, while rows are created for each instance of the prototypes.
Drizzle ORM is a TypeScript based data framework that maps database entities to programmable objects via Object Relational Mapping. ORMs like Drizzle help connect to a database server and execute queries and operations via object based APIs. In a JavaScript / TypeScript ORM, each type of database entity is represented by a JS/TS prototype. Tables are generated for each prototype, columns are represented by fields and attributes, while rows are created for each instance of the prototypes.

### Drizle ORM: The Core and Opt-in Packages

Drizzle ORM consists of the core `drizzle-orm` package, which is considered the headless part. The core supports different SQL databases, such as PostgreSQL, MySQL, SQLite alongside their different modes. For example, for our demo application in this post, we'll make use of the `drizzle-orm/pg-core` subpackage to connect to an extenally running PostgreSQL database.
Drizzle ORM consists of the core `drizzle-orm` package, which is considered the headless part. The core supports different SQL databases, such as PostgreSQL, MySQL, SQLite alongside their different modes. For example, for our demo application in this post, we'll make use of the `drizzle-orm/pg-core` subpackage to connect to an externally running PostgreSQL database.

Then there are opt-in packages for different kinds of adapters for these databases and backend services built from them. For example, for Postgres, we can use the `drizzle-orm/node-postgres` driver to run Postgres connection in a Node.js environment. Other drivers supported by Drizzle include PostgresJS, Neon, Supabase, etc. Similar driver support exists for MySQL and SQLite. You can find the lists of dialects and drivers supported by Drizzle [here](https://orm.drizzle.team/docs/get-started-postgresql).

Expand All @@ -50,11 +50,11 @@ Drizzle's schema based entity and relations definitions make migrations easy by

Database connections, migration and sseeding are handled by Drizzle's opt-in driver adapters for chosen SQL dialects. For example, in this post, we are going to consider the `pg` package and `drizzle-orm/node-postgres` subpackage for connecting PostgreSQL to a Node.js runtime, performing table migrations, and performing data operations on them.

Drizzle can be used to serve backend APIs from a JavaScript-based runtime such as Node, Deno or serverless functions. The same Drizzle tools can be used in the frontend with any server rendered JS frontend frameowrk such as Next.js, Svelte, etc.
Drizzle can be used to serve backend APIs from a JavaScript-based runtime such as Node, Deno or serverless functions. The same Drizzle tools can be used in the frontend with any server rendered JS frontend framework such as Next.js, Svelte, etc.

:::tip The Database Server Runs Independent of Drizzle

It is important to note that, the database server used with Drizzle must be created and run seperately. Drizzle only needs a database `url` from a database that's is already created, running, and waiting for connections.
It is important to note that, the database server used with Drizzle must be created and run separately. Drizzle only needs a database `url` from a database that's is already created, running, and waiting for connections.

:::

Expand Down Expand Up @@ -115,7 +115,7 @@ We need to use the `where()` method to invoke the SQL `WHERE` clause. With `wher

:::warning Drizzle Filtering Helpers Are a passing

Honestly speaking, Drizzle filter helpers fail to uphold the SQL-like motivation. There are functions for all filtering operations, and although their namings sound the same, their functional implmentation contribute to poor readability. Drizzle filters produce long and multiple lines of nested clumsy code, particularly when queries need multiple filters with `and()` and `or()` operators. For example, the following:
Honestly speaking, Drizzle filter helpers fail to uphold the SQL-like motivation. There are functions for all filtering operations, and although their namings sound the same, their functional implementation contribute to poor readability. Drizzle filters produce long and multiple lines of nested clumsy code, particularly when queries need multiple filters with `and()` and `or()` operators. For example, the following:

```ts
const postsList = db
Expand Down Expand Up @@ -256,9 +256,9 @@ Database schemas in Drizzle serve a multitude of roles. They are used for:
- defining relations between tables.
- produce TypeScript types for database entities.

:::tip Drizzle Schemas Act as Singel Source of Truth
:::tip Drizzle Schemas Act as Single Source of Truth

These features makes Drizzle schemas a single source of truth for comprehensively yet so easily managing table definitions, migrations, relations and TypeScript entity types. So, at any point when we consider we'd need to add/change a field, we can directly alter the schema accordingly. Upon invocation, Drizzle autmatically produces necessary migrations imposed by the changes. And all TypeScript types are inferred according to the latest schema version.
These features makes Drizzle schemas a single source of truth for comprehensively yet so easily managing table definitions, migrations, relations and TypeScript entity types. So, at any point when we consider we'd need to add/change a field, we can directly alter the schema accordingly. Upon invocation, Drizzle automatically produces necessary migrations imposed by the changes. And all TypeScript types are inferred according to the latest schema version.

:::

Expand Down Expand Up @@ -365,7 +365,7 @@ export const categoriesRelations = relations(categories, ({ many }) => ({

#### Drizzle Schemas: Generating TypeScript Entity Types

Perhaps the most standout feature of Drizzle schemas is the ability to generate TypeScript types from entity table definitions. Or using `zod.infer<>` In Drizzle, we are able to derive Zod schemas from table definitions by passing the table definitio to the `createInsertSchema()` and `createSelectSchema()` functions. We can then generate necessary type definitions using `zod.infer<>`. For example the type definitions for `posts` are derived like this:
Perhaps the most standout feature of Drizzle schemas is the ability to generate TypeScript types from entity table definitions. Or using `zod.infer<>` In Drizzle, we are able to derive Zod schemas from table definitions by passing the table definition to the `createInsertSchema()` and `createSelectSchema()` functions. We can then generate necessary type definitions using `zod.infer<>`. For example the type definitions for `posts` are derived like this:

```ts
export const PostSchema = createSelectSchema(posts);
Expand Down Expand Up @@ -814,7 +814,7 @@ Please feel free to examine them inside the `drizzle` branch of the repository.

Invoking mutations with Drizzle must also happen serverside. This is because Drizzle `db` connection placed inside `./src/drizzle/db.ts` is not accessible from client side. So, we have to split all `/new` pages to have forms render client side and define mutation actions server side -- both explicitly. That way, the form makes the mutation action accessible from client side, and eventual invocation is made from serverside.

For example, for the page `/posts/new` route, we have form data handled client side dyanmically using React Hook Form and Zod inside `<CreatePostForm />`:
For example, for the page `/posts/new` route, we have form data handled client side dynamically using React Hook Form and Zod inside `<CreatePostForm />`:

<details>
<summary>Show Client Rendered `<CreatePostForm />`</summary>
Expand Down

0 comments on commit ba364b7

Please sign in to comment.