[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"knowledge-\u002Fapi\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnestjs\u002Fbefore\u002Fdemo":3,"knowledge-related-\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnestjs\u002Fbefore\u002Fdemo":1558,"knowledge-series-\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnestjs\u002Fbefore\u002Fdemo":1579},{"source":4,"connector":5,"page":6},"sqlite","better-sqlite3",{"path":7,"title":8,"description":9,"category":10,"tags":11,"date":14,"pinned":15,"draft":15,"body":16,"seo":1554,"stem":1555,"id":1556,"extension":1557},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnestjs\u002Fbefore\u002Fdemo","入手Demo","","技能小册",[12,13],"nestjs","demo","2022-10-15",false,{"type":17,"value":18,"toc":1542},"minimark",[19,23,45,53,71,74,78,88,128,141,152,481,492,495,499,511,523,543,550,642,647,656,659,670,673,685,692,707,713,716,726,890,893,896,1121,1124,1131,1241,1244,1253,1442,1445,1459,1474,1477,1480,1483,1538],[20,21,8],"h1",{"id":22},"入手demo",[24,25,26],"blockquote",{},[27,28,29,33,34,39,40,44],"p",{},[30,31,32],"strong",{},"归档","：请优先阅读 ",[35,36,38],"a",{"href":37},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnestjs","NestJS 导读"," 与 ",[35,41,43],{"href":42},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnestjs\u002Fnew\u002Fbase","new\u002F 主线","。",[27,46,47,48,52],{},"简单了解一些",[49,50,51],"code",{},"Nest","，结合之前我开发的一个小工具日志上报插件，做一个小应用;",[27,54,55,56,59,60,63,64,67,68,70],{},"这个应用是什么? 有这么一个场景，我在",[49,57,58],{},"web","页面使用了",[49,61,62],{},"日志上报插件","，但是插件的",[49,65,66],{},"dsn","地址是没有的，这个地址需要后端的一个接口地址，那我们用",[49,69,51],{},"模式一下这个接口地址；",[27,72,73],{},"接下来，实践一下：",[75,76,77],"h2",{"id":77},"初始化项目",[27,79,80,81,87],{},"首先，去",[35,82,86],{"href":83,"rel":84},"https:\u002F\u002Fdocs.nestjs.com\u002F",[85],"nofollow","官网","找一下安装命令",[89,90,94],"pre",{"className":91,"code":92,"language":93,"meta":9,"style":9},"language-shell shiki shiki-themes material-theme-lighter github-light github-dark","npm i -g @nestjs\u002Fcli\nnest new project-name\n","shell",[49,95,96,116],{"__ignoreMap":9},[97,98,101,105,109,113],"span",{"class":99,"line":100},"line",1,[97,102,104],{"class":103},"sbgvK","npm",[97,106,108],{"class":107},"s_sjI"," i",[97,110,112],{"class":111},"stzsN"," -g",[97,114,115],{"class":107}," @nestjs\u002Fcli\n",[97,117,119,122,125],{"class":99,"line":118},2,[97,120,121],{"class":103},"nest",[97,123,124],{"class":107}," new",[97,126,127],{"class":107}," project-name\n",[27,129,130,131,134,135,140],{},"安装成功之后，所有的代码都是",[49,132,133],{},"ts","编写的; 关于项目的目录结构，可以参考",[35,136,139],{"href":137,"rel":138},"https:\u002F\u002Fdocs.nestjs.com\u002Ffirst-steps",[85],"官方文档","有具体说明;",[27,142,143,144,147,148,151],{},"我们找到入口文件：",[49,145,146],{},"main.ts",", 其中",[49,149,150],{},"bootstrap()","就是启动函数了；",[89,153,156],{"className":154,"code":155,"language":133,"meta":9,"style":9},"language-ts shiki shiki-themes material-theme-lighter github-light github-dark","async function bootstrap() {\n  \u002F\u002F 这里使用的是Express, 可以使用Fastify\n  const app = await NestFactory.create\u003CNestExpressApplication>(AppModule, {\n    \u002F\u002F 如果上报方式使用sendBeacon， 那么就需要对请求头设置相关参数\n    \u002F\u002F 如果上报方式使用fetch, 那么就不需要设置相关参数\n    rawBody: true,\n  });\n  \u002F\u002F 根据请求的Content-Type来解析请求体, 如果是 sendBeacon 那么需要设置相关参数\n  app.useBodyParser(\"text\");\n\n  \u002F\u002F 设置跨域\n  app.enableCors({\n    origin: \"*\",\n    credentials: true,\n    methods: \"GET,HEAD,PUT,PATCH,POST,DELETE\",\n    preflightContinue: false,\n    optionsSuccessStatus: 204,\n  });\n\n  \u002F\u002F 设置前缀, 可以设置也可以不设置 这里不设置\n  \u002F\u002F app.setGlobalPrefix(\"\u002Fapi\u002Fv1\");\n\n  await app.listen(3000);\n}\n\nbootstrap();\n",[49,157,158,178,184,233,239,245,261,273,279,305,312,318,333,351,363,380,393,407,416,421,427,433,438,460,466,471],{"__ignoreMap":9},[97,159,160,164,167,171,175],{"class":99,"line":100},[97,161,163],{"class":162},"sbsja","async",[97,165,166],{"class":162}," function",[97,168,170],{"class":169},"sGLFI"," bootstrap",[97,172,174],{"class":173},"sP7_E","()",[97,176,177],{"class":173}," {\n",[97,179,180],{"class":99,"line":118},[97,181,183],{"class":182},"sutJx","  \u002F\u002F 这里使用的是Express, 可以使用Fastify\n",[97,185,187,190,194,198,202,206,209,212,215,218,221,225,228,231],{"class":99,"line":186},3,[97,188,189],{"class":162},"  const",[97,191,193],{"class":192},"s_hVV"," app",[97,195,197],{"class":196},"smGrS"," =",[97,199,201],{"class":200},"sVHd0"," await",[97,203,205],{"class":204},"su5hD"," NestFactory",[97,207,208],{"class":173},".",[97,210,211],{"class":169},"create",[97,213,214],{"class":173},"\u003C",[97,216,217],{"class":103},"NestExpressApplication",[97,219,220],{"class":173},">",[97,222,224],{"class":223},"skxfh","(",[97,226,227],{"class":204},"AppModule",[97,229,230],{"class":173},",",[97,232,177],{"class":173},[97,234,236],{"class":99,"line":235},4,[97,237,238],{"class":182},"    \u002F\u002F 如果上报方式使用sendBeacon， 那么就需要对请求头设置相关参数\n",[97,240,242],{"class":99,"line":241},5,[97,243,244],{"class":182},"    \u002F\u002F 如果上报方式使用fetch, 那么就不需要设置相关参数\n",[97,246,248,251,254,258],{"class":99,"line":247},6,[97,249,250],{"class":223},"    rawBody",[97,252,253],{"class":173},":",[97,255,257],{"class":256},"syTEX"," true",[97,259,260],{"class":173},",\n",[97,262,264,267,270],{"class":99,"line":263},7,[97,265,266],{"class":173},"  }",[97,268,269],{"class":223},")",[97,271,272],{"class":173},";\n",[97,274,276],{"class":99,"line":275},8,[97,277,278],{"class":182},"  \u002F\u002F 根据请求的Content-Type来解析请求体, 如果是 sendBeacon 那么需要设置相关参数\n",[97,280,282,285,287,290,292,296,299,301,303],{"class":99,"line":281},9,[97,283,284],{"class":204},"  app",[97,286,208],{"class":173},[97,288,289],{"class":169},"useBodyParser",[97,291,224],{"class":223},[97,293,295],{"class":294},"sjJ54","\"",[97,297,298],{"class":107},"text",[97,300,295],{"class":294},[97,302,269],{"class":223},[97,304,272],{"class":173},[97,306,308],{"class":99,"line":307},10,[97,309,311],{"emptyLinePlaceholder":310},true,"\n",[97,313,315],{"class":99,"line":314},11,[97,316,317],{"class":182},"  \u002F\u002F 设置跨域\n",[97,319,321,323,325,328,330],{"class":99,"line":320},12,[97,322,284],{"class":204},[97,324,208],{"class":173},[97,326,327],{"class":169},"enableCors",[97,329,224],{"class":223},[97,331,332],{"class":173},"{\n",[97,334,336,339,341,344,347,349],{"class":99,"line":335},13,[97,337,338],{"class":223},"    origin",[97,340,253],{"class":173},[97,342,343],{"class":294}," \"",[97,345,346],{"class":107},"*",[97,348,295],{"class":294},[97,350,260],{"class":173},[97,352,354,357,359,361],{"class":99,"line":353},14,[97,355,356],{"class":223},"    credentials",[97,358,253],{"class":173},[97,360,257],{"class":256},[97,362,260],{"class":173},[97,364,366,369,371,373,376,378],{"class":99,"line":365},15,[97,367,368],{"class":223},"    methods",[97,370,253],{"class":173},[97,372,343],{"class":294},[97,374,375],{"class":107},"GET,HEAD,PUT,PATCH,POST,DELETE",[97,377,295],{"class":294},[97,379,260],{"class":173},[97,381,383,386,388,391],{"class":99,"line":382},16,[97,384,385],{"class":223},"    preflightContinue",[97,387,253],{"class":173},[97,389,390],{"class":256}," false",[97,392,260],{"class":173},[97,394,396,399,401,405],{"class":99,"line":395},17,[97,397,398],{"class":223},"    optionsSuccessStatus",[97,400,253],{"class":173},[97,402,404],{"class":403},"srdBf"," 204",[97,406,260],{"class":173},[97,408,410,412,414],{"class":99,"line":409},18,[97,411,266],{"class":173},[97,413,269],{"class":223},[97,415,272],{"class":173},[97,417,419],{"class":99,"line":418},19,[97,420,311],{"emptyLinePlaceholder":310},[97,422,424],{"class":99,"line":423},20,[97,425,426],{"class":182},"  \u002F\u002F 设置前缀, 可以设置也可以不设置 这里不设置\n",[97,428,430],{"class":99,"line":429},21,[97,431,432],{"class":182},"  \u002F\u002F app.setGlobalPrefix(\"\u002Fapi\u002Fv1\");\n",[97,434,436],{"class":99,"line":435},22,[97,437,311],{"emptyLinePlaceholder":310},[97,439,441,444,446,448,451,453,456,458],{"class":99,"line":440},23,[97,442,443],{"class":200},"  await",[97,445,193],{"class":204},[97,447,208],{"class":173},[97,449,450],{"class":169},"listen",[97,452,224],{"class":223},[97,454,455],{"class":403},"3000",[97,457,269],{"class":223},[97,459,272],{"class":173},[97,461,463],{"class":99,"line":462},24,[97,464,465],{"class":173},"}\n",[97,467,469],{"class":99,"line":468},25,[97,470,311],{"emptyLinePlaceholder":310},[97,472,474,477,479],{"class":99,"line":473},26,[97,475,476],{"class":169},"bootstrap",[97,478,174],{"class":204},[97,480,272],{"class":173},[27,482,483,484,487,488,491],{},"修改之后，执行命令",[49,485,486],{},"npm run start","就可以了，不过这里可以使用",[49,489,490],{},"npm run start:dev",",只有文件变动了服务就会重新启动；就不需要每次修改之后在重启；",[75,493,494],{"id":494},"实现添加功能",[496,497,498],"h3",{"id":498},"数据库",[27,500,501,502,505,506],{},"添加数据肯定需要数据库哇，那我们先添加下载数据库插件，我这里使用的",[49,503,504],{},"Mongoose,mongodb","； 具体可查看",[35,507,510],{"href":508,"rel":509},"https:\u002F\u002Fdocs.nestjs.com\u002Ftechniques\u002Fmongodb",[85],"Nest Mongo",[27,512,513,514,517,518],{},"关于本地如何安装",[49,515,516],{},"mongodb","以及如何使用，可查看基础文档",[35,519,522],{"href":520,"rel":521},"https:\u002F\u002Fwww.runoob.com\u002Fmongodb\u002Fmongodb-tutorial.html",[85],"MongoDb 教程",[89,524,526],{"className":91,"code":525,"language":93,"meta":9,"style":9},"npm i --save @nestjs\u002Fmongoose mongoose\n",[49,527,528],{"__ignoreMap":9},[97,529,530,532,534,537,540],{"class":99,"line":100},[97,531,104],{"class":103},[97,533,108],{"class":107},[97,535,536],{"class":111}," --save",[97,538,539],{"class":107}," @nestjs\u002Fmongoose",[97,541,542],{"class":107}," mongoose\n",[27,544,545,546,549],{},"然后在",[49,547,548],{},"app.module.ts","中添加配置",[89,551,553],{"className":154,"code":552,"language":133,"meta":9,"style":9},"import { MongooseModule } from '@nestjs\u002Fmongoose';\n@Module({\n  imports: [\n    \u002F\u002F 只需要在 imports 加入这一行即可;\n    MongooseModule.forRoot('mongodb:\u002F\u002Flocalhost\u002Fnest'),\n  ]\n}\n",[49,554,555,583,595,605,610,633,638],{"__ignoreMap":9},[97,556,557,560,563,566,569,572,575,578,581],{"class":99,"line":100},[97,558,559],{"class":200},"import",[97,561,562],{"class":173}," {",[97,564,565],{"class":204}," MongooseModule",[97,567,568],{"class":173}," }",[97,570,571],{"class":200}," from",[97,573,574],{"class":294}," '",[97,576,577],{"class":107},"@nestjs\u002Fmongoose",[97,579,580],{"class":294},"'",[97,582,272],{"class":173},[97,584,585,588,591,593],{"class":99,"line":118},[97,586,587],{"class":173},"@",[97,589,590],{"class":169},"Module",[97,592,224],{"class":204},[97,594,332],{"class":173},[97,596,597,600,602],{"class":99,"line":186},[97,598,599],{"class":223},"  imports",[97,601,253],{"class":173},[97,603,604],{"class":204}," [\n",[97,606,607],{"class":99,"line":235},[97,608,609],{"class":182},"    \u002F\u002F 只需要在 imports 加入这一行即可;\n",[97,611,612,615,617,620,622,624,627,629,631],{"class":99,"line":241},[97,613,614],{"class":204},"    MongooseModule",[97,616,208],{"class":173},[97,618,619],{"class":169},"forRoot",[97,621,224],{"class":204},[97,623,580],{"class":294},[97,625,626],{"class":107},"mongodb:\u002F\u002Flocalhost\u002Fnest",[97,628,580],{"class":294},[97,630,269],{"class":204},[97,632,260],{"class":173},[97,634,635],{"class":99,"line":247},[97,636,637],{"class":204},"  ]\n",[97,639,640],{"class":99,"line":263},[97,641,465],{"class":173},[27,643,644],{},[30,645,646],{},"保存之后重新启动，若日志显示一直重连，通常是本机未启动 MongoDB 服务，或连接串（主机、端口、库名）不正确。",[24,648,649],{},[27,650,651,652,655],{},"Mongoose 是 ODM 库；需单独安装并运行 ",[30,653,654],{},"MongoDB 服务","，与「安装 mongoose npm 包」不是同一回事。",[496,657,658],{"id":658},"添加一个日志模块",[27,660,661,662,665,666,669],{},"要想添加一个日志模块，你可以手动在",[49,663,664],{},"src","目录下添加目录为",[49,667,668],{},"logs","的文件夹，在文件夹下添加对应的文件；",[27,671,672],{},"不过我不建议你手动添加，不仅麻烦，而且也不好管理；",[27,674,675,676,678,679,681,682,684],{},"可以通过命令",[49,677,121],{}," 去添加；想要知道命令有哪些，可以在",[49,680,93],{},"工具中输入",[49,683,121],{},"然后回车；",[27,686,687,688,691],{},"然后使用命令",[49,689,690],{},"nest g name dirFile",";",[27,693,694,695,698,699,702,703,706],{},"我们直接使用",[49,696,697],{},"nest g resource logs",", 回车选择对应的",[49,700,701],{},"Api模式",", 之后就会生成一个完整模块的目录了；使用命令添加还会自动在",[49,704,705],{},"app.modules.ts","添加对应的模块哦~",[27,708,709,710,712],{},"创建完之后，就可以在",[49,711,664],{},"目录下找到你的文件夹或者文件了",[496,714,715],{"id":715},"创建一个控制器",[27,717,718,719,722,723,725],{},"在",[49,720,721],{},"logs.controller.ts","中添加一个方法，用来添加",[49,724,668],{},"数据",[89,727,729],{"className":154,"code":728,"language":133,"meta":9,"style":9},"\u002F\u002F 请求的前缀：https:\u002F\u002Fxxx.com\u002Flogs\n@Controller(\"logs\")\nexport class LogsController {\n  \u002F\u002F 这里的LogsService就是服务层文件 logs.service.ts中的类\n  constructor(private readonly logsService: LogsService) {}\n  \u002F\u002F https:\u002F\u002Fxxx.com\u002Flogs\u002FsetLog\n  @Post(\"setLog\")\n  \u002F\u002F createLogDto 就是前端给后端的字段\n  create(@Body() createLogDto: CreateLogDto) {\n    return this.logsService.create(createLogDto);\n  }\n}\n",[49,730,731,736,754,767,772,799,804,823,828,855,881,886],{"__ignoreMap":9},[97,732,733],{"class":99,"line":100},[97,734,735],{"class":182},"\u002F\u002F 请求的前缀：https:\u002F\u002Fxxx.com\u002Flogs\n",[97,737,738,740,743,745,747,749,751],{"class":99,"line":118},[97,739,587],{"class":173},[97,741,742],{"class":169},"Controller",[97,744,224],{"class":204},[97,746,295],{"class":294},[97,748,668],{"class":107},[97,750,295],{"class":294},[97,752,753],{"class":204},")\n",[97,755,756,759,762,765],{"class":99,"line":186},[97,757,758],{"class":200},"export",[97,760,761],{"class":162}," class",[97,763,764],{"class":103}," LogsController",[97,766,177],{"class":173},[97,768,769],{"class":99,"line":235},[97,770,771],{"class":182},"  \u002F\u002F 这里的LogsService就是服务层文件 logs.service.ts中的类\n",[97,773,774,777,779,782,785,789,791,794,796],{"class":99,"line":241},[97,775,776],{"class":162},"  constructor",[97,778,224],{"class":173},[97,780,781],{"class":162},"private",[97,783,784],{"class":162}," readonly",[97,786,788],{"class":787},"s99_P"," logsService",[97,790,253],{"class":196},[97,792,793],{"class":103}," LogsService",[97,795,269],{"class":173},[97,797,798],{"class":173}," {}\n",[97,800,801],{"class":99,"line":247},[97,802,803],{"class":182},"  \u002F\u002F https:\u002F\u002Fxxx.com\u002Flogs\u002FsetLog\n",[97,805,806,809,812,814,816,819,821],{"class":99,"line":263},[97,807,808],{"class":173},"  @",[97,810,811],{"class":169},"Post",[97,813,224],{"class":204},[97,815,295],{"class":294},[97,817,818],{"class":107},"setLog",[97,820,295],{"class":294},[97,822,753],{"class":204},[97,824,825],{"class":99,"line":275},[97,826,827],{"class":182},"  \u002F\u002F createLogDto 就是前端给后端的字段\n",[97,829,830,834,837,840,843,846,848,851,853],{"class":99,"line":281},[97,831,833],{"class":832},"sVXei","  create",[97,835,836],{"class":173},"(@",[97,838,839],{"class":169},"Body",[97,841,842],{"class":204},"() ",[97,844,845],{"class":787},"createLogDto",[97,847,253],{"class":196},[97,849,850],{"class":103}," CreateLogDto",[97,852,269],{"class":173},[97,854,177],{"class":173},[97,856,857,860,864,866,869,871,873,875,877,879],{"class":99,"line":307},[97,858,859],{"class":200},"    return",[97,861,863],{"class":862},"s39Yj"," this",[97,865,208],{"class":173},[97,867,868],{"class":204},"logsService",[97,870,208],{"class":173},[97,872,211],{"class":169},[97,874,224],{"class":223},[97,876,845],{"class":204},[97,878,269],{"class":223},[97,880,272],{"class":173},[97,882,883],{"class":99,"line":314},[97,884,885],{"class":173},"  }\n",[97,887,888],{"class":99,"line":320},[97,889,465],{"class":173},[27,891,892],{},"接着我们添加数据库需要的字段以及数据表;",[496,894,895],{"id":895},"添加数据表以及对应表结构",[89,897,899],{"className":154,"code":898,"language":133,"meta":9,"style":9},"import { Prop, Schema, SchemaFactory } from \"@nestjs\u002Fmongoose\";\nimport { HydratedDocument } from \"mongoose\";\n\nexport type LogDocument = HydratedDocument\u003CLog>;\n\n@Schema()\nexport class Log {\n  @Prop()\n  name: string;\n  @Prop()\n  url: string;\n  @Prop()\n  \u002F\u002F 创建时间\n  createdAt: Date;\n  \u002F\u002F 更新时间\n  updatedAt: Date;\n  \u002F\u002F ...\n}\nexport const LogSchema = SchemaFactory.createForClass(Log);\n",[49,900,901,932,954,958,980,984,994,1005,1014,1028,1036,1047,1055,1060,1072,1077,1088,1093,1097],{"__ignoreMap":9},[97,902,903,905,907,910,912,915,917,920,922,924,926,928,930],{"class":99,"line":100},[97,904,559],{"class":200},[97,906,562],{"class":173},[97,908,909],{"class":204}," Prop",[97,911,230],{"class":173},[97,913,914],{"class":204}," Schema",[97,916,230],{"class":173},[97,918,919],{"class":204}," SchemaFactory",[97,921,568],{"class":173},[97,923,571],{"class":200},[97,925,343],{"class":294},[97,927,577],{"class":107},[97,929,295],{"class":294},[97,931,272],{"class":173},[97,933,934,936,938,941,943,945,947,950,952],{"class":99,"line":118},[97,935,559],{"class":200},[97,937,562],{"class":173},[97,939,940],{"class":204}," HydratedDocument",[97,942,568],{"class":173},[97,944,571],{"class":200},[97,946,343],{"class":294},[97,948,949],{"class":107},"mongoose",[97,951,295],{"class":294},[97,953,272],{"class":173},[97,955,956],{"class":99,"line":186},[97,957,311],{"emptyLinePlaceholder":310},[97,959,960,962,965,968,970,972,974,977],{"class":99,"line":235},[97,961,758],{"class":200},[97,963,964],{"class":162}," type",[97,966,967],{"class":103}," LogDocument",[97,969,197],{"class":196},[97,971,940],{"class":103},[97,973,214],{"class":173},[97,975,976],{"class":103},"Log",[97,978,979],{"class":173},">;\n",[97,981,982],{"class":99,"line":241},[97,983,311],{"emptyLinePlaceholder":310},[97,985,986,988,991],{"class":99,"line":247},[97,987,587],{"class":173},[97,989,990],{"class":169},"Schema",[97,992,993],{"class":204},"()\n",[97,995,996,998,1000,1003],{"class":99,"line":263},[97,997,758],{"class":200},[97,999,761],{"class":162},[97,1001,1002],{"class":103}," Log",[97,1004,177],{"class":173},[97,1006,1007,1009,1012],{"class":99,"line":275},[97,1008,808],{"class":173},[97,1010,1011],{"class":169},"Prop",[97,1013,993],{"class":204},[97,1015,1016,1020,1022,1026],{"class":99,"line":281},[97,1017,1019],{"class":1018},"sucvu","  name",[97,1021,253],{"class":196},[97,1023,1025],{"class":1024},"sZMiF"," string",[97,1027,272],{"class":173},[97,1029,1030,1032,1034],{"class":99,"line":307},[97,1031,808],{"class":173},[97,1033,1011],{"class":169},[97,1035,993],{"class":204},[97,1037,1038,1041,1043,1045],{"class":99,"line":314},[97,1039,1040],{"class":1018},"  url",[97,1042,253],{"class":196},[97,1044,1025],{"class":1024},[97,1046,272],{"class":173},[97,1048,1049,1051,1053],{"class":99,"line":320},[97,1050,808],{"class":173},[97,1052,1011],{"class":169},[97,1054,993],{"class":204},[97,1056,1057],{"class":99,"line":335},[97,1058,1059],{"class":182},"  \u002F\u002F 创建时间\n",[97,1061,1062,1065,1067,1070],{"class":99,"line":353},[97,1063,1064],{"class":1018},"  createdAt",[97,1066,253],{"class":196},[97,1068,1069],{"class":103}," Date",[97,1071,272],{"class":173},[97,1073,1074],{"class":99,"line":365},[97,1075,1076],{"class":182},"  \u002F\u002F 更新时间\n",[97,1078,1079,1082,1084,1086],{"class":99,"line":382},[97,1080,1081],{"class":1018},"  updatedAt",[97,1083,253],{"class":196},[97,1085,1069],{"class":103},[97,1087,272],{"class":173},[97,1089,1090],{"class":99,"line":395},[97,1091,1092],{"class":182},"  \u002F\u002F ...\n",[97,1094,1095],{"class":99,"line":409},[97,1096,465],{"class":173},[97,1098,1099,1101,1104,1107,1109,1111,1113,1116,1119],{"class":99,"line":418},[97,1100,758],{"class":200},[97,1102,1103],{"class":162}," const",[97,1105,1106],{"class":192}," LogSchema",[97,1108,197],{"class":196},[97,1110,919],{"class":204},[97,1112,208],{"class":173},[97,1114,1115],{"class":169},"createForClass",[97,1117,1118],{"class":204},"(Log)",[97,1120,272],{"class":173},[27,1122,1123],{},"大概的数据表结构就定好了；",[27,1125,1126,1127,1130],{},"我们在",[49,1128,1129],{},"logs.module.ts","引入我们创建的表",[89,1132,1134],{"className":154,"code":1133,"language":133,"meta":9,"style":9},"\u002F\u002F 这个是你实际创建数据表的地址， LogSchema就是你导出的表\nimport { LogSchema } from \".\u002Fschemas\u002Flog.schema\";\n@Module({\n  imports: [\n    MongooseModule.forFeature([\n      {\n        name: \"Log\",\n        schema: LogSchema,\n      }\n    ])\n  ]\n}\n",[49,1135,1136,1141,1162,1172,1180,1192,1197,1212,1223,1228,1233,1237],{"__ignoreMap":9},[97,1137,1138],{"class":99,"line":100},[97,1139,1140],{"class":182},"\u002F\u002F 这个是你实际创建数据表的地址， LogSchema就是你导出的表\n",[97,1142,1143,1145,1147,1149,1151,1153,1155,1158,1160],{"class":99,"line":118},[97,1144,559],{"class":200},[97,1146,562],{"class":173},[97,1148,1106],{"class":204},[97,1150,568],{"class":173},[97,1152,571],{"class":200},[97,1154,343],{"class":294},[97,1156,1157],{"class":107},".\u002Fschemas\u002Flog.schema",[97,1159,295],{"class":294},[97,1161,272],{"class":173},[97,1163,1164,1166,1168,1170],{"class":99,"line":186},[97,1165,587],{"class":173},[97,1167,590],{"class":169},[97,1169,224],{"class":204},[97,1171,332],{"class":173},[97,1173,1174,1176,1178],{"class":99,"line":235},[97,1175,599],{"class":223},[97,1177,253],{"class":173},[97,1179,604],{"class":204},[97,1181,1182,1184,1186,1189],{"class":99,"line":241},[97,1183,614],{"class":204},[97,1185,208],{"class":173},[97,1187,1188],{"class":169},"forFeature",[97,1190,1191],{"class":204},"([\n",[97,1193,1194],{"class":99,"line":247},[97,1195,1196],{"class":173},"      {\n",[97,1198,1199,1202,1204,1206,1208,1210],{"class":99,"line":263},[97,1200,1201],{"class":223},"        name",[97,1203,253],{"class":173},[97,1205,343],{"class":294},[97,1207,976],{"class":107},[97,1209,295],{"class":294},[97,1211,260],{"class":173},[97,1213,1214,1217,1219,1221],{"class":99,"line":275},[97,1215,1216],{"class":223},"        schema",[97,1218,253],{"class":173},[97,1220,1106],{"class":204},[97,1222,260],{"class":173},[97,1224,1225],{"class":99,"line":281},[97,1226,1227],{"class":173},"      }\n",[97,1229,1230],{"class":99,"line":307},[97,1231,1232],{"class":204},"    ])\n",[97,1234,1235],{"class":99,"line":314},[97,1236,637],{"class":204},[97,1238,1239],{"class":99,"line":320},[97,1240,465],{"class":173},[496,1242,1243],{"id":1243},"添加服务层",[27,1245,718,1246,1249,1250,1252],{},[49,1247,1248],{},"logs.service.ts","中添加一个",[49,1251,211],{},"方法",[89,1254,1256],{"className":154,"code":1255,"language":133,"meta":9,"style":9},"interface CreateLogDto {\n  name: string;\n  url: string;\n}\n\n@Injectable()\nexport class LogsService {\n  constructor(\n    \u002F\u002F 这里是用到了数据库 这里的 @InjectModel(\"Log\") Log要个上面的 MongooseModule.forFeature 中的name保持一致;\n    \u002F\u002F  Model\u003CLog> 中Log就是你到处的表结构 class Log{}\n    @InjectModel(\"Log\") private readonly logModel: Model\u003CLog>,\n  ) {}\n\n  \u002F\u002F 这个方法就是 logs.controller.ts 中使用的 this.logsService.create\n  \u002F\u002F CreateLogDto 这个是为了检验参数的， 也就是接口 interface 你自己可以自定义\n  create(createLogDto: CreateLogDto) {\n    \u002F\u002F 这里使用 Model\u003CLog> 的 create 方法，具体mongodb如何自行百度\n    return this.logModel.create(createLogDto);\n  }\n}\n",[49,1257,1258,1267,1277,1287,1291,1295,1304,1314,1321,1326,1331,1369,1376,1380,1385,1390,1406,1411,1434,1438],{"__ignoreMap":9},[97,1259,1260,1263,1265],{"class":99,"line":100},[97,1261,1262],{"class":162},"interface",[97,1264,850],{"class":103},[97,1266,177],{"class":173},[97,1268,1269,1271,1273,1275],{"class":99,"line":118},[97,1270,1019],{"class":1018},[97,1272,253],{"class":196},[97,1274,1025],{"class":1024},[97,1276,272],{"class":173},[97,1278,1279,1281,1283,1285],{"class":99,"line":186},[97,1280,1040],{"class":1018},[97,1282,253],{"class":196},[97,1284,1025],{"class":1024},[97,1286,272],{"class":173},[97,1288,1289],{"class":99,"line":235},[97,1290,465],{"class":173},[97,1292,1293],{"class":99,"line":241},[97,1294,311],{"emptyLinePlaceholder":310},[97,1296,1297,1299,1302],{"class":99,"line":247},[97,1298,587],{"class":173},[97,1300,1301],{"class":169},"Injectable",[97,1303,993],{"class":204},[97,1305,1306,1308,1310,1312],{"class":99,"line":263},[97,1307,758],{"class":200},[97,1309,761],{"class":162},[97,1311,793],{"class":103},[97,1313,177],{"class":173},[97,1315,1316,1318],{"class":99,"line":275},[97,1317,776],{"class":162},[97,1319,1320],{"class":173},"(\n",[97,1322,1323],{"class":99,"line":281},[97,1324,1325],{"class":182},"    \u002F\u002F 这里是用到了数据库 这里的 @InjectModel(\"Log\") Log要个上面的 MongooseModule.forFeature 中的name保持一致;\n",[97,1327,1328],{"class":99,"line":307},[97,1329,1330],{"class":182},"    \u002F\u002F  Model\u003CLog> 中Log就是你到处的表结构 class Log{}\n",[97,1332,1333,1336,1339,1341,1343,1345,1347,1350,1352,1354,1357,1359,1362,1364,1366],{"class":99,"line":314},[97,1334,1335],{"class":173},"    @",[97,1337,1338],{"class":169},"InjectModel",[97,1340,224],{"class":204},[97,1342,295],{"class":294},[97,1344,976],{"class":107},[97,1346,295],{"class":294},[97,1348,1349],{"class":204},") ",[97,1351,781],{"class":162},[97,1353,784],{"class":162},[97,1355,1356],{"class":787}," logModel",[97,1358,253],{"class":196},[97,1360,1361],{"class":103}," Model",[97,1363,214],{"class":173},[97,1365,976],{"class":103},[97,1367,1368],{"class":173},">,\n",[97,1370,1371,1374],{"class":99,"line":320},[97,1372,1373],{"class":173},"  )",[97,1375,798],{"class":173},[97,1377,1378],{"class":99,"line":335},[97,1379,311],{"emptyLinePlaceholder":310},[97,1381,1382],{"class":99,"line":353},[97,1383,1384],{"class":182},"  \u002F\u002F 这个方法就是 logs.controller.ts 中使用的 this.logsService.create\n",[97,1386,1387],{"class":99,"line":365},[97,1388,1389],{"class":182},"  \u002F\u002F CreateLogDto 这个是为了检验参数的， 也就是接口 interface 你自己可以自定义\n",[97,1391,1392,1394,1396,1398,1400,1402,1404],{"class":99,"line":382},[97,1393,833],{"class":832},[97,1395,224],{"class":173},[97,1397,845],{"class":787},[97,1399,253],{"class":196},[97,1401,850],{"class":103},[97,1403,269],{"class":173},[97,1405,177],{"class":173},[97,1407,1408],{"class":99,"line":395},[97,1409,1410],{"class":182},"    \u002F\u002F 这里使用 Model\u003CLog> 的 create 方法，具体mongodb如何自行百度\n",[97,1412,1413,1415,1417,1419,1422,1424,1426,1428,1430,1432],{"class":99,"line":409},[97,1414,859],{"class":200},[97,1416,863],{"class":862},[97,1418,208],{"class":173},[97,1420,1421],{"class":204},"logModel",[97,1423,208],{"class":173},[97,1425,211],{"class":169},[97,1427,224],{"class":223},[97,1429,845],{"class":204},[97,1431,269],{"class":223},[97,1433,272],{"class":173},[97,1435,1436],{"class":99,"line":418},[97,1437,885],{"class":173},[97,1439,1440],{"class":99,"line":423},[97,1441,465],{"class":173},[75,1443,1444],{"id":1444},"使用",[27,1446,1447,1448,1451,1452,1451,1455,1458],{},"可以使用",[49,1449,1450],{},"postman","或者",[49,1453,1454],{},"apipost",[49,1456,1457],{},"apifox","测试； 具体工具如何使用，自行百度官网;",[27,1460,1461,1462,1465,1466,1469,1470,1473],{},"添加一个",[49,1463,1464],{},"post","接口，接口地址就是",[49,1467,1468],{},"localhost:3000\u002Flogs\u002FsetLog",", 参数就是上面自定义的接口",[49,1471,1472],{},"interface CreateLogDto","， 然后点击发送就可以了;",[27,1475,1476],{},"那么一个小应用就基本完成了。",[75,1478,1479],{"id":1479},"参考文献",[27,1481,1482],{},"以下链接在编写时均可正常访问：",[1484,1485,1486,1499],"table",{},[1487,1488,1489],"thead",{},[1490,1491,1492,1496],"tr",{},[1493,1494,1495],"th",{},"资料",[1493,1497,1498],{},"说明",[1500,1501,1502,1514,1526],"tbody",{},[1490,1503,1504,1511],{},[1505,1506,1507],"td",{},[35,1508,1510],{"href":137,"rel":1509},[85],"NestJS · First steps",[1505,1512,1513],{},"CLI 与目录结构",[1490,1515,1516,1522],{},[1505,1517,1518],{},[35,1519,1521],{"href":508,"rel":1520},[85],"NestJS · MongoDB",[1505,1523,1524],{},[49,1525,577],{},[1490,1527,1528,1535],{},[1505,1529,1530],{},[35,1531,1534],{"href":1532,"rel":1533},"https:\u002F\u002Fwww.mongodb.com\u002Fdocs\u002Fmanual\u002Finstallation\u002F",[85],"MongoDB 安装",[1505,1536,1537],{},"官方安装说明",[1539,1540,1541],"style",{},"html pre.shiki code .sbgvK, html code.shiki .sbgvK{--shiki-light:#E2931D;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .s_sjI, html code.shiki .s_sjI{--shiki-light:#91B859;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .stzsN, html code.shiki .stzsN{--shiki-light:#91B859;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sbsja, html code.shiki .sbsja{--shiki-light:#9C3EDA;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sGLFI, html code.shiki .sGLFI{--shiki-light:#6182B8;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sP7_E, html code.shiki .sP7_E{--shiki-light:#39ADB5;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sutJx, html code.shiki .sutJx{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit}html pre.shiki code .s_hVV, html code.shiki .s_hVV{--shiki-light:#90A4AE;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .smGrS, html code.shiki .smGrS{--shiki-light:#39ADB5;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sVHd0, html code.shiki .sVHd0{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit}html pre.shiki code .su5hD, html code.shiki .su5hD{--shiki-light:#90A4AE;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .skxfh, html code.shiki .skxfh{--shiki-light:#E53935;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .syTEX, html code.shiki .syTEX{--shiki-light:#FF5370;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sjJ54, html code.shiki .sjJ54{--shiki-light:#39ADB5;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .srdBf, html code.shiki .srdBf{--shiki-light:#F76D47;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .s99_P, html code.shiki .s99_P{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#FFAB70;--shiki-dark-font-style:inherit}html pre.shiki code .sVXei, html code.shiki .sVXei{--shiki-light:#E53935;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .s39Yj, html code.shiki .s39Yj{--shiki-light:#39ADB5;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sucvu, html code.shiki .sucvu{--shiki-light:#E53935;--shiki-default:#E36209;--shiki-dark:#FFAB70}html pre.shiki code .sZMiF, html code.shiki .sZMiF{--shiki-light:#E2931D;--shiki-default:#005CC5;--shiki-dark:#79B8FF}",{"title":9,"searchDepth":118,"depth":118,"links":1543},[1544,1545,1552,1553],{"id":77,"depth":118,"text":77},{"id":494,"depth":118,"text":494,"children":1546},[1547,1548,1549,1550,1551],{"id":498,"depth":186,"text":498},{"id":658,"depth":186,"text":658},{"id":715,"depth":186,"text":715},{"id":895,"depth":186,"text":895},{"id":1243,"depth":186,"text":1243},{"id":1444,"depth":118,"text":1444},{"id":1479,"depth":118,"text":1479},{"title":8,"description":9},"knowledge\u002Fbooklet\u002Fend\u002FNestJS\u002Fbefore\u002Fdemo","knowledge\u002Fknowledge\u002Fbooklet\u002Fend\u002FNestJS\u002Fbefore\u002Fdemo.md","md",{"items":1559},[1560,1563,1566,1569,1573,1576],{"path":1561,"title":1562,"description":9,"category":10,"score":247},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnestjs\u002Fbefore\u002Fexce","异常处理器",{"path":1564,"title":1565,"description":9,"category":10,"score":247},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnestjs\u002Fbefore\u002Fenv","环境加载",{"path":1567,"title":1568,"description":9,"category":10,"score":247},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnestjs\u002Fbefore\u002Fdatabase","数据库的配置",{"path":1570,"title":1571,"description":1572,"category":10,"score":247},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnestjs\u002Fbefore\u002Finfo","归档说明（before\u002F）","本目录（before\u002F）为早期 NestJS 实战笔记：以完整业务片段（守卫、拦截器、MongoDB、JWT 等）为主，写法与文件命名不统一。新项目请跟 new\u002F 主线，技术细节以 docs.nestjs.com 为准。",{"path":1574,"title":1575,"description":9,"category":10,"score":247},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnestjs\u002Fbefore\u002Fitc","统一响应格式拦截器",{"path":1577,"title":1578,"description":9,"category":10,"score":247},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnestjs\u002Fbefore\u002Fnext","路由守卫",{"series":1580,"title":1581,"items":1582,"index":100,"prev":1612,"next":1613},"booklet\u002Fend\u002Fnestjs\u002Fbefore","before",[1583,1585,1586,1588,1590,1592,1596,1598,1602,1606,1608],{"path":1567,"title":1568,"date":1584,"pinned":15},"2024-06-22",{"path":7,"title":8,"date":14,"pinned":15},{"path":1564,"title":1565,"date":1587,"pinned":15},"2024-09-01",{"path":1561,"title":1562,"date":1589,"pinned":15},"2026-03-17",{"path":1570,"title":1571,"date":1591,"pinned":15},"2023-08-31",{"path":1593,"title":1594,"date":1595,"pinned":15},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnestjs\u002Fbefore\u002Finjectable","操作日志拦截器","2020-02-20",{"path":1574,"title":1575,"date":1597,"pinned":15},"2023-08-17",{"path":1599,"title":1600,"date":1601,"pinned":15},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnestjs\u002Fbefore\u002Fjwt","JWT 与 Passport 授权","2021-08-10",{"path":1603,"title":1604,"date":1605,"pinned":15},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnestjs\u002Fbefore\u002Fmi","Nest 中间件","2022-06-21",{"path":1577,"title":1578,"date":1607,"pinned":15},"2022-12-01",{"path":1609,"title":1610,"date":1611,"pinned":15},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnestjs\u002Fbefore\u002Fother","其他配置","2022-05-23",{"path":1567,"title":1568,"date":1584,"pinned":15},{"path":1564,"title":1565,"date":1587,"pinned":15}]