最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

NestJS+TypeScript 全棧項(xiàng)目骨架配置實(shí)戰(zhàn)

 更新時(shí)間:2026年04月19日 10:41:24   作者:代碼搬運(yùn)媛  
對(duì)前端轉(zhuǎn)全棧來(lái)說(shuō),NestJS + TypeScript 是零語(yǔ)言切換成本、快速落地的最優(yōu)解,本文就來(lái)詳細(xì)的介紹一下NestJS+TypeScript 全棧項(xiàng)目骨架配置實(shí)戰(zhàn),感興趣的可以了解一下

對(duì)前端轉(zhuǎn)全棧來(lái)說(shuō),NestJS + TypeScript 是「零語(yǔ)言切換成本、快速落地」的最優(yōu)解。這一章,我們不聊理論,只做「手把手實(shí)操」—— 從環(huán)境準(zhǔn)備到項(xiàng)目骨架搭建,再到第一個(gè)接口開(kāi)發(fā),全程帶代碼、帶命令,讓你 1 小時(shí)內(nèi)跑通全棧項(xiàng)目基礎(chǔ)架構(gòu)。

核心目標(biāo):搭建一個(gè)「前端可調(diào)用、支持 AI API 對(duì)接、帶數(shù)據(jù)庫(kù)連接」的全棧后端骨架,為后續(xù) AI 功能落地打基礎(chǔ)。

一、前置環(huán)境準(zhǔn)備(必做,5 分鐘搞定)

NestJS 基于 Node.js,所以先確保你的環(huán)境滿(mǎn)足要求,按以下步驟操作:

1. 安裝 Node.js(核心依賴(lài))

  • 要求:Node.js 版本 ≥ 18.x(推薦 18.17.0 或 20.x,LTS 版本更穩(wěn)定)
  • 下載地址:Node.js官網(wǎng)(選對(duì)應(yīng)系統(tǒng)的 LTS 版本)
  • 驗(yàn)證:安裝完成后,打開(kāi)終端輸入以下命令,能顯示版本號(hào)即成功:
node -v # 輸出 v18.17.0 之類(lèi)的版本號(hào)
npm -v  # 輸出 9.x 或 10.x 版本號(hào)

2. 安裝 Nest CLI(項(xiàng)目腳手架,必裝)

Nest CLI 能快速創(chuàng)建項(xiàng)目、生成模塊 / 控制器 / 服務(wù),前端同學(xué)可以理解為「Nest 版的 Vue CLI/Create React App」。

終端執(zhí)行以下命令全局安裝:

npm install -g @nestjs/cli

驗(yàn)證:輸入 nest -v,顯示版本號(hào)即成功(如 10.3.0)。

3. 可選工具(提升開(kāi)發(fā)效率)

  • 代碼編輯器:推薦 VS Code,安裝以下插件:
    • ESLint(代碼校驗(yàn))
    • Prettier(代碼格式化)
    • NestJS Snippets(Nest 語(yǔ)法提示)
    • Prisma(若選 Prisma 數(shù)據(jù)庫(kù),提前安裝)
    • TypeORM(若選 TypeORM 數(shù)據(jù)庫(kù),提前安裝)
  • 終端:Windows 推薦 PowerShell/Windows Terminal,Mac/Linux 用自帶終端即可。
  • API 調(diào)試工具:Postman 或 Apifox(后續(xù)測(cè)試接口用)。

二、創(chuàng)建 NestJS 項(xiàng)目(10 分鐘搞定)

1. 初始化項(xiàng)目

終端進(jìn)入你想存放項(xiàng)目的文件夾(如 ~/projects),執(zhí)行以下命令創(chuàng)建項(xiàng)目:

# nest new 項(xiàng)目名(推薦用英文,比如 ai-fullstack-demo)
nest new ai-fullstack-demo

執(zhí)行后會(huì)出現(xiàn)選項(xiàng):

  • 選擇包管理器:推薦選 npm(最通用,避免后續(xù)依賴(lài)問(wèn)題)
  • 等待安裝依賴(lài)(約 1-3 分鐘,取決于網(wǎng)絡(luò))

2. 項(xiàng)目目錄結(jié)構(gòu)解析(前端視角看懂核心目錄)

安裝完成后,用 VS Code 打開(kāi)項(xiàng)目,核心目錄結(jié)構(gòu)如下(不用記,先有個(gè)印象):

ai-fullstack-demo/
├── src/                  # 核心代碼目錄(所有業(yè)務(wù)邏輯寫(xiě)這里)
│   ├── app.controller.ts # 控制器(處理路由、接收請(qǐng)求)→ 類(lèi)似前端的路由配置
│   ├── app.service.ts    # 服務(wù)(處理業(yè)務(wù)邏輯)→ 類(lèi)似前端的工具函數(shù)/API 封裝
│   ├── app.module.ts     # 根模塊(項(xiàng)目入口,整合所有功能模塊)→ 類(lèi)似前端的入口文件
│   └── main.ts           # 項(xiàng)目啟動(dòng)文件(配置端口、中間件等)
├── package.json          # 依賴(lài)配置(和前端一樣)
├── tsconfig.json         # TypeScript 配置(前端同學(xué)熟悉的配置文件)
└── nest-cli.json         # Nest CLI 配置(無(wú)需修改,默認(rèn)即可)

對(duì)前端同學(xué)的通俗解釋?zhuān)?/p>

  • 控制器(Controller):負(fù)責(zé)「接收請(qǐng)求」—— 比如前端調(diào)用 /api/ai/generate,就由對(duì)應(yīng)的控制器處理路由;
  • 服務(wù)(Service):負(fù)責(zé)「處理邏輯」—— 比如調(diào)用 OpenAI API、操作數(shù)據(jù)庫(kù),都寫(xiě)在 Service 里;
  • 模塊(Module):負(fù)責(zé)「整合功能」—— 比如把 AI 相關(guān)的控制器、服務(wù)、數(shù)據(jù)庫(kù)模型打包成一個(gè) AiModule,結(jié)構(gòu)清晰。

3. 啟動(dòng)項(xiàng)目,驗(yàn)證環(huán)境

終端進(jìn)入項(xiàng)目根目錄,執(zhí)行啟動(dòng)命令:

cd ai-fullstack-demo
npm run start:dev # 開(kāi)發(fā)模式啟動(dòng)(熱更新,改代碼不用重啟服務(wù))

啟動(dòng)成功后,終端會(huì)顯示:

[Nest] 12345  - 2026/04/07 10:00:00     LOG [NestFactory] Starting Nest application...
[Nest] 12345  - 2026/04/07 10:00:01     LOG [InstanceLoader] AppModule dependencies initialized +100ms
[Nest] 12345  - 2026/04/07 10:00:01     LOG [NestApplication] Nest application successfully started +50ms

打開(kāi)瀏覽器訪(fǎng)問(wèn) http://localhost:3000,能看到 Hello World! 即說(shuō)明項(xiàng)目啟動(dòng)成功!

三、搭建核心模塊(全棧骨架核心,30 分鐘搞定)

我們要搭建「用戶(hù)模塊 + AI 模塊 + 數(shù)據(jù)庫(kù)連接」的基礎(chǔ)骨架,后續(xù)所有功能(如 AI 生成代碼、用戶(hù)登錄)都基于這個(gè)結(jié)構(gòu)擴(kuò)展。

1. 用 Nest CLI 快速生成模塊(高效不手寫(xiě))

Nest CLI 支持自動(dòng)生成模塊、控制器、服務(wù),避免手動(dòng)創(chuàng)建文件和配置,終端執(zhí)行以下命令:

# 生成用戶(hù)模塊(處理用戶(hù)登錄、注冊(cè)等)
nest generate module modules/user
nest generate controller modules/user # 生成用戶(hù)控制器
nest generate service modules/user   # 生成用戶(hù)服務(wù)
# 生成 AI 模塊(處理 AI API 調(diào)用、生成功能等)
nest generate module modules/ai
nest generate controller modules/ai
nest generate service modules/ai

執(zhí)行后,項(xiàng)目會(huì)新增 src/modules 目錄,自動(dòng)創(chuàng)建 user 和 ai 兩個(gè)模塊,且會(huì)自動(dòng)在根模塊 app.module.ts 中導(dǎo)入(不用手動(dòng)配置,太香了!)。

2. 配置 TypeScript(前端友好,統(tǒng)一類(lèi)型規(guī)范)

打開(kāi) tsconfig.json,確保以下配置(默認(rèn)已配置,重點(diǎn)看這幾項(xiàng)):

{
  "compilerOptions": {
    "module": "commonjs",
    "declaration": true,
    "removeComments": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true, // 啟用裝飾器(Nest 核心特性)
    "target": "ES2021", // 目標(biāo) ES 版本,兼容 Node.js 18+
    "sourceMap": true,
    "outDir": "./dist",
    "baseUrl": "./",
    "incremental": true,
    "skipLibCheck": true,
    "strictNullChecks": true, // 嚴(yán)格 null 檢查(避免 undefined 報(bào)錯(cuò),前端熟悉)
    "noImplicitAny": true, // 禁止隱式 any 類(lèi)型(強(qiáng)制寫(xiě)類(lèi)型,更規(guī)范)
    "strictBindCallApply": true,
    "forceConsistentCasingInFileNames": true
  }
}

這些配置和前端項(xiàng)目的 TS 配置基本一致,前端同學(xué)不用額外學(xué)習(xí)。

3. 數(shù)據(jù)庫(kù)選型與連接(TypeORM vs Prisma 二選一,前端友好)

全棧項(xiàng)目離不開(kāi)數(shù)據(jù)庫(kù),NestJS 最常用的兩種 ORM 工具是 TypeORMPrisma。兩者各有優(yōu)勢(shì),前端同學(xué)可根據(jù)自身情況選擇,以下先對(duì)比核心差異,再分別給出實(shí)操步驟:

3.1 TypeORM vs Prisma 核心對(duì)比(前端視角)

對(duì)比維度TypeORMPrisma前端轉(zhuǎn)全棧適配度
核心定位傳統(tǒng) ORM(對(duì)象關(guān)系映射)下一代 ORM(類(lèi)型安全查詢(xún)構(gòu)建器)兩者均高,Prisma 更易上手
類(lèi)型安全依賴(lài) TypeScript 裝飾器,需手動(dòng)定義類(lèi)型自動(dòng)生成類(lèi)型,零手動(dòng)維護(hù)Prisma 更優(yōu)(前端熟悉的 “自動(dòng)類(lèi)型” 邏輯)
模型定義用「實(shí)體類(lèi) + 裝飾器」映射數(shù)據(jù)庫(kù)表用「Prisma Schema DSL」定義模型TypeORM 更貼近前端 “類(lèi) + 裝飾器” 思維;Prisma 更簡(jiǎn)潔
學(xué)習(xí)成本中(需學(xué)裝飾器、Repository、查詢(xún)構(gòu)建器)低(語(yǔ)法簡(jiǎn)潔,類(lèi)似寫(xiě) interface)Prisma 更低(前端無(wú)額外認(rèn)知負(fù)擔(dān))
開(kāi)發(fā)效率中等(查詢(xún)需拼接 Repository 方法)高(鏈?zhǔn)讲樵?xún) + 自動(dòng)補(bǔ)全,少寫(xiě)冗余代碼)Prisma 更優(yōu)
生態(tài)適配NestJS 官方推薦,支持所有數(shù)據(jù)庫(kù)NestJS 無(wú)縫集成,支持主流數(shù)據(jù)庫(kù)持平
遷移體驗(yàn)命令行生成遷移文件,需手動(dòng)調(diào)整 SQL聲明式遷移,自動(dòng)生成 SQL,支持回滾Prisma 更友好(前端不用懂復(fù)雜 SQL)
調(diào)試體驗(yàn)需打印 SQL 調(diào)試,類(lèi)型錯(cuò)誤運(yùn)行時(shí)才暴露編譯時(shí)類(lèi)型校驗(yàn),Prisma Studio 可視化調(diào)試Prisma 更優(yōu)

選型建議

  • 若你 已用 TypeORM 或熟悉類(lèi) + 裝飾器語(yǔ)法(比如 React 裝飾器),選 TypeORM,無(wú)縫銜接前端思維;
  • 若你 剛起步、怕麻煩、想少寫(xiě)代碼,選 Prisma,自動(dòng)類(lèi)型提示 + 可視化工具,開(kāi)發(fā)效率拉滿(mǎn)。

3.2 方案一:TypeORM + SQLite(適合已有 TypeORM 經(jīng)驗(yàn)的同學(xué))

SQLite 是文件型數(shù)據(jù)庫(kù)(不用安裝服務(wù),零配置,適合開(kāi)發(fā)階段),TypeORM 是 NestJS 官方推薦 ORM,以下是完整實(shí)操:

步驟 1:安裝 TypeORM 依賴(lài)

npm install @nestjs/typeorm typeorm sqlite3

步驟 2:定義 TypeORM 實(shí)體(數(shù)據(jù)庫(kù)表結(jié)構(gòu))

新建 src/modules/user/entities/user.entity.ts:

import { Entity, PrimaryGeneratedColumn, Column, CreateDateColumn, UpdateDateColumn, OneToMany } from 'typeorm';
import { AiRecord } from '../../ai/entities/ai-record.entity';
@Entity('users') // 映射數(shù)據(jù)庫(kù)表 users
export class User {
  @PrimaryGeneratedColumn('uuid') // 主鍵,UUID 類(lèi)型
  id: string;
  @Column({ unique: true, length: 64 }) // 唯一字段,字符串類(lèi)型
  username: string;
  @Column({ unique: true, length: 128 })
  email: string;
  @Column({ length: 255 })
  password: string;
  @CreateDateColumn({ name: 'created_at' }) // 自動(dòng)維護(hù)創(chuàng)建時(shí)間
  createdAt: Date;
  @UpdateDateColumn({ name: 'updated_at' }) // 自動(dòng)維護(hù)更新時(shí)間
  updatedAt: Date;
  @OneToMany(() => AiRecord, (aiRecord) => aiRecord.user) // 一對(duì)多關(guān)聯(lián)(關(guān)聯(lián) AI 生成記錄)
  aiRecords: AiRecord[];
}

新建 src/modules/ai/entities/ai-record.entity.ts:

import { Entity, PrimaryGeneratedColumn, Column, CreateDateColumn, UpdateDateColumn, ManyToOne, JoinColumn } from 'typeorm';
import { User } from '../../user/entities/user.entity';
@Entity('ai_records') // 映射數(shù)據(jù)庫(kù)表 ai_records
export class AiRecord {
  @PrimaryGeneratedColumn('uuid')
  id: string;
  @Column('text') // 長(zhǎng)文本字段(存儲(chǔ) AI 生成內(nèi)容)
  content: string;
  @Column({ length: 32 }) // 生成類(lèi)型(如 "code"、"text")
  type: string;
  @Column({ length: 32, default: 'success' }) // 狀態(tài)(success/error)
  status: string;
  @Column({ name: 'user_id' }) // 外鍵字段(關(guān)聯(lián)用戶(hù)表)
  userId: string;
  @CreateDateColumn({ name: 'created_at' })
  createdAt: Date;
  @UpdateDateColumn({ name: 'updated_at' })
  updatedAt: Date;
  @ManyToOne(() => User, (user) => user.aiRecords) // 多對(duì)一關(guān)聯(lián)
  @JoinColumn({ name: 'user_id' }) // 顯式指定外鍵列名,避免歧義
  user: User;
}

步驟 3:配置 TypeORM 數(shù)據(jù)源

新建 src/config/typeorm.config.ts:

import { DataSource } from 'typeorm';
import { ConfigService } from '@nestjs/config';
import { User } from '../modules/user/entities/user.entity';
import { AiRecord } from '../modules/ai/entities/ai-record.entity';
export const getTypeOrmConfig = (configService: ConfigService) => ({
  type: 'sqlite', // 數(shù)據(jù)庫(kù)類(lèi)型:SQLite
  database: configService.get('DATABASE_URL') || 'dev.db', // 數(shù)據(jù)庫(kù)文件(自動(dòng)生成)
  entities: [User, AiRecord], // 注冊(cè)實(shí)體(數(shù)據(jù)庫(kù)表映射)
  synchronize: false, // 生產(chǎn)環(huán)境禁用!用遷移管理表結(jié)構(gòu)
  migrations: ['dist/src/migrations/*.js'], // 遷移文件路徑
  migrationsTableName: 'migrations', // 遷移記錄表名
});

在根模塊 src/app.module.ts 中導(dǎo)入 TypeORM 配置:

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { UserModule } from './modules/user/user.module';
import { AiModule } from './modules/ai/ai.module';
import { TypeOrmModule } from '@nestjs/typeorm';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { getTypeOrmConfig } from './config/typeorm.config';
@Module({
  imports: [
    ConfigModule.forRoot({ isGlobal: true }), // 加載環(huán)境變量(.env 文件)
    TypeOrmModule.forRootAsync({
      useFactory: getTypeOrmConfig,
      inject: [ConfigService], // 注入配置服務(wù)
    }),
    UserModule,
    AiModule,
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

步驟 4:生成數(shù)據(jù)庫(kù)表(遷移命令)

# 1. 生成遷移文件(基于實(shí)體類(lèi)變更)
npx typeorm-ts-node-commonjs migration:generate src/migrations/init-tables --dataSource src/config/typeorm.config.ts
# 2. 執(zhí)行遷移(創(chuàng)建數(shù)據(jù)庫(kù)表)
npx typeorm-ts-node-commonjs migration:run --dataSource src/config/typeorm.config.ts

執(zhí)行成功后,項(xiàng)目根目錄會(huì)生成 dev.db 數(shù)據(jù)庫(kù)文件,表結(jié)構(gòu)與實(shí)體類(lèi)一致。

3.3 方案二:Prisma + SQLite(適合新手、追求高效的同學(xué))

Prisma 是 TypeScript 友好的 ORM 工具,自動(dòng)生成類(lèi)型,不用懂 SQL,以下是完整實(shí)操:

步驟 1:安裝 Prisma 依賴(lài)

npm install prisma --save-dev
npm install @prisma/client

步驟 2:初始化 Prisma

npx prisma init

執(zhí)行后會(huì)生成:

  • prisma/schema.prisma:數(shù)據(jù)庫(kù)模型配置文件(定義表結(jié)構(gòu));
  • .env:環(huán)境變量文件(默認(rèn)生成 DATABASE_URL,配置數(shù)據(jù)庫(kù)連接地址)。

步驟 3:配置數(shù)據(jù)庫(kù)連接(SQLite)

打開(kāi) .env 文件,修改 DATABASE_URL 為 SQLite 連接地址:

# 原配置(PostgreSQL)注釋掉,替換為以下內(nèi)容
DATABASE_URL="file:./dev.db" # SQLite 數(shù)據(jù)庫(kù)文件(會(huì)自動(dòng)生成在 prisma 目錄下)

步驟 4:定義 Prisma 模型(數(shù)據(jù)庫(kù)表結(jié)構(gòu))

打開(kāi) prisma/schema.prisma,替換為以下代碼:

generator client {
  provider = "prisma-client-js"
}
datasource db {
  provider = "sqlite" // 數(shù)據(jù)庫(kù)類(lèi)型:SQLite
  url      = env("DATABASE_URL") // 連接地址(從 .env 讀?。?
}
// 用戶(hù)表(存儲(chǔ)用戶(hù)信息,后續(xù)登錄用)
model User {
  id        String      @id @default(uuid()) // 主鍵,自動(dòng)生成 UUID
  username  String      @unique // 用戶(hù)名(唯一)
  email     String      @unique // 郵箱(唯一)
  password  String      // 密碼(后續(xù)會(huì)加密)
  createdAt DateTime    @default(now()) // 創(chuàng)建時(shí)間
  updatedAt DateTime    @updatedAt // 更新時(shí)間
  aiRecords AiRecord[]  // 關(guān)聯(lián) AI 生成記錄(一對(duì)多)
}
// AI 生成記錄表(存儲(chǔ) AI 生成的內(nèi)容,如代碼、文案)
model AiRecord {
  id        String   @id @default(uuid())
  content   String   // 生成的內(nèi)容(如代碼字符串)
  type      String   // 生成類(lèi)型(如 "code"、"text")
  status    String   @default("success") // 狀態(tài)(success/error)
  userId    String   // 關(guān)聯(lián)的用戶(hù) ID
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt
  user      User     @relation(fields: [userId], references: [id]) // 關(guān)聯(lián)用戶(hù)表
}

步驟 5:生成數(shù)據(jù)庫(kù)和 Prisma 客戶(hù)端

npx prisma migrate dev --name init
  • --name init:給這次數(shù)據(jù)庫(kù)遷移起個(gè)名字(初始化);
  • 執(zhí)行成功后,會(huì)生成 prisma/dev.db 數(shù)據(jù)庫(kù)文件,且自動(dòng)生成 TypeScript 客戶(hù)端(用于操作數(shù)據(jù)庫(kù))。

步驟 6:封裝 Prisma 全局服務(wù)

nest generate service prisma

打開(kāi) src/prisma/prisma.service.ts,替換為以下代碼:

import { Injectable, OnModuleInit } from '@nestjs/common';
import { PrismaClient } from '@prisma/client';
@Injectable()
export class PrismaService extends PrismaClient implements OnModuleInit {
  // 模塊初始化時(shí)連接數(shù)據(jù)庫(kù)
  async onModuleInit() {
    await this.$connect();
  }
}

打開(kāi) src/prisma/prisma.module.ts,修改為全局模塊:

import { Global, Module } from '@nestjs/common';
import { PrismaService } from './prisma.service';
@Global() // 標(biāo)記為全局模塊,所有模塊無(wú)需導(dǎo)入即可使用
@Module({
  providers: [PrismaService],
  exports: [PrismaService], // 導(dǎo)出服務(wù),供其他模塊使用
})
export class PrismaModule {}

在根模塊 src/app.module.ts 中導(dǎo)入 PrismaModule:

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { UserModule } from './modules/user/user.module';
import { AiModule } from './modules/ai/ai.module';
import { PrismaModule } from './prisma/prisma.module'; // 導(dǎo)入 Prisma 模塊
@Module({
  imports: [PrismaModule, UserModule, AiModule], // 加入全局模塊
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

四、開(kāi)發(fā)第一個(gè)接口(驗(yàn)證骨架可用性,二選一)

根據(jù)你選擇的數(shù)據(jù)庫(kù)方案,以下分別給出 TypeORM 和 Prisma 版本的 AI 生成接口,驗(yàn)證模塊、數(shù)據(jù)庫(kù)、路由是否正常工作:

方案一:TypeORM 版本接口

步驟 1:定義請(qǐng)求參數(shù) DTO

新建 src/modules/ai/dto/generate-text.dto.ts:

// 定義 AI 生成請(qǐng)求的參數(shù)類(lèi)型(前端可復(fù)用)
export class GenerateTextDto {
  prompt: string; // 提示詞(如 "寫(xiě)一段前端學(xué)習(xí)文案")
  type: string; // 生成類(lèi)型(如 "text")
  userId: string; // 關(guān)聯(lián)的用戶(hù) ID(測(cè)試用,后續(xù)替換為登錄用戶(hù))
}

步驟 2:編寫(xiě) AI 服務(wù)邏輯

打開(kāi) src/modules/ai/ai.service.ts,替換為以下代碼:

import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { AiRecord } from './entities/ai-record.entity';
import { GenerateTextDto } from './dto/generate-text.dto';
@Injectable()
export class AiService {
  // 注入 AiRecord 實(shí)體的 Repository(操作數(shù)據(jù)庫(kù))
  constructor(@InjectRepository(AiRecord) private aiRecordRepo: Repository<AiRecord>) {}
  // 模擬 AI 生成文本(后續(xù)替換為真實(shí) LLM API 調(diào)用)
  async generateText(dto: GenerateTextDto) {
    // 1. 模擬 AI 生成結(jié)果(實(shí)際項(xiàng)目中替換為 OpenAI/通義千問(wèn) API 調(diào)用)
    const generatedContent = `AI 生成結(jié)果(基于提示詞:${dto.prompt}):前端轉(zhuǎn)全棧,用 NestJS + TypeORM 真的太香了!`;
    // 2. 把生成結(jié)果存入數(shù)據(jù)庫(kù)
    const aiRecord = this.aiRecordRepo.create({
      content: generatedContent,
      type: dto.type,
      userId: dto.userId,
    });
    await this.aiRecordRepo.save(aiRecord);
    // 3. 返回結(jié)果(包含數(shù)據(jù)庫(kù)記錄 ID)
    return {
      success: true,
      data: {
        recordId: aiRecord.id,
        content: generatedContent,
      },
    };
  }
}

步驟 3:定義接口路由

打開(kāi) src/modules/ai/ai.controller.ts,替換為以下代碼:

import { Controller, Post, Body } from '@nestjs/common';
import { AiService } from './ai.service';
import { GenerateTextDto } from './dto/generate-text.dto';
@Controller('api/ai') // 路由前綴:所有接口都以 /api/ai 開(kāi)頭
export class AiController {
  constructor(private readonly aiService: AiService) {}
  // 定義 POST 接口:/api/ai/generate-text
  @Post('generate-text')
  async generateText(@Body() dto: GenerateTextDto) {
    return this.aiService.generateText(dto);
  }
}

方案二:Prisma 版本接口

步驟 1:定義請(qǐng)求參數(shù) DTO

新建 src/modules/ai/dto/generate-text.dto.ts:

// 定義 AI 生成請(qǐng)求的參數(shù)類(lèi)型(前端可復(fù)用)
export class GenerateTextDto {
  prompt: string; // 提示詞(如 "寫(xiě)一段前端學(xué)習(xí)文案")
  type: string; // 生成類(lèi)型(如 "text")
  userId: string; // 關(guān)聯(lián)的用戶(hù) ID(測(cè)試用,后續(xù)替換為登錄用戶(hù))
}

步驟 2:編寫(xiě) AI 服務(wù)邏輯

打開(kāi) src/modules/ai/ai.service.ts,替換為以下代碼:

import { Injectable } from '@nestjs/common';
import { PrismaService } from 'src/prisma/prisma.service';
import { GenerateTextDto } from './dto/generate-text.dto';
@Injectable()
export class AiService {
  constructor(private prisma: PrismaService) {} // 注入 Prisma 全局服務(wù)
  // 模擬 AI 生成文本(后續(xù)替換為真實(shí) LLM API 調(diào)用)
  async generateText(dto: GenerateTextDto) {
    // 1. 模擬 AI 生成結(jié)果(實(shí)際項(xiàng)目中替換為 OpenAI/通義千問(wèn) API 調(diào)用)
    const generatedContent = `AI 生成結(jié)果(基于提示詞:${dto.prompt}):前端轉(zhuǎn)全棧,用 NestJS + Prisma 開(kāi)發(fā)效率翻倍!`;
    // 2. 把生成結(jié)果存入數(shù)據(jù)庫(kù)
    const aiRecord = await this.prisma.aiRecord.create({
      data: {
        content: generatedContent,
        type: dto.type,
        userId: dto.userId,
      },
    });
    // 3. 返回結(jié)果(包含數(shù)據(jù)庫(kù)記錄 ID)
    return {
      success: true,
      data: {
        recordId: aiRecord.id,
        content: generatedContent,
      },
    };
  }
}

步驟 3:定義接口路由

打開(kāi) src/modules/ai/ai.controller.ts,替換為以下代碼:

import { Controller, Post, Body } from '@nestjs/common';
import { AiService } from './ai.service';
import { GenerateTextDto } from './dto/generate-text.dto';
@Controller('api/ai') // 路由前綴:所有接口都以 /api/ai 開(kāi)頭
export class AiController {
  constructor(private readonly aiService: AiService) {}
  // 定義 POST 接口:/api/ai/generate-text
  @Post('generate-text')
  async generateText(@Body() dto: GenerateTextDto) {
    return this.aiService.generateText(dto);
  }
}

步驟 4:測(cè)試接口(用 Postman/Apifox)

  1. 確保項(xiàng)目處于運(yùn)行狀態(tài)(npm run start:dev);
  2. 打開(kāi) Postman,創(chuàng)建一個(gè) POST 請(qǐng)求,地址:http://localhost:3000/api/ai/generate-text;
  3. 請(qǐng)求體(Body)選擇 raw → JSON,輸入以下參數(shù):
{
  "prompt": "寫(xiě)一段前端學(xué)習(xí)文案",
  "type": "text",
  "userId": "test-user-123" // 測(cè)試用用戶(hù) ID,后續(xù)替換為真實(shí)用戶(hù)
}
  1. 發(fā)送請(qǐng)求,成功返回以下結(jié)果即說(shuō)明接口正常工作:
{
  "success": true,
  "data": {
    "recordId": "xxx-xxx-xxx-xxx", // 自動(dòng)生成的記錄 ID
    "content": "AI 生成結(jié)果(基于提示詞:寫(xiě)一段前端學(xué)習(xí)文案):前端轉(zhuǎn)全棧,用 NestJS + XXX 真的太香了!"
  }
}

同時(shí),數(shù)據(jù)庫(kù)中會(huì)新增一條 AI 生成記錄,驗(yàn)證數(shù)據(jù)庫(kù)連接成功。

五、項(xiàng)目骨架總結(jié)與后續(xù)擴(kuò)展

到這里,我們的 NestJS + TypeScript 全棧項(xiàng)目骨架已經(jīng)搭建完成,包含:

? 基礎(chǔ)環(huán)境配置(Node.js + Nest CLI + TypeScript);

? 核心模塊結(jié)構(gòu)(用戶(hù)模塊 + AI 模塊 + 數(shù)據(jù)庫(kù)模塊);

? 數(shù)據(jù)庫(kù)連接(TypeORM/Prisma 二選一,支持類(lèi)型安全);

? 測(cè)試接口(AI 生成文本,包含數(shù)據(jù)庫(kù)存儲(chǔ));

? 前端友好的類(lèi)型定義(前后端可復(fù)用 interface/dto)。

這個(gè)骨架的優(yōu)勢(shì):

  1. 前后端 TypeScript 類(lèi)型互通 —— 前端可直接復(fù)用后端的 GenerateTextDto 類(lèi)型,避免字段不一致;
  2. 模塊化清晰 —— 后續(xù)新增功能(如用戶(hù)登錄、AI 生成代碼),只需新增對(duì)應(yīng)模塊;
  3. 可擴(kuò)展性強(qiáng) —— 后續(xù)替換為真實(shí) LLM API、切換數(shù)據(jù)庫(kù)(如 MySQL/PostgreSQL)、添加權(quán)限校驗(yàn),都能基于這個(gè)骨架快速擴(kuò)展。

到此這篇關(guān)于NestJS+TypeScript 全棧項(xiàng)目骨架配置實(shí)戰(zhàn)的文章就介紹到這了,更多相關(guān)NestJS TypeScript 配置內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 如何使用 Intl.RelativeTimeFormat 在 JavaScript 中進(jìn)行相對(duì)時(shí)間格式化

    如何使用 Intl.RelativeTimeFormat 在 JavaScript&nbs

    Intl.RelativeTimeFormat是JavaScript提供的一個(gè)國(guó)際化API,用于格式化相對(duì)時(shí)間,如"3天前"或"2年后",支持多種語(yǔ)言和配置選項(xiàng),適用于社交媒體時(shí)間戳和事件提醒等場(chǎng)景,它簡(jiǎn)化了國(guó)際化的相對(duì)時(shí)間顯示,使開(kāi)發(fā)者能夠根據(jù)用戶(hù)的語(yǔ)言和區(qū)域設(shè)置輕松實(shí)現(xiàn)時(shí)間格式化
    2024-09-09
  • JavaScript實(shí)現(xiàn)網(wǎng)頁(yè)版五子棋游戲

    JavaScript實(shí)現(xiàn)網(wǎng)頁(yè)版五子棋游戲

    這篇文章主要為大家詳細(xì)介紹了JavaScript實(shí)現(xiàn)網(wǎng)頁(yè)版五子棋游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • 輕量級(jí)JavaScript模糊搜索庫(kù)Fuse.js入門(mén)教程

    輕量級(jí)JavaScript模糊搜索庫(kù)Fuse.js入門(mén)教程

    Fuse.js是一個(gè)功能強(qiáng)大且易于使用的模糊搜索庫(kù),它的輕量級(jí)設(shè)計(jì)和高度可配置性使其成為前端搜索的絕佳選擇,本文給大家介紹輕量級(jí)JavaScript模糊搜索庫(kù)Fuse.js入門(mén)教程,感興趣的朋友跟隨小編一起看看吧
    2025-11-11
  • JavaScript利用Canvas實(shí)現(xiàn)粒子動(dòng)畫(huà)倒計(jì)時(shí)

    JavaScript利用Canvas實(shí)現(xiàn)粒子動(dòng)畫(huà)倒計(jì)時(shí)

    粒子動(dòng)畫(huà)就是頁(yè)面上通過(guò)發(fā)射許多微小粒子來(lái)表示不規(guī)則模糊物體。本文將利用canvas實(shí)現(xiàn)酷炫的粒子動(dòng)畫(huà)倒計(jì)時(shí),感興趣的小伙伴可以嘗試一下
    2022-12-12
  • 在uniapp中如何去掉一些不想要的權(quán)限

    在uniapp中如何去掉一些不想要的權(quán)限

    在uniapp中,云打包以后會(huì)自動(dòng)增加一個(gè)電話(huà)權(quán)限,并且在manifest.json里面也沒(méi)有添加這個(gè)權(quán)限,怎么添加都添加不上,下面小編給大家分享在uniapp中如何去掉一些不想要的權(quán)限,感興趣的朋友跟隨小編一起看看吧
    2024-03-03
  • js文件中調(diào)用js的實(shí)現(xiàn)方法小結(jié)

    js文件中調(diào)用js的實(shí)現(xiàn)方法小結(jié)

    JavaScript文件引用JavaScript文件的方法,需要的朋友可以參考下。
    2009-10-10
  • 微信小程序使用input組件實(shí)現(xiàn)密碼框功能【附源碼下載】

    微信小程序使用input組件實(shí)現(xiàn)密碼框功能【附源碼下載】

    這篇文章主要介紹了微信小程序使用input組件實(shí)現(xiàn)密碼框功能,涉及input組件布局設(shè)置相關(guān)操作技巧,并附帶源碼供讀者下載參考,需要的朋友可以參考下
    2017-12-12
  • JS 獲取文件后綴,判斷文件類(lèi)型(比如是否為圖片格式)

    JS 獲取文件后綴,判斷文件類(lèi)型(比如是否為圖片格式)

    這篇文章主要介紹了JS 獲取文件后綴,判斷文件類(lèi)型(比如是否為圖片格式),需要的朋友可以參考下
    2020-05-05
  • javascript去除空格方法小結(jié)

    javascript去除空格方法小結(jié)

    這篇文章主要介紹了javascript去除空格方法,實(shí)例總結(jié)了javascript去除字符串空格的常用技巧,需要的朋友可以參考下
    2015-05-05
  • preact組件案例的使用詳解

    preact組件案例的使用詳解

    SelectValue是一個(gè)Preact組件,用于創(chuàng)建一個(gè)下拉選擇框,它接收props如value、setfn、options和disabled,用于更新父組件中的值、處理下拉選擇框的值改變事件、顯示選項(xiàng)和禁用或啟用下拉選擇框,本文介紹preact組件案例的使用詳解,感興趣的朋友一起看看吧
    2025-03-03

最新評(píng)論

华容县| 视频| 陵水| 浏阳市| 县级市| 大埔区| 施秉县| 行唐县| 泰和县| 新巴尔虎右旗| 庆阳市| 晋宁县| 崇文区| 和田县| 蒲江县| 工布江达县| 乌拉特中旗| 贡嘎县| 定西市| 顺平县| 建水县| 共和县| 庄河市| 广西| 太仆寺旗| 郓城县| 九龙坡区| 武冈市| 嘉黎县| 怀仁县| 彰化市| 梅河口市| 深水埗区| 黑水县| 姜堰市| 蛟河市| 三穗县| 红桥区| 临武县| 孟津县| 正蓝旗|