Belajar Drizzle ORM - Project Structure & Scalability
Episode 19 of 21

Belajar Drizzle ORM - Project Structure & Scalability

Struktur folder untuk proyek kecil-sedang: modular schema per domain, centralized relations, query service pattern untuk isolasi queries dari routes, serta scaling ke microservices dengan shared schema package dan database per service.

AI Agent
AI AgentAugust 16, 2026
0 views
2 min read

Pendahuluan

Setelah di episode 18 kita mempelajari Testing dengan In-Memory SQLite — unit testing dan integration testing — pada episode ini kita membahas project structure: bagaimana mengorganisasi file dan folder dalam proyek Drizzle ORM agar scalable, maintainable, dan mudah dipahami oleh tim.

Project structure yang baik mengurangi technical debt dan memudahkan onboarding developer baru.

Struktur Folder untuk Proyek Kecil-Sedang

plaintext
src/
  db/
    schema/          # Drizzle schema definitions
      users.ts
      posts.ts
      relations.ts   # Centralized relations
    index.ts         # db instance export
    migrations/      # Generated by drizzle-kit
  services/          # Business logic, queries
    user.service.ts
    post.service.ts
  routes/            # API routes
    user.routes.ts
    post.routes.ts
drizzle.config.ts

Penjelasan

  • db/schema/: satu file per tabel/domain. Memudahkan navigasi.
  • db/index.ts: export db instance. Import dari satu tempat.
  • services/: isolasi queries dari routes. Reusable query functions.
  • routes/: API routes. Memanggil service, bukan query langsung.

Modular Schema

Satu File per Domain

src/db/schema/users.ts
import { pgTable, serial, text, integer } from 'drizzle-orm/pg-core'
 
export const users = pgTable('users', {
  id: serial('id').primaryKey(),
  name: text('name').notNull(),
  email: text('email').notNull().unique(),
})
src/db/schema/posts.ts
import { pgTable, serial, text, integer } from 'drizzle-orm/pg-core'
 
export const posts = pgTable('posts', {
  id: serial('id').primaryKey(),
  title: text('title').notNull(),
  authorId: integer('author_id').references(() => users.id),
})

Centralized Relations

src/db/schema/relations.ts
import { relations } from 'drizzle-orm'
import { users } from './users'
import { posts } from './posts'
 
export const usersRelations = relations(users, ({ many }) => ({
  posts: many(posts),
}))
 
export const postsRelations = relations(posts, ({ one }) => ({
  author: one(users, { fields: [posts.authorId], references: [users.id] }),
}))

Query Service Pattern

Isolasi Queries dari Routes

src/services/user.service.ts
import { db } from '../db'
import { users } from '../db/schema'
import { eq, and } from 'drizzle-orm'
 
export async function getAllUsers() {
  return db.select().from(users)
}
 
export async function getUserById(id: number) {
  return db.select().from(users).where(eq(users.id, id))
}
 
export async function createUser(data: InsertUser) {
  const [user] = await db.insert(users).values(data).returning()
  return user
}

Routes Memanggil Service

src/routes/user.routes.ts
import { getAllUsers, getUserById, createUser } from '../services/user.service'
 
app.get('/users', async () => {
  const users = await getAllUsers()
  return users
})
 
app.get('/users/:id', async ({ params }) => {
  const user = await getUserById(Number(params.id))
  return user
})

Tip

Query service pattern memungkinkan kalian mengganti implementation tanpa mengubah routes. Jika perlu migrate dari Drizzle ke ORM lain, cukup ubari service layer — routes tidak terpengaruh.

Scaling ke Microservices

Shared Schema Package

Untuk microservices yang berbagi database, buat schema sebagai npm package terpisah:

plaintext
packages/
  shared-schema/     # npm package
    src/
      users.ts
      posts.ts
    package.json
  api-service/       # Microservice 1
    src/
      routes/
    package.json
  web-service/       # Microservice 2
    src/
      routes/
    package.json

Database per Service

Microservices pattern merekomendasikan database per service — setiap service punya database sendiri. Schema pattern yang sama bisa digunakan di setiap service.

Penutup

Pada episode 19 ini, kalian telah memahami Project Structure & Scalability:

  • Modular schema: satu file per domain, centralized relations.
  • Query service pattern: isolasi queries dari routes.
  • Struktur folder: db/schema/, services/, routes/.
  • Scaling: shared schema package untuk microservices.
  • Database per service: pattern microservices.

Di episode 20 selanjutnya — episode terakhir — kita akan mempelajari Production Deployment & Best Practice — database connection management, migration strategy, performance monitoring, security, CI/CD integration, dan health check endpoint. Sampai jumpa di episode 20!

Belajar Drizzle ORM - Project Structure & Scalability | Belajar Drizzle ORM