-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: use NestJS design patterns (#37)
* Working postgres integration * Remove optional fields from user create * Move credentials to an env file * chore: add convenience db scripts * refactor: linting * fix: make migrate.ts work from root + this fixes the necessity to cd to src/db to apply migrations and allows executing the script from anywhere * refactor: move things around to mimic nestjs Move things around to a NestJS-like resource based structure, based on plural and not singular * refactor: move one more file * fix: remove bad script * fix: db/config.ts catch all schemas * feat: use decorators * refactor: index.ts > main.ts this is more inline with nestjs standards * refactor: denest 1 level * refactor: denest 1 level * refactor: abstract db from service --------- Co-authored-by: Hajbo <[email protected]>
- Loading branch information
Showing
17 changed files
with
127 additions
and
46 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import {drizzle} from "drizzle-orm/postgres-js"; | ||
import {migrate} from "drizzle-orm/postgres-js/migrator"; | ||
import {migrationClient} from "@/database.providers"; | ||
|
||
await migrate(drizzle(migrationClient), {migrationsFolder: `${import.meta.dir}`}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,7 @@ | ||
import { exit } from 'process'; | ||
import { db } from './index'; | ||
import { users } from './schemas/users'; | ||
import { db } from '@/database.providers'; | ||
import {users} from "@/users/users.schema"; | ||
|
||
|
||
console.log("Migrations complete.") | ||
const data = { | ||
id: users.id.default, | ||
email: '[email protected]', | ||
|
@@ -19,4 +17,4 @@ console.log("User inserted") | |
const userResult = await db.select().from(users); | ||
console.log("User result: ", userResult); | ||
|
||
exit(0); | ||
exit(0); |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
// the file name is in the spirit of NestJS, where app module is the device in charge of putting together all the pieces of the app | ||
// see: https://docs.nestjs.com/modules | ||
|
||
import { Elysia } from "elysia"; | ||
import UsersService from "./users/users.service"; | ||
import UsersController from "./users/users.controller"; | ||
import { db } from "@/database.providers"; | ||
|
||
// the word 'setup' (instead of e.g. 'bootstrap') is in correspondence with the official elysiajs docs | ||
// see: https://elysiajs.com/patterns/dependency-injection.html#dependency-injection | ||
|
||
export const setup = () => { | ||
const usersService = UsersService(db); | ||
const usersController = UsersController(usersService); | ||
|
||
return new Elysia() | ||
.use(usersController) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import { drizzle, PostgresJsDatabase } from 'drizzle-orm/postgres-js'; | ||
import postgres from 'postgres'; | ||
import { dbCredentialsString } from '@db/config'; | ||
|
||
// for migrations | ||
export const migrationClient = postgres(dbCredentialsString, { max: 1 }); | ||
|
||
// for query purposes | ||
export const queryClient = postgres(dbCredentialsString); | ||
|
||
export const db: PostgresJsDatabase = drizzle(queryClient); |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import { Elysia } from "elysia"; | ||
import {UsersService} from "@/users/users.service"; | ||
|
||
// Below are some ideas for how to structure the controller-service relationship. | ||
|
||
// Idea 1: use 'Dependency Injection' to inject the service into the controller | ||
// Pros: follows ElysiaJS docs (https://elysiajs.com/patterns/dependency-injection.html) | ||
// Cons: we must explicitly refer to the service in every single route | ||
|
||
// export default new Elysia({prefix: '/users'}) | ||
// .decorate("usersService", new UsersService()) | ||
// .get("/", async ({usersService}) => { | ||
// return usersService.findAll(); | ||
// }) | ||
|
||
// Idea 2: use a class to wrap the controller and service | ||
// Pros: follows NestJS conventions (https://github.com/lujakob/nestjs-realworld-example-app/blob/master/src/user/user.controller.ts) | ||
// Cons: too noisy, too nested (ha), requires calling the controller with an awkward 'controller.controller' syntax | ||
|
||
// export class UsersController { | ||
// constructor(private readonly usersService: UsersService) {} | ||
// | ||
// get controller() { | ||
// return new Elysia({prefix: '/users'}) | ||
// .get("/", () => { | ||
// return this.usersService.findAll(); | ||
// }) | ||
// } | ||
// } | ||
|
||
// Idea 3: use a factory function to wrap the controller and service | ||
// Pros: simple, supports 'Method Chaining', follows NestJS conventions (in broad strokes) | ||
// Cons: none | ||
|
||
export default (usersService: UsersService) => new Elysia({prefix: '/users'}) | ||
.get("/", () => { | ||
return usersService.findAll(); | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import {users} from "./users.schema"; | ||
import {PostgresJsDatabase} from "drizzle-orm/postgres-js"; | ||
|
||
// note that we should specifically NOT import the db and use it here | ||
// so we can mock it in tests and switch it out as needed | ||
// also, this would hurt the single responsibility principle. | ||
|
||
export class UsersService { | ||
|
||
// the type here is | ||
constructor(private readonly db: PostgresJsDatabase) {} | ||
|
||
async findAll() { | ||
return this.db.select().from(users); | ||
} | ||
} | ||
|
||
// export a factory for consistency with other providers (like the controller) | ||
export default (db: PostgresJsDatabase) => new UsersService(db); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters