如上节所说,我们目前所有代码都堆砌在src/main.ts中,这在真正开发中是不可能的。
优化
新建一个src/user.service.ts,内容如下:
interface User {
id: number;
author: string;
age: number;
}
class UserService {
users: User[] = [
{ id: 1, author: "张三", age: 18 },
];
getAll() {
return this.users;
}
getUserById(id: number) {
return this.users.find((user) => user.id === id);
}
addUser(user: Omit<User, "id">) {
const id = this.users.length + 1;
const newUser = {
...user,
id,
};
this.users.push(newUser);
return newUser;
}
removeUser(id: number) {
this.users = this.users.filter((user) => user.id !== id);
}
updateUser(id: number, user: Omit<User, "id">) {
const oldUser = this.getUserById(id);
if (!oldUser) {
throw new Error(`user not found`);
}
Object.assign(oldUser, user);
}
}
export const userService = new UserService();
修改src/main.ts
import { Application, Router } from "https://deno.land/x/oak@v11.1.0/mod.ts";
import { userService } from "./user.service.ts";
const router = new Router();
router
.get("/", (context) => {
context.response.body = "hello world";
})
.get("/user", (context) => {
context.response.body = userService.getAll();
})
.get("/user/:id", (context) => {
const id = Number(context.params.id);
const user = userService.getUserById(id);
if (user) {
context.response.body = user;
} else {
context.response.status = 404;
context.response.body = "user not found";
}
})
.post("/user", async (context) => {
const result = context.request.body({
type: "json",
});
const value = await result.value;
const user = userService.addUser(value);
context.response.body = user;
})
.put("/user/:id", async (context) => {
const id = Number(context.params.id);
const result = context.request.body({
type: "json",
});
const value = await result.value;
try {
userService.updateUser(id, value);
context.response.body = "update ok";
} catch (e) {
context.response.status = 400;
context.response.body = e.message;
}
})
.delete("/user/:id", (context) => {
const id = Number(context.params.id);
userService.removeUser(id);
context.response.body = "delete ok";
});
这样分层有什么好处呢?看起来代码只会更多,不会减少。
这是关注点分离,上层代码(main.ts)不需要知道下层(user.service.ts)的处理逻辑,二者完全解耦。封装service层业务逻辑有利于通用的业务逻辑的独立性和重复利用性。
如此一来,用户信息是怎么存储的(是在内存里,或是在文件里,还是数据库中),数据又是怎么修改的,上层都不必关注,只需要处理好参数接收、响应数据即可。同时也方便我们下一步的持久化操作。
作业
尝试下怎么持久化数据到文件中。