Project Link: Median
This note explains something that can improve the project performance in any aspect as I know haha... :D. Or I just want to put a random note about this project for my personal learning experience.
First of all, actually I have been reading Prisma documentation about indexing in databases, but I found that we can't just simply put that configuration in schema.prisma so to change the index algorithm we need to touch the database itself.
I have been tried using @@index([id], name: "id_hash_idx", type: Hash) in schema.prisma, and what I get is Prisma just create new index with what I spesify before and not applied to id column.
I want to try to change the index algorithm in the id column because the default value for that column is UUIDv4. This UUID is a random string which doesn't have any ordering stuff, so if I just stand with the default Postgres indexing algorithm BTree it can cause more expensive computations to index the data when inserting new data compared to Hash algorithm.
BTree algorithm in Postgres works by simply comparing the new data with existing data and creating a structure like a balance tree. So when we try to search values in a column using this algo to indexing, we don't need to compare the data to the entire data and it makes it faster. You can see this algorithm in more detail with beautifull diagram in this link BTree Diagram.
In this context, when I use UUID in the id column, I don't need to search that column to compare data like literally 1 > 2,3,4...etc if using BTree. I need to exactly find that value match with the parameter I give, so it is more like hjasd = <any id>. Because that I consider to use Hash instead of BTree to indexing the id column.
When you use some of Bun native method, like Bun.password etc. You need to configure nest runner to add parameter --watch \"bun run\". Full command like this bellow.
"start:dev": "nest start --watch --exec \"bun run\""This issue appears when we use global prefix in main.ts, even if we set the prefix exactly the same with path in middleware, the middleware wont work.
You can place this code in prisma.filter.ts. This example I learn from Building a REST API with NestJS and Prisma: Error Handling.
@Catch(PrismaClientKnownRequestError)
export class PrismaFilter extends BaseExceptionFilter {
catch(exception: PrismaClientKnownRequestError, host: ArgumentsHost) {
console.error(exception.message);
const ctx = host.switchToHttp();
const response = ctx.getResponse<Response>();
const message = exception.message.replace(/\n/g, '');
switch (exception.code) {
case 'P2002': {
const status = HttpStatus.CONFLICT;
response.status(status).json({
statusCode: status,
message: message,
});
break;
}
default:
// default 500 error code
super.catch(exception, host);
break;
}
}
}I decided to use manual config not from NestJs because of Nest config pattern. I mean when we need to call ConfigModule building NestJs it only can call inside modules, so if you need to get config and pass it outside the class of nest module you can't do that. This makes calling config not practical to me and a bit complicated to me.
This is how to use NestJs build config, just note how to use it cuz I want to remove it, in case I want to use it again in another project.
-
Install the module
bun i @nestjs/config
-
Apply in
app.module.ts@Module({ imports: [ ConfigModule.forRoot({ isGlobal: true, cache: true }), ... ], }) ...
-
Use config in
main.tsconst config = app.get(ConfigService); const appPort = config.get(APP_PORT);
-
Use config in controller
*.controller.tsexport class UsersController { constructor(private readonly config: ConfigService) {} @Get() async findAll() { const appVer = config.get<string>('APP_VER'); ... } ...
Note: Becuse we import
ConfigModuleas global inapp.module.tswe dont neet to import it in other module, just inject it as constructor.
To generate secret key from OpenSSL it simply run this command
openssl rand -base64 32- Add prisma dependency
bun add -d prisma
- Prisma init
bunx prisma init
- Migrate schema
bunx prisma migrate dev --name "init" - Seed
Make sure you have add this code to
package.jsonAnd then you can seed using"prisma": { "seed": "bun prisma/seed.ts" }
bun prisma db seed
Why I do this instead of write plain password and hashing it in seeder is because when I use Bun.password.hash I need to run that seeder using Bun and I actually can run it but I don't really know why the data it not inputed to db, event the seeder is success run. Solution I do for now is using hashed password as string in seeder and run the seeder using ts-node.