【Node.js】Web開發框架

在這里插入圖片描述

個人主頁:Guiat
歸屬專欄:node.js

在這里插入圖片描述

文章目錄

  • 1. Node.js Web框架概述
    • 1.1 Web框架的作用
    • 1.2 Node.js主要Web框架生態
    • 1.3 框架選擇考慮因素
  • 2. Express.js
    • 2.1 Express.js概述
    • 2.2 基本用法
      • 2.2.1 安裝Express
      • 2.2.2 創建基本服務器
    • 2.3 路由
    • 2.4 中間件
    • 2.5 請求和響應
    • 2.6 完整的Express應用結構
  • 3. Koa.js
    • 3.1 Koa.js概述
    • 3.2 基本用法
      • 3.2.1 安裝Koa
      • 3.2.2 創建基本服務器
    • 3.3 中間件和上下文
    • 3.4 Koa與Express對比
  • 4. Nest.js
    • 4.1 Nest.js概述
    • 4.2 基本用法
      • 4.2.1 安裝Nest.js
      • 4.2.2 主要組件
    • 4.3 依賴注入
    • 4.4 中間件、守衛和攔截器
  • 5. Fastify
    • 5.1 Fastify概述
    • 5.2 基本用法
      • 5.2.1 安裝Fastify
      • 5.2.2 創建服務器
    • 5.3 Schema驗證和序列化
    • 5.4 插件系統
    • 5.5 與Express和Koa性能對比
  • 6. Next.js
    • 6.1 Next.js概述
    • 6.2 基本用法
      • 6.2.1 創建Next.js應用
      • 6.2.2 頁面和路由
    • 6.3 數據獲取方法
    • 6.4 API路由
    • 6.5 中間件和布局
  • 7. Hapi.js
    • 7.1 Hapi.js概述
    • 7.2 基本用法
      • 7.2.1 安裝Hapi
      • 7.2.2 創建服務器
    • 7.3 路由和處理程序
    • 7.4 插件和擴展
    • 7.5 驗證和認證
  • 8. 全棧框架: AdonisJS和Sails.js
    • 8.1 AdonisJS概述
    • 8.2 AdonisJS基本用法
      • 8.2.1 創建AdonisJS應用
      • 8.2.2 AdonisJS應用結構
      • 8.2.3 路由和控制器
    • 8.3 Sails.js概述
    • 8.4 Sails.js基本用法
      • 8.4.1 創建Sails.js應用
      • 8.4.2 模型和API
      • 8.4.3 路由配置
  • 9. 專業領域框架
    • 9.1 Loopback - API框架
      • 9.1.1 基本使用
    • 9.2 Strapi - 內容管理框架
      • 9.2.1 基本使用
  • 10. 框架選擇指南與比較
    • 10.1 框架特性對比
    • 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 框架選擇考慮因素

mindmaproot((Web框架選擇))性能需求高并發應用低延遲資源消耗開發效率開發速度學習曲線社區支持項目復雜度小型項目中型應用企業級應用團隊技能TypeScript經驗現有框架經驗架構偏好生態系統中間件ORM支持插件豐富度應用類型REST APIGraphQL實時應用靜態網站

2. Express.js

2.1 Express.js概述

Express.js是Node.js最流行的Web框架,提供了簡單而靈活的API,適用于各種Web應用和API開發。

客戶端請求
Express應用
路由
中間件1
中間件2
路由處理器
響應
客戶端

2.2 基本用法

2.2.1 安裝Express

npm install express

2.2.2 創建基本服務器

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 路由

// 基本路由
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 中間件

請求
全局中間件
路由特定中間件
路由處理器
響應
// 內置中間件
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 請求和響應

// 請求對象(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);        // 客戶端IPconsole.log(req.path);      // 請求路徑console.log(req.method);    // HTTP方法// 響應對象(res)res.status(200);            // 設置狀態碼res.set('Content-Type', 'application/json'); // 設置響應頭res.cookie('name', 'value', { maxAge: 900000 }); // 設置cookieres.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

npm install koa

3.2.2 創建基本服務器

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 中間件和上下文

// 錯誤處理中間件
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' };  // 響應體// Cookiesctx.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

npm i -g @nestjs/cli
nest new project-name

4.2.2 主要組件

// 控制器 (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
// 定義提供者
@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 中間件、守衛和攔截器

客戶端請求
中間件
守衛
攔截器-前
管道
控制器路由處理
攔截器-后
異常過濾器
響應
// 中間件
@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

npm install fastify

5.2.2 創建服務器

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驗證和序列化

// 定義帶有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 插件系統

// 定義插件
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性能對比

bartitle Node.js框架性能對比(請求/秒)"Express" : 12000"Koa" : 15000"Fastify" : 30000"Bare Node.js" : 35000

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應用

npx create-next-app my-next-app
# 或
yarn create next-app my-next-app

6.2.2 頁面和路由

// 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
// 服務器端渲染示例 (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路由

// 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 中間件和布局

// 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

npm install @hapi/hapi

7.2.2 創建服務器

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 路由和處理程序

// 基本路由
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 插件和擴展

// 定義插件
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 驗證和認證

// 安裝依賴
// npm install @hapi/joi @hapi/basic @hapi/jwtconst 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應用

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 路由和控制器

// 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應用

npm install sails -g
sails new my-sails-app
cd my-sails-app
sails lift

8.4.2 模型和API

// 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 路由配置

// 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 基本使用

npm install -g @loopback/cli
lb4 app my-api
// 定義模型
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 基本使用

npx create-strapi-app my-project
// 自定義控制器
// ./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;// 自動生成slugif (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 適用場景選擇

mindmaproot((選擇框架))微服務FastifyNest.jsExpress企業應用Nest.jsLoopbackHapi.jsAPI開發ExpressFastifyKoaLoopback全棧應用Next.jsAdonisJSSails.js內容平臺StrapiNext.js實時應用Sails.jsSocket.io + Express

結語
感謝您的閱讀!期待您的一鍵三連!歡迎指正!

在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/82454.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/82454.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/82454.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

PDF 轉 JPG 圖片小工具:CodeBuddy 助力解決轉換痛點

本文所使用的 CodeBuddy 免費下載鏈接&#xff1a;騰訊云代碼助手 CodeBuddy - AI 時代的智能編程伙伴 前言 在數字化辦公與內容創作的浪潮中&#xff0c;將 PDF 文件轉換為 JPG 圖片格式的需求日益頻繁。無論是學術文獻中的圖表提取&#xff0c;還是宣傳資料的視覺化呈現&am…

Linux 文件系統層次結構

Linux 的文件系統遵循 Filesystem Hierarchy Standard (FHS) 標準&#xff0c;其目錄結構是層次化的&#xff0c;每個目錄都有明確的用途。以下是 Linux 中部分目錄的作用解析&#xff1a; 1. 根目錄 / 作用&#xff1a;根目錄是整個文件系統的頂層目錄&#xff0c;所有其他目…

密碼學標準(Cryptography Standards)介紹

密碼學標準(Cryptography Standards)是為確保信息安全傳輸、存儲和處理而制定的一系列技術規范和協議,廣泛應用于通信、金融、互聯網等領域。以下從分類、主流標準、應用場景和發展趨勢四個方面進行詳細介紹: 一、密碼學標準的分類 密碼學標準可根據技術原理和應用場景分…

ubuntu 22.04安裝和使用docker介紹

docker安裝和使用 準備環境常見的docker操作linux系統常用的配置卸載docker 準備環境 本機環境&#xff1a; Linux yz-MS-7E06 6.8.0-59-generic #61~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Tue Apr 15 17:03:15 UTC 2 x86_64 x86_64 x86_64 GNU/Linux安裝依賴軟件&#xff1a;…

obsidian 中的查找和替換插件,支持正則

最近用著 obsidian 時&#xff0c;發現想要在當前文檔中 查找和替換 內容時&#xff0c;沒有自動查找和替換的功能&#xff0c;去插件市場查找也沒有發現好用的插件&#xff0c;那就自己寫一個吧。 全程用的 AI 來寫的&#xff0c;當然&#xff0c;我對 JS/CSS/TypeScript 等沒…

針對vue項目的webpack優化攻略

一、開發階段優化 1. 熱更新加速&#xff08;HMR&#xff09; // vue.config.js module.exports {devServer: {hot: true, // 開啟熱更新injectClient: true, // 自動注入HMR客戶端watchOptions: {ignored: /node_modules/, // 忽略node_modules變化aggregateTimeout: 300…

BTC官網關注巨鯨12億美元平倉,XBIT去中心化交易平臺表現穩定

在全球加密貨幣市場波動加劇的背景下&#xff0c;2025年5月25日傳出重磅消息。據今日最新國際報道&#xff0c;知名巨鯨James Wynn完全平倉價值12億美元的BTC多頭倉位&#xff0c;整體盈利約845萬美元&#xff0c;此舉引發市場廣泛關注。與此同時&#xff0c;收益型穩定幣市場迎…

在WPF中添加動畫背景

在WPF中添加動畫背景 在WPF中創建動畫背景可以大大增強應用程序的視覺效果。以下是幾種實現動畫背景的方法&#xff1a; 方法1&#xff1a;使用動畫ImageBrush&#xff08;圖片輪播&#xff09; <Window x:Class"AnimatedBackground.MainWindow"xmlns"htt…

單點擊登錄sso實現

一、單點登錄&#xff08;SSO&#xff09;是什么&#xff1f; 核心定義 單點登錄&#xff08;Single Sign-On&#xff0c;SSO&#xff09;是一種身份認證解決方案&#xff0c;允許用戶通過一次登錄訪問多個相互信任的應用系統。其核心邏輯是統一認證中心與分布式會話管理&…

JavaWebsocket-demo

Websocket客戶端 pom依賴 <dependency><groupId>org.java-websocket</groupId><artifactId>Java-WebSocket</artifactId><version>1.4.0</version></dependency>客戶端代碼片段 Component Slf4j public class PositionAlarmL…

Java Collection(集合) 接口

Date: 2025-05-21 20:21:32 author: lijianzhan Java 集合框架提供了一組接口和類&#xff0c;以實現各種數據結構和算法。 以下是關于 Java 集合的核心內容說明&#xff1a; /*** Java Collection Framework 說明&#xff1a;** 在 Java 中&#xff0c;集合&#xff08;Collec…

讓MySQL更快:EXPLAIN語句詳盡解析

前言 在數據庫性能調優中&#xff0c;SQL 查詢的執行效率是影響系統整體性能的關鍵因素之一。MySQL 提供了強大的工具——EXPLAIN 語句&#xff0c;幫助開發者和數據庫管理員深入分析查詢的執行計劃&#xff0c;從而發現潛在的性能瓶頸并進行針對性優化。 EXPLAIN 語句能夠模…

Java基礎 Day20

一、HashSet 集合類 1、簡介 HashSet 集合底層采取哈希表存儲數據 底層是HashMap 不能使存取有序 JDK8之前的哈希表是數組和鏈表&#xff0c;頭插法 JDK8之后的哈希表是數組、鏈表和紅黑樹&#xff0c;尾插法 2、存儲元素 &#xff08;1&#xff09;如果要保證元素的唯…

2505C++,32位轉64位

原文 假設有個想要將一個32位值傳遞給一個帶64位值的函數的函數.你不關心高32位的內容,因為該值是傳遞給回調函數的直通值,回調函數會把它截斷為32位值. 因此,你都擔心編譯器一般生成的將32位值擴展到64位值的那條指令的性能影響. 我懷疑這條指令不是程序中的性能瓶頸. 我想出…

光伏電站及時巡檢:守護清潔能源的“生命線”

在“雙碳”目標驅動下&#xff0c;光伏電站作為清潔能源的主力軍&#xff0c;正以年均20%以上的裝機增速重塑全球能源格局。然而&#xff0c;這些遍布荒漠、屋頂的“光伏矩陣”并非一勞永逸的能源提款機&#xff0c;其穩定運行高度依賴精細化的巡檢維護。山東棗莊觸電事故、衢州…

C++初階-list的使用2

目錄 1.std::list::splice的使用 2.std::list::remove和std::list::remove_if的使用 2.1remove_if函數的簡單介紹 基本用法 函數原型 使用函數對象作為謂詞 使用普通函數作為謂詞 注意事項 復雜對象示例 2.2remove與remove_if的簡單使用 3.std::list::unique的使用 …

OpenHarmony平臺驅動使用(一),ADC

OpenHarmony平臺驅動使用&#xff08;一&#xff09; ADC 概述 功能簡介 ADC&#xff08;Analog to Digital Converter&#xff09;&#xff0c;即模擬-數字轉換器&#xff0c;可將模擬信號轉換成對應的數字信號&#xff0c;便于存儲與計算等操作。除電源線和地線之外&#…

CSS【詳解】彈性布局 flex

適用場景 一維&#xff08;行或列&#xff09;布局 基本概念 包裹所有被布局元素的父元素為容器 所有被布局的元素為項目 項目的排列方向&#xff08;垂直/水平&#xff09;為主軸 與主軸垂直的方向交交叉軸 容器上啟用 flex 布局 將容器的 display 樣式設置為 flex 或 i…

基于MATLAB實現傳統譜減法以及兩種改進的譜減法(增益函數譜減法、多帶譜減法)的語音增強

基于MATLAB實現傳統譜減法以及兩種改進的譜減法&#xff08;增益函數譜減法、多帶譜減法&#xff09;的語音增強代碼示例&#xff1a; 傳統譜減法 function enhanced traditional_spectral_subtraction(noisy, fs, wlen, inc, NIS, a, b)% 參數說明&#xff1a;% noisy - 帶…

symbol【ES6】

你一閉眼世界就黑了&#xff0c;你不是主角是什么&#xff1f; 目錄 什么是Symbol&#xff1f;?Symbol特點?&#xff1a;創建方法&#xff1a;注意點&#xff1a;不能進行運算&#xff1a;顯示調用toString() --沒有意義隱式轉換boolean 如果屬性名沖突了怎么辦&#xff1f;o…