Bài này chúng ta sẽ từng bước xây dựng một Rest API bằng TypeScript, Express.js và TypeORM với xác thực và phân quyền cơ bản bằng JWT. TypeORM cho phép bạn chỉ cần viết một class và công cụ đồng bộ hóa sẽ tự động tạo ra cấu trúc SQL cho entity của bạn. Nó tương thích với nhiều cơ sở dữ liệu khác nhau như MySQL, MariaDB, Postgres, SQLite, Microsoft SQL Server, Oracle, sql.js, và MongoDB. Trong project này, chúng ta sẽ sử dụng SQLite để thuận tiện cho việc phát triển và thử nghiệm. Hãy cùng khám phá cách cài đặt và cấu hình dự án để xây dựng một hệ thống xác thực mạnh mẽ với JWT.
Bước 1: Cài đặt và khởi tạo dự án Node.js với TypeScript
Trước tiên, hãy tạo một thư mục mới và khởi tạo dự án Node.js:
mkdir ts-express-typeorm
cd ts-express-typeorm
npm init -y
Tiếp theo, cài đặt các dependencies cần thiết:
npm install express typeorm reflect-metadata sqlite3 jsonwebtoken bcryptjs
npm install --save-dev typescript ts-node @types/node @types/express @types/jsonwebtoken @types/bcryptjs
Bước 2: Thiết lập TypeScript
Tạo file tsconfig.json
để cấu hình TypeScript:
{
"compilerOptions": {
"target": "ES6",
"module": "commonjs",
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true
}
}
Bước 3: Cấu trúc dự án
Tạo các thư mục và file cần thiết cho dự án:
mkdir src
cd src
touch app.ts
mkdir controllers routes entities middleware
Bước 4: Cấu hình TypeORM
Tạo file ormconfig.json
để cấu hình TypeORM:
{
"type": "sqlite",
"database": "database.sqlite",
"synchronize": true,
"logging": false,
"entities": ["src/entities/**/*.ts"],
"migrations": ["src/migration/**/*.ts"],
"subscribers": ["src/subscriber/**/*.ts"],
"cli": {
"entitiesDir": "src/entities",
"migrationsDir": "src/migration",
"subscribersDir": "src/subscriber"
}
}
Bước 5: Tạo Entity
Tạo entity User
trong thư mục entities
:
// src/entities/User.ts
import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm';
import { IsEmail, Length } from 'class-validator';
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column()
@Length(4, 20)
username: string;
@Column()
@IsEmail()
email: string;
@Column()
@Length(8, 100)
password: string;
}
Bước 6: Tạo Controller và Route
Tạo controller cho người dùng trong thư mục controllers
:
// src/controllers/UserController.ts
import { Request, Response } from 'express';
import { getRepository } from 'typeorm';
import { User } from '../entities/User';
import bcrypt from 'bcryptjs';
import jwt from 'jsonwebtoken';
export class UserController {
static register = async (req: Request, res: Response) => {
const { username, email, password } = req.body;
const userRepository = getRepository(User);
const user = new User();
user.username = username;
user.email = email;
user.password = bcrypt.hashSync(password, 8);
try {
await userRepository.save(user);
} catch (error) {
return res.status(409).send("username already in use");
}
res.status(201).send("User created");
};
static login = async (req: Request, res: Response) => {
const { email, password } = req.body;
const userRepository = getRepository(User);
let user: User;
try {
user = await userRepository.findOneOrFail({ where: { email } });
} catch (error) {
return res.status(401).send("User not found");
}
if (!bcrypt.compareSync(password, user.password)) {
return res.status(401).send("Incorrect password");
}
const token = jwt.sign(
{ userId: user.id, username: user.username },
process.env.JWT_SECRET,
{ expiresIn: "1h" }
);
res.send({ token });
};
}
Tạo routes cho người dùng trong thư mục routes
:
// src/routes/user.ts
import { Router } from 'express';
import { UserController } from '../controllers/UserController';
const router = Router();
router.post('/register', UserController.register);
router.post('/login', UserController.login);
export default router;
Bước 7: Thiết lập Express
Thiết lập server Express trong app.ts
:
// src/app.ts
import 'reflect-metadata';
import * as express from 'express';
import * as bodyParser from 'body-parser';
import { createConnection } from 'typeorm';
import userRouter from './routes/user';
const app = express();
app.use(bodyParser.json());
app.use('/user', userRouter);
createConnection().then(() => {
app.listen(3000, () => {
console.log('Server started on port 3000');
});
}).catch(error => console.log(error));
Kết luận
Với các bước trên, bạn đã thiết lập thành công một ứng dụng Rest API với TypeScript, Express.js, TypeORM, JWT xác thực và phân quyền cơ bản. Bạn có thể dễ dàng chuyển đổi giữa các cơ sở dữ liệu mà không cần thay đổi mã nguồn và mở rộng dự án của mình bằng cách thêm các chức năng và routes mới. Hãy thử nghiệm và tùy chỉnh dự án này theo nhu cầu của bạn để học TypeScript hiệu quả hơn.