How to use NestJS with Turso Tech
a remote sqlite db
Post by Pedro Resende on the 28 of August of 2024 at 18:30
Tags: devdevelopmenttutorialsqlitetursonestjs
This week, I've decided to spend some time investigating how hard it would be to use Nest.js with turso.tech.
What is turso.tech? It's a remote sqlite db or what they mention a SQLite for Production hosted in the cloud.
The free tier, it's quite interesting. It allows you to create up to 500 Databases, using a total of 9GB of storage, 1 billion row reads, 25 million written and up to three locations.
Let's start by installing Nest.js locally, I'm assuming you already have Node.js and NPM installed on your OS.
$ npm install -g @nestjs/cli
$ nest new nest-project
after running this command you should see something like this
⚡ We will scaffold your app in a few seconds..
? Which package manager would you ❤️ to use? npm
CREATE nest-project/.eslintrc.js (663 bytes)
CREATE nest-project/.prettierrc (51 bytes)
CREATE nest-project/README.md (4369 bytes)
CREATE nest-project/nest-cli.json (171 bytes)
CREATE nest-project/package.json (1951 bytes)
CREATE nest-project/tsconfig.build.json (97 bytes)
CREATE nest-project/tsconfig.json (546 bytes)
CREATE nest-project/src/app.controller.ts (274 bytes)
CREATE nest-project/src/app.module.ts (249 bytes)
CREATE nest-project/src/app.service.ts (142 bytes)
CREATE nest-project/src/main.ts (208 bytes)
CREATE nest-project/src/app.controller.spec.ts (617 bytes)
CREATE nest-project/test/jest-e2e.json (183 bytes)
CREATE nest-project/test/app.e2e-spec.ts (630 bytes)
✔ Installation in progress... ☕
🚀 Successfully created project nest-project
👉 Get started with the following commands:
$ cd nest-project
$ npm run start
Thanks for installing Nest 🙏
Please consider donating to our open collective
to help us maintain this package.
🍷 Donate: https://opencollective.com/nest
let's verify that everything is in order, to do that you need to run
$ cd nest-project
$ npm run start
Open your browser on the address http://localhost:3000/
you should see the response Hello World!
Let's open a new terminal and run
$ nest g service prisma
after running this command you should see something like this
CREATE src/prisma/prisma.service.spec.ts (460 bytes)
CREATE src/prisma/prisma.service.ts (90 bytes)
UPDATE src/app.module.ts (321 bytes)
let's open the file src/prisma/prisma.service.ts
and add the following content
import { Injectable } from '@nestjs/common';
@Injectable()
export class PrismaService {}
let's replace it with the following
import { Injectable } from '@nestjs/common';
import { PrismaClient } from '@prisma/client';
import { PrismaLibSQL } from '@prisma/adapter-libsql';
import { createClient } from '@libsql/client';
@Injectable()
export class PrismaService extends PrismaClient {
constructor() {
const libsql = createClient({
url: `${process.env.TURSO_DATABASE_URL}`,
authToken: `${process.env.TURSO_AUTH_TOKEN}`,
});
const adapter = new PrismaLibSQL(libsql);
super({ adapter });
}
async onModuleInit() {
await this.$connect();
}
}
let's go back to the terminal and run
$ npm install @libsql/client @prisma/adapter-libsql @prisma/client
$ npm install prisma --save-dev
$ npx prisma
$ npx prisma init
let's open prisma/schema.prisma
and replace it with the following
generator client {
provider = "prisma-client-js"
previewFeatures = ["driverAdapters"]
}
datasource db {
provider = "sqlite"
url = "file:./dev.db"
}
model User {
userId Int @id @default(autoincrement())
username String @unique
password String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
and run the command npx prisma generate
If you don't have an existing database, you can provision a database by running the following command:
$ turso db create turso-prisma-db
The above command will create a database in the closest region to your location.
Run the following command to retrieve your database's connection string:
$ turso db show turso-prisma-db
Next, create an authentication token that will allow you to connect to the database:
$ turso db tokens create turso-prisma-db
Update your .env
file with the authentication token and connection string:
TURSO_AUTH_TOKEN="eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9..."
TURSO_DATABASE_URL="libsql://turso-prisma-db-user.turso.io"
Now let's create a user service, by running the following command
$ nest g service user
let's open the file src/user/user.service.ts
and replace it with the following
import { Injectable } from '@nestjs/common';
import { User } from '@prisma/client';
import { PrismaService } from 'src/prisma/prisma.service';
@Injectable()
export class UserService {
constructor(private prisma: PrismaService) {}
async findAll() {
return this.prisma.user.findMany();
}
async findOne(id: number) {
return this.prisma.user.findUnique({
where: { userId: id },
});
}
async create(user: User) {
return this.prisma.user.create({
data: user,
});
}
async update(id: number, user: User) {
return this.prisma.user.update({
where: { userId: id },
data: user,
});
}
async delete(id: number) {
return this.prisma.user.delete({
where: { userId: id },
});
}
}
let's open the file src/app.controller.ts
and replace it with the following
import { Controller, Get, Post, Body, Patch, Param, Delete, NotFoundException } from '@nestjs/common';
import { UserService } from './user.service';
import { User } from '@prisma/client';
@Controller('users')
export class AppController {
constructor(private readonly userService: UserService) {}
@Get()
findAll() {
return this.userService.findAll();
}
@Get(':id')
await findOne(@Param('id') id: string) {
const user = await this.userService.findOne(+id);
if (!user) {
throw new NotFoundException(`User with id ${id} not found`);
}
return user;
}
@Post()
create(@Body() user: User) {
return this.userService.create(user);
}
@Patch(':id')
update(@Param('id') id: string, @Body() user: User) {
return this.userService.update(+id, user);
}
@Delete(':id')
delete(@Param('id') id: string) {
return this.userService.delete(+id);
}
}
Now, let's generate a migration file using prisma migrate dev against a local SQLite database:
$ npx prisma migrate dev --name init
Apply the migration:
$ turso db shell turso-prisma-db < ./prisma/migrations/20230922132717_init/migration.sql
finally, let's run the application
$ npm run start:dev
and open your browser on the address http://localhost:3000/users
you should see the response
[]
let's create a user by running the following command
$ curl -X POST -H "Content-Type: application/json" -d '{"username": "pedro", "password": "pedro"}' http://localhost:3000/users
you should see the response
{"userId":1,"username":"pedro","password":"pedro","createdAt":"2024-08-27T21:15:41.190Z","updatedAt":"2024-08-27T21:15:41.190Z"}
and open your browser on the address http://localhost:3000/users
you should see the response
[
{
"userId": 1,
"username": "pedro",
"password": "pedro",
"createdAt": "2024-08-27T21:15:41.190Z",
"updatedAt": "2024-08-27T21:15:41.190Z"
}
]
That's it.
Please let me know what you think about this tutorial, would you change anything or add something?