interface User { id: number name: string email: string age: number createdAt: Date updatedAt: Date }
interface CreateUserInput { name: string email: string age: number }
interface UpdateUserInput { name?: string email?: string age?: number }
interface UserRepository { findById(id: number): Promise<User | null> findAll(): Promise<User[]> create(data: CreateUserInput): Promise<User> update(id: number, data: UpdateUserInput): Promise<User> delete(id: number): Promise<boolean> }
class InMemoryUserRepository implements UserRepository { private users: User[] = [] private nextId = 1
async findById(id: number): Promise<User | null> { return this.users.find(user => user.id === id) || null }
async findAll(): Promise<User[]> { return [...this.users] }
async create(data: CreateUserInput): Promise<User> { const user: User = { id: this.nextId++, ...data, createdAt: new Date(), updatedAt: new Date() } this.users.push(user) return user }
async update(id: number, data: UpdateUserInput): Promise<User> { const userIndex = this.users.findIndex(user => user.id === id) if (userIndex === -1) { throw new Error('User not found') } this.users[userIndex] = { ...this.users[userIndex], ...data, updatedAt: new Date() } return this.users[userIndex] }
async delete(id: number): Promise<boolean> { const initialLength = this.users.length this.users = this.users.filter(user => user.id !== id) return this.users.length < initialLength } }
interface UserService { createUser(data: CreateUserInput): Promise<User> getUser(id: number): Promise<User> getAllUsers(): Promise<User[]> updateUser(id: number, data: UpdateUserInput): Promise<User> deleteUser(id: number): Promise<boolean> }
class UserServiceImpl implements UserService { constructor(private userRepository: UserRepository) {}
async createUser(data: CreateUserInput): Promise<User> { if (!this.isValidEmail(data.email)) { throw new Error('Invalid email format') } if (data.age < 18) { throw new Error('User must be at least 18 years old') } return this.userRepository.create(data) }
async getUser(id: number): Promise<User> { const user = await this.userRepository.findById(id) if (!user) { throw new Error('User not found') } return user }
async getAllUsers(): Promise<User[]> { return this.userRepository.findAll() }
async updateUser(id: number, data: UpdateUserInput): Promise<User> { if (data.email && !this.isValidEmail(data.email)) { throw new Error('Invalid email format') } return this.userRepository.update(id, data) }
async deleteUser(id: number): Promise<boolean> { return this.userRepository.delete(id) }
private isValidEmail(email: string): boolean { return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email) } }
interface UserController { createUser(req: Request, res: Response): Promise<void> getUser(req: Request, res: Response): Promise<void> getAllUsers(req: Request, res: Response): Promise<void> updateUser(req: Request, res: Response): Promise<void> deleteUser(req: Request, res: Response): Promise<void> }
class UserControllerImpl implements UserController { constructor(private userService: UserService) {}
async createUser(req: Request, res: Response): Promise<void> { try { const user = await this.userService.createUser(req.body) res.status(201).json(user) } catch (error) { res.status(400).json({ error: error.message }) } }
async getUser(req: Request, res: Response): Promise<void> { try { const user = await this.userService.getUser(Number(req.params.id)) res.json(user) } catch (error) { res.status(404).json({ error: error.message }) } }
async getAllUsers(req: Request, res: Response): Promise<void> { const users = await this.userService.getAllUsers() res.json(users) }
async updateUser(req: Request, res: Response): Promise<void> { try { const user = await this.userService.updateUser(Number(req.params.id), req.body) res.json(user) } catch (error) { res.status(400).json({ error: error.message }) } }
async deleteUser(req: Request, res: Response): Promise<void> { try { const success = await this.userService.deleteUser(Number(req.params.id)) res.status(success ? 204 : 404).json({ success }) } catch (error) { res.status(400).json({ error: error.message }) } } }
const userRepository = new InMemoryUserRepository() const userService = new UserServiceImpl(userRepository) const userController = new UserControllerImpl(userService)
interface Request { body: any params: { [key: string]: string } }
interface Response { status(code: number): Response json(data: any): void }
const mockServer = { routes: [], post(path: string, handler: (req: Request, res: Response) => Promise<void>) { this.routes.push({ method: 'POST', path, handler }) }, get(path: string, handler: (req: Request, res: Response) => Promise<void>) { this.routes.push({ method: 'GET', path, handler }) }, put(path: string, handler: (req: Request, res: Response) => Promise<void>) { this.routes.push({ method: 'PUT', path, handler }) }, delete(path: string, handler: (req: Request, res: Response) => Promise<void>) { this.routes.push({ method: 'DELETE', path, handler }) }, async handleRequest(method: string, path: string, req: Request) { const route = this.routes.find(r => r.method === method && r.path === path) if (!route) { throw new Error('Route not found') } const res = { status: (code: number) => ({ json: (data: any) => console.log(`${code}:`, data) }), json: (data: any) => console.log(JSON.stringify(data)) } await route.handler(req, res) } }
mockServer.post('/users', (req: Request, res: Response) => userController.createUser(req, res))
mockServer.get('/users', (req: Request, res: Response) => userController.getAllUsers(req, res))
mockServer.get('/users/:id', (req: Request, res: Response) => userController.getUser(req, res))
mockServer.put('/users/:id', (req: Request, res: Response) => userController.updateUser(req, res))
mockServer.delete('/users/:id', (req: Request, res: Response) => userController.deleteUser(req, res))
async function testApp() { console.log('Creating user...') await mockServer.handleRequest('POST', '/users', { body: { name: '张三', email: 'zhangsan@example.com', age: 25 }, params: {} }) console.log('\nGetting all users...') await mockServer.handleRequest('GET', '/users', { body: {}, params: {} }) console.log('\nGetting user by ID...') await mockServer.handleRequest('GET', '/users/1', { body: {}, params: { id: '1' } }) }
testApp()
|