Using Another ORM or Query Builder
The core of the framework is independent of TypeORM. So, if you do not want to use an ORM at all or use another ORM or ODM than TypeORM, you absolutely can.
To do so, you will have to remove TypeORM and all its utilities and implement some functions yourself like the authentication function fetchUser.
Uninstall TypeORM
-
First uninstall the dependencies.
npm uninstall typeorm @foal/typeorm -
Then remove the directory
src/app/entities. -
Remove or replace the script
create-userinsrc/app/scripts. -
In the file
app.controller.ts, delete the connection creation callcreateConnection. -
Finally, remove in
package.jsonthe scripts to manage migrations.
Functions to Be Added
The fetchUser function
If you wish to use the user option of @JWTRequired or @UseSessions to set the ctx.user property, then you will need to implement your own fetchUser function.
This utility returns a function that takes an id as parameter which might be a string or a number and returns a promise. The promise value must be undefined is no user matches the given id and the user object otherwise.
Example
import { FetchUser, ServiceManager } from '@foal/core';
export function fetchUser(userModel: any): FetchUser {
return async (id: number|string, services: ServiceManager) => {
if (typeof id === 'string') {
throw new Error('The user ID must be a number.');
}
const user = await userModel.findOne({ id });
if (user === null) {
return undefined;
}
return user;
};
}
Examples
Prisma
This example uses an SQLite database.
Warning on Configuration
Prisma uses the dotenv library under the hood which handles .env files and environment variables differently.
Therefore, when using Prisma, you can only use one single .env file. Using other files such as .env.local or .env.production will lead to unexpected variable values.
Basic Set Up
Install the latest version of TypeScript (Prisma v2.21 requires at least v4.1).
npm install typescript@latest
If you get compile-time errors referencing the file
node_modules/.prisma/client/index.d.ts, it is likely that your version of TypeScript is too old.
Install the Prisma dependencies.
npm install prisma --save-dev
npm install @prisma/client
Init the project.
npx prisma init
Set up the database configuration in prisma/schema.prisma.
datasource db {
provider = "sqlite"
url = env("DATABASE_URL")
}
generator client {
provider = "prisma-client-js"
}
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
}
Specify the database URL in the .env file.
DATABASE_URL="file:./db.sqlite3"
Generate and run the migration.
npx prisma migrate dev --name init
Generate the TypeScript interfaces.
npx prisma generate
Update your src/index.ts to create the prisma connection and pass it to the service manager.
src/index.ts
// 3p
import { ServiceManager } from '@foal/core';
import { PrismaClient } from '@prisma/client';
// App
import { AppController } from './app/app.controller';
const prisma = new PrismaClient();
async function main() {
const serviceManager = new ServiceManager();
serviceManager.set(PrismaClient, prisma);
const app = await createApp(AppController, { serviceManager });
// ...
}
main()
.catch(err => { console.error(err.stack); process.exit(1); })
.finally(() => prisma.$disconnect());
Finally, inject the prisma client into your controllers and start using it.
app.controller.ts
import { dependency, Get, HttpResponseOK, IAppController } from '@foal/core';
import { PrismaClient } from '@prisma/client';
export class AppController implements IAppController {
@dependency
prisma: PrismaClient;
@Get('/users')
async getAllUsers() {
const allUsers = await this.prisma.user.findMany();
return new HttpResponseOK(allUsers);
}
}
The fetchUser function
In case your application uses the hooks @UseSessions or @JWTRequired and you want to assign a value to ctx.user, then you will need to create a fetchUser function.
First, make sure your have a User model defined in schema.prisma.
// ...
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
}
If you haven't already done so, generate and run the migration and generate the TypeScript interfaces.
npx prisma migrate dev --name add-user
npx prisma generate
Then create the fetchPrismaUser function.
import { ServiceManager } from '@foal/core';
import { PrismaClient } from '@prisma/client';
export async function fetchPrismaUser(id: number|string, services: ServiceManager) {
if (typeof id === 'string') {
throw new Error('The user ID must be a number.');
}
const user = await services.get(PrismaClient).user.findFirst({
where: { id }
});
if (user === null) {
return undefined;
}
return user;
}
You're now ready to use it in your hooks.
@JWTRequired({ user: fetchPrismaUser })
// OR
@UseSessions({ user: fetchPrismaUser })
Limitations
When using another ORM than TypeORM some features, are not available:
- the Groups & Permissions system,
- and the
foal g rest-apicommand.