

文章目录
- [1. Node.js Web框架概述](#1. Node.js Web框架概述)
-
- [1.1 Web框架的作用](#1.1 Web框架的作用)
- [1.2 Node.js主要Web框架生态](#1.2 Node.js主要Web框架生态)
- [1.3 框架选择考虑因素](#1.3 框架选择考虑因素)
- [2. Express.js](#2. Express.js)
-
- [2.1 Express.js概述](#2.1 Express.js概述)
- [2.2 基本用法](#2.2 基本用法)
-
- [2.2.1 安装Express](#2.2.1 安装Express)
- [2.2.2 创建基本服务器](#2.2.2 创建基本服务器)
- [2.3 路由](#2.3 路由)
- [2.4 中间件](#2.4 中间件)
- [2.5 请求和响应](#2.5 请求和响应)
- [2.6 完整的Express应用结构](#2.6 完整的Express应用结构)
- [3. Koa.js](#3. Koa.js)
-
- [3.1 Koa.js概述](#3.1 Koa.js概述)
- [3.2 基本用法](#3.2 基本用法)
-
- [3.2.1 安装Koa](#3.2.1 安装Koa)
- [3.2.2 创建基本服务器](#3.2.2 创建基本服务器)
- [3.3 中间件和上下文](#3.3 中间件和上下文)
- [3.4 Koa与Express对比](#3.4 Koa与Express对比)
- [4. Nest.js](#4. Nest.js)
-
- [4.1 Nest.js概述](#4.1 Nest.js概述)
- [4.2 基本用法](#4.2 基本用法)
-
- [4.2.1 安装Nest.js](#4.2.1 安装Nest.js)
- [4.2.2 主要组件](#4.2.2 主要组件)
- [4.3 依赖注入](#4.3 依赖注入)
- [4.4 中间件、守卫和拦截器](#4.4 中间件、守卫和拦截器)
- [5. Fastify](#5. Fastify)
-
- [5.1 Fastify概述](#5.1 Fastify概述)
- [5.2 基本用法](#5.2 基本用法)
-
- [5.2.1 安装Fastify](#5.2.1 安装Fastify)
- [5.2.2 创建服务器](#5.2.2 创建服务器)
- [5.3 Schema验证和序列化](#5.3 Schema验证和序列化)
- [5.4 插件系统](#5.4 插件系统)
- [5.5 与Express和Koa性能对比](#5.5 与Express和Koa性能对比)
- [6. Next.js](#6. Next.js)
-
- [6.1 Next.js概述](#6.1 Next.js概述)
- [6.2 基本用法](#6.2 基本用法)
-
- [6.2.1 创建Next.js应用](#6.2.1 创建Next.js应用)
- [6.2.2 页面和路由](#6.2.2 页面和路由)
- [6.3 数据获取方法](#6.3 数据获取方法)
- [6.4 API路由](#6.4 API路由)
- [6.5 中间件和布局](#6.5 中间件和布局)
- [7. Hapi.js](#7. Hapi.js)
-
- [7.1 Hapi.js概述](#7.1 Hapi.js概述)
- [7.2 基本用法](#7.2 基本用法)
-
- [7.2.1 安装Hapi](#7.2.1 安装Hapi)
- [7.2.2 创建服务器](#7.2.2 创建服务器)
- [7.3 路由和处理程序](#7.3 路由和处理程序)
- [7.4 插件和扩展](#7.4 插件和扩展)
- [7.5 验证和认证](#7.5 验证和认证)
- [8. 全栈框架: AdonisJS和Sails.js](#8. 全栈框架: AdonisJS和Sails.js)
-
- [8.1 AdonisJS概述](#8.1 AdonisJS概述)
- [8.2 AdonisJS基本用法](#8.2 AdonisJS基本用法)
-
- [8.2.1 创建AdonisJS应用](#8.2.1 创建AdonisJS应用)
- [8.2.2 AdonisJS应用结构](#8.2.2 AdonisJS应用结构)
- [8.2.3 路由和控制器](#8.2.3 路由和控制器)
- [8.3 Sails.js概述](#8.3 Sails.js概述)
- [8.4 Sails.js基本用法](#8.4 Sails.js基本用法)
-
- [8.4.1 创建Sails.js应用](#8.4.1 创建Sails.js应用)
- [8.4.2 模型和API](#8.4.2 模型和API)
- [8.4.3 路由配置](#8.4.3 路由配置)
- [9. 专业领域框架](#9. 专业领域框架)
-
- [9.1 Loopback - API框架](#9.1 Loopback - API框架)
-
- [9.1.1 基本使用](#9.1.1 基本使用)
- [9.2 Strapi - 内容管理框架](#9.2 Strapi - 内容管理框架)
-
- [9.2.1 基本使用](#9.2.1 基本使用)
- [10. 框架选择指南与比较](#10. 框架选择指南与比较)
-
- [10.1 框架特性对比](#10.1 框架特性对比)
- [10.2 适用场景选择](#10.2 适用场景选择)
正文
1. Node.js Web框架概述
Node.js的生态系统提供了多种Web开发框架,它们各自具有不同的特点和适用场景。这些框架帮助开发者快速构建高性能、可维护的Web应用程序。
1.1 Web框架的作用
- 简化HTTP服务器的创建
- 提供路由管理
- 集成中间件系统
- 统一错误处理
- 提供模板引擎支持
- 简化API开发
- 改善应用程序结构
1.2 Node.js主要Web框架生态
Node.js Web框架 Express.js Koa.js Hapi.js Nest.js Fastify Next.js Adonis.js Sails.js Loopback Middleware-based Async/Await友好 配置驱动 TypeScript优先 性能导向 React SSR/SSG 全栈MVC 企业级API API开发
1.3 框架选择考虑因素
2. Express.js
2.1 Express.js概述
Express.js是Node.js最流行的Web框架,提供了简单而灵活的API,适用于各种Web应用和API开发。
客户端请求 Express应用 路由 中间件1 中间件2 路由处理器 响应 客户端
2.2 基本用法
2.2.1 安装Express
bash
npm install express
2.2.2 创建基本服务器
javascript
const express = require('express');
const app = express();
const port = 3000;
// 路由处理
app.get('/', (req, res) => {
res.send('Hello World!');
});
// 启动服务器
app.listen(port, () => {
console.log(`服务器运行在 http://localhost:${port}`);
});
2.3 路由
javascript
// 基本路由
app.get('/users', (req, res) => {
res.json([{ name: 'John' }, { name: 'Jane' }]);
});
app.post('/users', (req, res) => {
// 创建用户
res.status(201).json({ success: true });
});
// 参数路由
app.get('/users/:id', (req, res) => {
const userId = req.params.id;
res.json({ id: userId, name: 'John Doe' });
});
// 路由模块化
const usersRoutes = express.Router();
usersRoutes.get('/', (req, res) => { /* ... */ });
usersRoutes.post('/', (req, res) => { /* ... */ });
usersRoutes.get('/:id', (req, res) => { /* ... */ });
app.use('/api/users', usersRoutes);
2.4 中间件
请求 全局中间件 路由特定中间件 路由处理器 响应
javascript
// 内置中间件
app.use(express.json()); // 解析JSON请求体
app.use(express.urlencoded({ extended: true })); // 解析URL编码的请求体
app.use(express.static('public')); // 提供静态文件
// 自定义中间件
app.use((req, res, next) => {
console.log(`${req.method} ${req.url} at ${new Date()}`);
next(); // 继续下一个中间件
});
// 路由特定中间件
const authenticate = (req, res, next) => {
const token = req.headers.authorization;
if (!token) {
return res.status(401).json({ error: '未授权' });
}
// 验证token...
next();
};
app.get('/protected', authenticate, (req, res) => {
res.json({ message: '受保护的数据' });
});
// 错误处理中间件
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).json({ error: '服务器内部错误' });
});
2.5 请求和响应
javascript
// 请求对象(req)
app.get('/example', (req, res) => {
console.log(req.query); // 查询参数
console.log(req.params); // 路由参数
console.log(req.body); // 请求体
console.log(req.headers); // 请求头
console.log(req.cookies); // Cookies (需要cookie-parser)
console.log(req.ip); // 客户端IP
console.log(req.path); // 请求路径
console.log(req.method); // HTTP方法
// 响应对象(res)
res.status(200); // 设置状态码
res.set('Content-Type', 'application/json'); // 设置响应头
res.cookie('name', 'value', { maxAge: 900000 }); // 设置cookie
res.json({ data: 'JSON响应' }); // 发送JSON响应
res.send('文本响应'); // 发送通用响应
res.sendFile('/path/to/file.pdf'); // 发送文件
res.download('/report.pdf'); // 下载文件
res.redirect('/new-page'); // 重定向
res.render('template', { title: '模板渲染' }); // 渲染模板
});
2.6 完整的Express应用结构
project-root/
├── config/ # 配置文件
│ ├── database.js
│ └── app.js
├── controllers/ # 控制器
│ ├── userController.js
│ └── productController.js
├── middleware/ # 中间件
│ ├── auth.js
│ └── errorHandler.js
├── models/ # 数据模型
│ ├── User.js
│ └── Product.js
├── routes/ # 路由
│ ├── userRoutes.js
│ └── productRoutes.js
├── public/ # 静态资源
│ ├── css/
│ ├── js/
│ └── images/
├── views/ # 视图模板
│ ├── layouts/
│ ├── users/
│ └── products/
├── tests/ # 测试
│ ├── unit/
│ └── integration/
├── app.js # 主应用文件
├── server.js # 服务器启动文件
├── package.json
└── .env # 环境变量
3. Koa.js
3.1 Koa.js概述
Koa是由Express团队开发的更轻量级、更富有表现力的Node.js Web框架,专为异步编程设计,利用async/await特性提供更简洁的中间件机制。
客户端请求 Koa应用 中间件1 中间件2 中间件3 响应处理 中间件3 返回 中间件2 返回 中间件1 返回 响应
3.2 基本用法
3.2.1 安装Koa
bash
npm install koa
3.2.2 创建基本服务器
javascript
const Koa = require('koa');
const app = new Koa();
const port = 3000;
// 中间件
app.use(async (ctx, next) => {
const start = Date.now();
await next();
const ms = Date.now() - start;
console.log(`${ctx.method} ${ctx.url} - ${ms}ms`);
});
app.use(async ctx => {
ctx.body = 'Hello World';
});
app.listen(port, () => {
console.log(`服务器运行在 http://localhost:${port}`);
});
3.3 中间件和上下文
javascript
// 错误处理中间件
app.use(async (ctx, next) => {
try {
await next();
} catch (err) {
ctx.status = err.statusCode || 500;
ctx.body = {
message: err.message
};
ctx.app.emit('error', err, ctx);
}
});
// 数据解析中间件
const bodyParser = require('koa-bodyparser');
app.use(bodyParser());
// 路由中间件
const Router = require('@koa/router');
const router = new Router();
router.get('/', async (ctx) => {
ctx.body = { message: '首页' };
});
router.get('/users/:id', async (ctx) => {
const userId = ctx.params.id;
ctx.body = { id: userId, name: 'John Doe' };
});
app.use(router.routes());
app.use(router.allowedMethods());
// 上下文操作示例
app.use(async ctx => {
// 请求数据
console.log(ctx.request.query); // 查询参数
console.log(ctx.request.body); // 请求体 (需要bodyParser)
console.log(ctx.params); // 路由参数 (需要路由中间件)
// 响应设置
ctx.status = 200; // 状态码
ctx.set('X-Custom-Header', 'value'); // 自定义响应头
ctx.type = 'application/json'; // 内容类型
ctx.body = { data: 'success' }; // 响应体
// Cookies
ctx.cookies.set('name', 'value', { maxAge: 86400000 });
const cookie = ctx.cookies.get('name');
});
3.4 Koa与Express对比
Web框架对比 Express Koa 优点 成熟稳定 社区庞大 中间件丰富 简单直观 缺点 回调地狱 错误处理复杂 优点 async/await支持 更好的错误处理 更简洁的API 可组合中间件 缺点 学习曲线 需要额外模块
4. Nest.js
4.1 Nest.js概述
Nest.js是一个用于构建高效、可靠、可扩展的服务器端应用程序的渐进式Node.js框架,它结合了面向对象编程、函数式编程和函数响应式编程的元素。
Nest.js架构 模块Module 控制器Controller 提供者Provider 中间件Middleware 管道Pipe 守卫Guard 拦截器Interceptor 异常过滤器ExceptionFilter 功能封装 处理请求 提供服务 处理HTTP请求 数据转换/验证 权限验证 响应拦截/修改 异常处理
4.2 基本用法
4.2.1 安装Nest.js
bash
npm i -g @nestjs/cli
nest new project-name
4.2.2 主要组件
typescript
// 控制器 (users.controller.ts)
import { Controller, Get, Post, Body, Param, UseGuards } from '@nestjs/common';
import { UsersService } from './users.service';
import { CreateUserDto } from './dto/create-user.dto';
import { AuthGuard } from '../auth/auth.guard';
@Controller('users')
export class UsersController {
constructor(private readonly usersService: UsersService) {}
@Get()
findAll() {
return this.usersService.findAll();
}
@Get(':id')
findOne(@Param('id') id: string) {
return this.usersService.findOne(+id);
}
@Post()
@UseGuards(AuthGuard)
create(@Body() createUserDto: CreateUserDto) {
return this.usersService.create(createUserDto);
}
}
// 服务 (users.service.ts)
import { Injectable } from '@nestjs/common';
import { CreateUserDto } from './dto/create-user.dto';
import { User } from './entities/user.entity';
@Injectable()
export class UsersService {
private readonly users: User[] = [];
create(createUserDto: CreateUserDto): User {
const user = { id: this.users.length + 1, ...createUserDto };
this.users.push(user);
return user;
}
findAll(): User[] {
return this.users;
}
findOne(id: number): User {
return this.users.find(user => user.id === id);
}
}
// 模块 (users.module.ts)
import { Module } from '@nestjs/common';
import { UsersController } from './users.controller';
import { UsersService } from './users.service';
@Module({
controllers: [UsersController],
providers: [UsersService],
exports: [UsersService]
})
export class UsersModule {}
// 主模块 (app.module.ts)
import { Module } from '@nestjs/common';
import { UsersModule } from './users/users.module';
import { AuthModule } from './auth/auth.module';
@Module({
imports: [UsersModule, AuthModule],
})
export class AppModule {}
4.3 依赖注入
Nest.js依赖注入 提供者Provider 消费者Consumer 服务Service 存储库Repository 工厂Factory 辅助类Helper 控制器Controller 其他服务Service 守卫Guard 拦截器Interceptor
typescript
// 定义提供者
@Injectable()
export class CatsService {
private readonly cats: Cat[] = [];
create(cat: Cat) {
this.cats.push(cat);
}
findAll(): Cat[] {
return this.cats;
}
}
// 注册提供者
@Module({
controllers: [CatsController],
providers: [CatsService],
})
export class CatsModule {}
// 消费依赖
@Controller('cats')
export class CatsController {
constructor(private readonly catsService: CatsService) {}
@Get()
findAll() {
return this.catsService.findAll();
}
}
4.4 中间件、守卫和拦截器
客户端请求 中间件 守卫 拦截器-前 管道 控制器路由处理 拦截器-后 异常过滤器 响应
typescript
// 中间件
@Injectable()
export class LoggerMiddleware implements NestMiddleware {
use(req: Request, res: Response, next: Function) {
console.log(`Request... ${req.method} ${req.url}`);
next();
}
}
// 使用中间件
@Module({
imports: [UsersModule],
})
export class AppModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
consumer
.apply(LoggerMiddleware)
.forRoutes('users');
}
}
// 守卫
@Injectable()
export class AuthGuard implements CanActivate {
canActivate(
context: ExecutionContext,
): boolean | Promise<boolean> | Observable<boolean> {
const request = context.switchToHttp().getRequest();
// 验证逻辑
return isAuthorized(request);
}
}
// 拦截器
@Injectable()
export class TransformInterceptor implements NestInterceptor {
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
console.log('Before...');
return next
.handle()
.pipe(
map(data => {
console.log('After...');
return { data, timestamp: new Date().toISOString() };
}),
);
}
}
// 管道
@Injectable()
export class ValidationPipe implements PipeTransform {
transform(value: any, metadata: ArgumentMetadata) {
// 数据验证和转换逻辑
return validatedValue;
}
}
5. Fastify
5.1 Fastify概述
Fastify是一个专注于性能和低开销的快速Web框架,提供了一套精简API,适合构建高性能的服务。
Fastify特点 高性能 低内存占用 插件架构 Schema验证 TypeScript支持 日志内置
5.2 基本用法
5.2.1 安装Fastify
bash
npm install fastify
5.2.2 创建服务器
javascript
const fastify = require('fastify')({ logger: true });
const port = 3000;
// 定义路由
fastify.get('/', async (request, reply) => {
return { hello: 'world' };
});
// 启动服务器
const start = async () => {
try {
await fastify.listen({ port });
fastify.log.info(`服务器运行在 ${fastify.server.address().port}`);
} catch (err) {
fastify.log.error(err);
process.exit(1);
}
};
start();
5.3 Schema验证和序列化
javascript
// 定义带有Schema的路由
fastify.route({
method: 'POST',
url: '/users',
schema: {
body: {
type: 'object',
required: ['name', 'email'],
properties: {
name: { type: 'string' },
email: { type: 'string', format: 'email' },
age: { type: 'integer', minimum: 18 }
}
},
response: {
200: {
type: 'object',
properties: {
id: { type: 'integer' },
name: { type: 'string' },
email: { type: 'string' }
}
}
}
},
handler: async (request, reply) => {
const { name, email, age } = request.body;
// 处理创建用户的逻辑
const user = { id: 1, name, email };
return user;
}
});
5.4 插件系统
javascript
// 定义插件
const myPlugin = async (fastify, options) => {
// 注册钩子
fastify.addHook('onRequest', async (request, reply) => {
request.log.info('请求已接收');
});
// 注册路由
fastify.get('/plugin-route', async (request, reply) => {
return { message: '这是插件路由' };
});
// 装饰fastify实例
fastify.decorate('utility', function() {
return 'utility value';
});
// 装饰请求
fastify.decorateRequest('customProp', 'custom value');
};
// 注册插件
fastify.register(myPlugin, { pluginOption: 'value' });
// 使用插件功能
fastify.get('/use-plugin', async (request, reply) => {
console.log(fastify.utility());
console.log(request.customProp);
return { success: true };
});
5.5 与Express和Koa性能对比
6. Next.js
6.1 Next.js概述
Next.js是一个React框架,用于构建服务器渲染、静态生成和客户端渲染的React应用。它提供了现代Web应用所需的所有功能,如路由、图像优化、API路由等。
Next.js特性 服务器渲染SSR 静态站点生成SSG 混合渲染模式 文件系统路由 API路由 图像优化 自动代码分割 TypeScript支持
6.2 基本用法
6.2.1 创建Next.js应用
bash
npx create-next-app my-next-app
# 或
yarn create next-app my-next-app
6.2.2 页面和路由
javascript
// pages/index.js - 主页
import Head from 'next/head';
export default function Home() {
return (
<div>
<Head>
<title>Next.js应用</title>
<meta name="description" content="我的Next.js应用" />
</Head>
<main>
<h1>欢迎来到Next.js!</h1>
</main>
</div>
);
}
// pages/users/[id].js - 动态路由
import { useRouter } from 'next/router';
export default function User() {
const router = useRouter();
const { id } = router.query;
return (
<div>
<h1>用户: {id}</h1>
</div>
);
}
// pages/about.js - 静态页面
export default function About() {
return (
<div>
<h1>关于我们</h1>
<p>这是关于页面的内容</p>
</div>
);
}
6.3 数据获取方法
Next.js数据获取 getServerSideProps getStaticProps getStaticPaths 客户端数据获取 每次请求运行
服务器端渲染SSR 构建时运行
静态站点生成SSG 指定动态路由
需要预渲染的路径 React钩子
SWR/React Query
javascript
// 服务器端渲染示例 (SSR)
export async function getServerSideProps(context) {
// 从服务器获取数据
const res = await fetch('https://api.example.com/data');
const data = await res.json();
// 将数据传递给页面组件
return {
props: { data }, // 作为props传递给页面
};
}
// 静态生成示例 (SSG)
export async function getStaticProps() {
// 在构建时获取数据
const res = await fetch('https://api.example.com/static-data');
const data = await res.json();
return {
props: { data },
revalidate: 60, // 增量静态再生成 (ISR) - 每60秒更新
};
}
// 静态路径示例
export async function getStaticPaths() {
// 获取所有可能的路径
const res = await fetch('https://api.example.com/users');
const users = await res.json();
// 为每个用户生成路径
const paths = users.map((user) => ({
params: { id: user.id.toString() },
}));
return {
paths,
fallback: 'blocking', // 或 true 或 false
};
}
6.4 API路由
javascript
// pages/api/hello.js
export default function handler(req, res) {
res.status(200).json({ message: 'Hello World!' });
}
// pages/api/users/[id].js - 动态API路由
export default function handler(req, res) {
const { id } = req.query;
const { method } = req;
switch (method) {
case 'GET':
// 获取用户
res.status(200).json({ id, name: 'John Doe' });
break;
case 'PUT':
// 更新用户
res.status(200).json({ id, ...req.body });
break;
case 'DELETE':
// 删除用户
res.status(200).json({ id, deleted: true });
break;
default:
res.setHeader('Allow', ['GET', 'PUT', 'DELETE']);
res.status(405).end(`Method ${method} Not Allowed`);
}
}
6.5 中间件和布局
javascript
// middleware.js (Next.js 12+)
import { NextResponse } from 'next/server';
export function middleware(request) {
// 检查身份验证
const token = request.cookies.get('token');
if (!token && request.nextUrl.pathname.startsWith('/dashboard')) {
return NextResponse.redirect(new URL('/login', request.url));
}
return NextResponse.next();
}
// _app.js - 全局布局
import '../styles/globals.css';
import Layout from '../components/Layout';
function MyApp({ Component, pageProps }) {
// 如果页面有自定义布局,使用它,否则使用默认布局
const getLayout = Component.getLayout || ((page) => <Layout>{page}</Layout>);
return getLayout(<Component {...pageProps} />);
}
export default MyApp;
// components/Layout.js
export default function Layout({ children }) {
return (
<>
<header>网站头部</header>
<main>{children}</main>
<footer>网站底部</footer>
</>
);
}
7. Hapi.js
7.1 Hapi.js概述
Hapi.js是一个功能丰富的框架,专注于配置而非代码,旨在帮助开发者构建可扩展的API和服务。
Hapi.js特性 配置驱动开发 内置缓存 身份验证框架 状态管理 插件系统 请求验证
7.2 基本用法
7.2.1 安装Hapi
bash
npm install @hapi/hapi
7.2.2 创建服务器
javascript
const Hapi = require('@hapi/hapi');
const init = async () => {
const server = Hapi.server({
port: 3000,
host: 'localhost'
});
// 定义路由
server.route({
method: 'GET',
path: '/',
handler: (request, h) => {
return 'Hello World!';
}
});
await server.start();
console.log('服务器运行在 %s', server.info.uri);
};
process.on('unhandledRejection', (err) => {
console.log(err);
process.exit(1);
});
init();
7.3 路由和处理程序
javascript
// 基本路由
server.route({
method: 'GET',
path: '/users/{id}',
handler: (request, h) => {
const id = request.params.id;
return { id, name: 'John Doe' };
}
});
// 使用路由选项
server.route({
method: 'POST',
path: '/users',
options: {
validate: {
payload: Joi.object({
name: Joi.string().min(3).required(),
email: Joi.string().email().required()
})
},
auth: 'jwt',
tags: ['api', 'users'],
description: '创建新用户'
},
handler: async (request, h) => {
const user = await createUser(request.payload);
return h.response(user).code(201);
}
});
// 路由通配符和参数
server.route({
method: 'GET',
path: '/files/{param*}',
handler: (request, h) => {
const path = request.params.param || '';
return `请求的文件路径: ${path}`;
}
});
7.4 插件和扩展
javascript
// 定义插件
const myPlugin = {
name: 'myPlugin',
version: '1.0.0',
register: async function (server, options) {
// 添加路由
server.route({
method: 'GET',
path: '/plugin-route',
handler: (request, h) => {
return { plugin: 'myPlugin' };
}
});
// 注册扩展点
server.ext('onRequest', (request, h) => {
request.app.requestTime = new Date().getTime();
return h.continue;
});
// 添加方法
server.method('calculateTax', (price) => {
return price * 0.2;
});
}
};
// 注册插件
const init = async () => {
const server = Hapi.server({ /* ... */ });
await server.register({
plugin: myPlugin,
options: { /* 插件选项 */ }
});
// 使用插件提供的方法
server.route({
method: 'GET',
path: '/tax/{price}',
handler: (request, h) => {
const price = parseFloat(request.params.price);
const tax = server.methods.calculateTax(price);
return { price, tax, total: price + tax };
}
});
await server.start();
};
7.5 验证和认证
javascript
// 安装依赖
// npm install @hapi/joi @hapi/basic @hapi/jwt
const Joi = require('@hapi/joi');
const Basic = require('@hapi/basic');
const JWT = require('@hapi/jwt');
const init = async () => {
const server = Hapi.server({ /* ... */ });
// 注册认证插件
await server.register([Basic, JWT]);
// 配置JWT认证策略
server.auth.strategy('jwt', 'jwt', {
keys: 'your-secret-key',
verify: {
aud: 'urn:audience:app',
iss: 'urn:issuer:app',
sub: false,
maxAgeSec: 14400 // 4小时
},
validate: (artifacts, request, h) => {
return {
isValid: true,
credentials: { user: artifacts.decoded.payload.user }
};
}
});
// 配置基本认证策略
server.auth.strategy('simple', 'basic', {
validate: async (request, username, password, h) => {
// 验证逻辑
const isValid = username === 'admin' && password === 'password';
const credentials = { id: 1, name: username };
return { isValid, credentials };
}
});
// 设置默认认证策略
server.auth.default('jwt');
// 带有验证的路由
server.route({
method: 'POST',
path: '/users',
options: {
auth: 'jwt',
validate: {
payload: Joi.object({
name: Joi.string().min(3).max(50).required(),
email: Joi.string().email().required(),
age: Joi.number().integer().min(18).required()
}),
query: Joi.object({
includeDetails: Joi.boolean().default(false)
}),
failAction: (request, h, err) => {
throw err; // 将验证错误返回给客户端
}
}
},
handler: async (request, h) => {
// 处理创建用户的逻辑
return { success: true };
}
});
await server.start();
};
8. 全栈框架: AdonisJS和Sails.js
8.1 AdonisJS概述
AdonisJS是一个全栈MVC框架,提供开箱即用的ORM、身份验证、授权等功能,类似于Laravel(PHP)和Rails(Ruby)的开发体验。
AdonisJS特性 MVC架构 内置ORM 身份验证 ACL授权 验证器 命令行工具 WebSocket支持
8.2 AdonisJS基本用法
8.2.1 创建AdonisJS应用
bash
npm init adonis-ts-app@latest my-app
8.2.2 AdonisJS应用结构
my-app/
├── app/ # 应用代码
│ ├── Controllers/ # 控制器
│ ├── Models/ # 数据模型
│ ├── Middleware/ # 中间件
│ ├── Validators/ # 验证器
│ └── Services/ # 服务
├── config/ # 配置文件
├── contracts/ # TypeScript接口定义
├── database/ # 数据库相关
│ ├── migrations/ # 数据库迁移
│ └── seeders/ # 数据种子
├── providers/ # 服务提供者
├── public/ # 静态资源
├── resources/ # 视图和其他资源
│ └── views/ # 视图模板
├── start/ # 启动文件
│ ├── routes.ts # 路由定义
│ ├── kernel.ts # HTTP内核配置
│ └── events.ts # 事件监听器
├── .env # 环境变量
└── server.ts # 服务器启动文件
8.2.3 路由和控制器
typescript
// start/routes.ts
import Route from '@ioc:Adonis/Core/Route'
Route.get('/', 'HomeController.index')
Route.get('/about', 'HomeController.about')
Route.group(() => {
Route.get('/', 'PostsController.index')
Route.post('/', 'PostsController.store').middleware('auth')
Route.get('/:id', 'PostsController.show')
Route.put('/:id', 'PostsController.update').middleware('auth')
Route.delete('/:id', 'PostsController.destroy').middleware('auth')
}).prefix('/api/posts')
// app/Controllers/Http/PostsController.ts
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
import Post from 'App/Models/Post'
export default class PostsController {
public async index({ request, response }: HttpContextContract) {
const page = request.input('page', 1)
const limit = request.input('limit', 10)
const posts = await Post.query().paginate(page, limit)
return response.ok(posts)
}
public async store({ request, response, auth }: HttpContextContract) {
const postData = request.only(['title', 'content'])
const post = await Post.create({
...postData,
userId: auth.user!.id
})
return response.created(post)
}
public async show({ params, response }: HttpContextContract) {
const post = await Post.find(params.id)
if (!post) {
return response.notFound({ message: '文章未找到' })
}
return response.ok(post)
}
}
8.3 Sails.js概述
Sails.js是一个基于Express的全栈MVC框架,专注于企业级应用开发,提供了自动生成REST API、实时WebSocket等功能。
Sails.js特性 MVC架构 自动生成API 实时WebSocket ORM/Waterline 自动路由 国际化支持 安全策略
8.4 Sails.js基本用法
8.4.1 创建Sails.js应用
bash
npm install sails -g
sails new my-sails-app
cd my-sails-app
sails lift
8.4.2 模型和API
javascript
// api/models/User.js
module.exports = {
attributes: {
name: {
type: 'string',
required: true
},
email: {
type: 'string',
required: true,
unique: true,
isEmail: true
},
posts: {
collection: 'post',
via: 'owner'
}
}
};
// api/models/Post.js
module.exports = {
attributes: {
title: {
type: 'string',
required: true
},
content: {
type: 'string'
},
owner: {
model: 'user'
}
}
};
// api/controllers/PostController.js
module.exports = {
// 自定义动作
featured: async function(req, res) {
const featuredPosts = await Post.find({ isFeatured: true });
return res.json(featuredPosts);
},
// 覆盖默认动作
create: async function(req, res) {
// 自定义创建逻辑
try {
const postData = req.body;
postData.owner = req.session.userId;
const newPost = await Post.create(postData).fetch();
return res.status(201).json(newPost);
} catch (err) {
return res.serverError(err);
}
}
};
8.4.3 路由配置
javascript
// config/routes.js
module.exports.routes = {
// 自定义REST路由
'GET /api/posts/featured': 'PostController.featured',
// 蓝图API路由 (自动生成)
'GET /api/posts': 'PostController.find',
'GET /api/posts/:id': 'PostController.findOne',
'POST /api/posts': 'PostController.create',
'PATCH /api/posts/:id': 'PostController.update',
'DELETE /api/posts/:id': 'PostController.destroy',
// 视图路由
'GET /': { view: 'pages/homepage' }
};
// config/blueprints.js
module.exports.blueprints = {
// 启用/禁用 REST 路由
rest: true,
// 启用/禁用 CRUD 快捷方式
shortcuts: false,
// 启用/禁用 WebSocket 动作
actions: false,
// REST 前缀
prefix: '/api'
};
9. 专业领域框架
9.1 Loopback - API框架
Loopback特性 API自动生成 OpenAPI规范 强大的ORM 关系管理 授权/认证 GraphQL支持
9.1.1 基本使用
bash
npm install -g @loopback/cli
lb4 app my-api
typescript
// 定义模型
import {Entity, model, property} from '@loopback/repository';
@model()
export class Product extends Entity {
@property({
type: 'number',
id: true,
generated: true,
})
id?: number;
@property({
type: 'string',
required: true,
})
name: string;
@property({
type: 'number',
required: true,
})
price: number;
constructor(data?: Partial<Product>) {
super(data);
}
}
// 定义存储库
import {DefaultCrudRepository} from '@loopback/repository';
import {Product} from '../models';
import {DbDataSource} from '../datasources';
import {inject} from '@loopback/core';
export class ProductRepository extends DefaultCrudRepository<
Product,
typeof Product.prototype.id
> {
constructor(@inject('datasources.db') dataSource: DbDataSource) {
super(Product, dataSource);
}
}
// 定义控制器
import {
Count,
CountSchema,
Filter,
FilterExcludingWhere,
repository,
Where,
} from '@loopback/repository';
import {
post,
param,
get,
getModelSchemaRef,
patch,
put,
del,
requestBody,
response,
} from '@loopback/rest';
import {Product} from '../models';
import {ProductRepository} from '../repositories';
export class ProductController {
constructor(
@repository(ProductRepository)
public productRepository : ProductRepository,
) {}
@post('/products')
@response(200, {
description: 'Product model instance',
content: {'application/json': {schema: getModelSchemaRef(Product)}},
})
async create(
@requestBody({
content: {
'application/json': {
schema: getModelSchemaRef(Product, {
title: 'NewProduct',
exclude: ['id'],
}),
},
},
})
product: Omit<Product, 'id'>,
): Promise<Product> {
return this.productRepository.create(product);
}
@get('/products/{id}')
@response(200, {
description: 'Product model instance',
content: {
'application/json': {
schema: getModelSchemaRef(Product, {includeRelations: true}),
},
},
})
async findById(
@param.path.number('id') id: number,
@param.filter(Product, {exclude: 'where'}) filter?: FilterExcludingWhere<Product>
): Promise<Product> {
return this.productRepository.findById(id, filter);
}
}
9.2 Strapi - 内容管理框架
Strapi特性 无头CMS 自定义内容类型 管理面板 用户角色权限 插件系统 RESTful API GraphQL API
9.2.1 基本使用
bash
npx create-strapi-app my-project
javascript
// 自定义控制器
// ./src/api/article/controllers/custom.js
module.exports = {
async featured(ctx) {
try {
const featuredArticles = await strapi.db.query('api::article.article').findMany({
where: { featured: true },
populate: ['cover', 'category', 'author'],
});
return featuredArticles;
} catch (err) {
ctx.body = err;
}
},
};
// 自定义路由
// ./src/api/article/routes/custom.js
module.exports = {
routes: [
{
method: 'GET',
path: '/articles/featured',
handler: 'custom.featured',
config: {
policies: [],
middlewares: [],
},
},
],
};
// 生命周期钩子
// ./src/api/article/content-types/article/lifecycles.js
module.exports = {
beforeCreate(event) {
const { data, where, select, populate } = event.params;
// 自动生成slug
if (data.title && !data.slug) {
data.slug = slugify(data.title, { lower: true });
}
},
afterCreate(event) {
const { result, params } = event;
// 发送通知
console.log(`Created article: ${result.title}`);
},
};
10. 框架选择指南与比较
10.1 框架特性对比
框架特性对比 性能 学习曲线 开发速度 TypeScript支持 社区支持 企业适用性 Fastify > Koa > Express > Nest > Adonis Express < Koa < Fastify < Nest < Adonis Adonis > Nest > Express > Koa > Fastify Nest > Adonis > Next > Express/Koa/Fastify Express > Next > Nest > Koa > Fastify > Adonis Nest > Adonis > Express > Fastify > Koa
10.2 适用场景选择
结语
感谢您的阅读!期待您的一键三连!欢迎指正!
