序文
遊ぼう、騒ぎましょう、からかわないでください!Node サービスを C 側のサービスとして使用することはお勧めできません。結局のところ、これはメカニズムです。この機能は、Java >>>[スクリプト] という言語設計の最初からその使命を決定します。ここでは説明しません。JavaScript の歴史を見ればわかります。これにより、「いいね!」ができないことも決まります。言語を終了すると、少量のユーザーの訪問には耐えられますが、多数の同時訪問に耐えられるようになると、素晴らしいものになるでしょう~C端
单线程多任务
Javascript
多线程多任务
では、なぜ依然として Node サービスを作成する必要があるのでしょうか? その主な理由は、利便性と迅速性であり、小規模プロジェクトの場合、構築が早く完了し、開発コストが小さいことです。次に、主に書くことによって次のような利点が得られます。Nest
- デコレータ構文を学び、そのシンプルさと美しさを感じてください。
- 新しい開発フレームワークを自ら学び、さまざまなフレームワークの長所と短所を感じ、今後の開発と選択の基礎を築きます。
- サーバー側のトラブルシューティングの複雑さを感じて、フロントエンド設計のインスピレーションを見つけてください。
この記事では主に NestJs + Sequelize + MySQL を使用して基本操作を完了します。Node サーバーの基本構造を示します。Java SpringBoot プロジェクトの基本構造も見ることができます。これらは非常によく似ています。信じられないでしょう、サーバー開発について聞いてください。クラスメート。
良い習慣をつけましょう。記事を読むときは読む前に3回クリックしてください~[いいね、フォロー、リツイート]、コメントを読んだ後にコメントすることができます~改善を続けて穴を埋めてください~
最初のステップはプロジェクトを開始することです
サーバーを選択する際は、以前Egg.jsを使用したことがありますので、今回は選択しません。次に、Egg も Koa の開発基盤を継承しており、Express も Koa をベースにした革新的なものであり、両者は似ているはずなので、Koa と Express を選択しません。
したがって、構文が Java と同じであることを確認するために Nest.js を試してみたいと思います。さらに、以前に Java + SpringBoot プロジェクトを開発したことがあります。もちろん、古い SSH 2.0 も最初から構築しました。 Spring2.0 + Struts2 + Hibernate3.2 なら簡単に始められるはずだと思うので、振り返って書いてみます。
参考ドキュメント:
- https://www.geeksforgeeks.org/best-nodejs-frameworks-for-app-development/
- https://anywhere.epam.com/business/best-node-js-frameworks
私の考えを述べさせていただきますと、まず、まだ始めたばかりで、よくわからない落とし穴もたくさんあると思いますが、まずは簡単に説明して、後でさらに深めていきます。サーバーサイドも開発したいので、やりたいならもっとやって、みんなで楽しくやってみましょう。フロントエンドフレームワークとして、中間処理層として使用する予定です。従来の基盤となるデータベースを使用します。これは比較的安定しており、信頼性が高く、比較的馴染みのあるものです。ここでは新しいものは使用しません。結局のところ、データベースはすべての基礎です。Nest
Graphql
MySQL
具体的な実装手順について話しましょう。
MySQL
@nestjs/sequelize
增删改查
CRUD
Graphql
Swagger
middleware
redis
さらに最適化ポイントを追加することも歓迎です。一緒に話し合います~興味があれば、コードの追加を手伝ってください~
大まかな方向性を決めた後、整理を始めました。後から追加するだけで、基本機能の完成を優先する必要があります。Nest.js 公式 Web サイト: https://docs.nestjs.com/早速、詳細を見ていきましょう。
# 进入文件夹目录
cd full-stack-demo/packages
# 安装脚手架
npm i -g @nestjs/cli
# 创建基础项目
nest new node-server-demo
# 进入项目
cd new node-server-demo
# 运行项目测试
npm run start:dev
混乱しないように、不要なものをいくつか削除し、単純なものから始めて、次に複雑なものにしましょう。次に、このフレームワークの感触を得るために簡単な例を作成し、後で完全なコードを公開します。さっそく始めましょう! 調整後のディレクトリ構成:
common
config
controller
service
dto
entities
module
main.ts
types
デモを書いているだけなので、急げばコメントを書かなくても済みます 一目で理解できる気がします Java SpringBootの書き方と非常に一致しています コードの一部は表示:
- コントローラーコントローラー
// packages/node-server-demo/src/controller/user/index.ts
import { Controller, Get, Query } from '@nestjs/common';
import UserServices from '@/service/user';
import { GetUserDto, GetUserInfoDto } from '@/dto/user';
@Controller('user')
export class UserController {
constructor(private readonly userService: UserServices) {}
// Get 请求 user/name?name=bricechou
@Get('name')
async findByName(@Query() getUserDto: GetUserDto) {
return this.userService.read.findByName(getUserDto.name);
}
// Get 请求 user/info?id=123
@Get('info')
async findById(@Query() getUserInfoDto: GetUserInfoDto) {
const user = await this.userService.read.findById(getUserInfoDto.id);
return { gender: user.gender, job: user.job };
}
}
// packages/node-server-demo/src/controller/log/add.ts
import { Controller, Post, Body } from '@nestjs/common';
import { AddLogDto } from '@/dto/log';
import LogServices from '@/service/log';
@Controller('log')
export class CreateLogController {
constructor(private readonly logServices: LogServices) {}
// post('/log/add')
@Post('add')
create(@Body() createLogDto: AddLogDto) {
return this.logServices.create.create(createLogDto);
}
}
- データ転送データ転送オブジェクト
// packages/node-server-demo/src/dto/user.ts
export class CreateUserDto {
name: string;
age: number;
gender: string;
job: string;
}
// 可以分开写,也可以合并
export class GetUserDto {
id?: number;
name: string;
}
// 可以分开写,也可以合并
export class GetUserInfoDto {
id: number;
}
- サービスデータベース対話処理クラス
// packages/node-server-demo/src/service/user/read.ts
import { Injectable } from '@nestjs/common';
import { User } from '@/entities/User';
@Injectable()
export class ReadUserService {
constructor() {}
async findByName(name: string): Promise<User> {
// 可以处理判空,从数据库读取/写入数据,可能会被多个 controller 进行调用
console.info('ReadUserService findByName > ', name);
return Promise.resolve({ id: 1, name, job: '程序员', gender: 1, age: 18 });
}
async findById(id: number): Promise<User> {
console.info('ReadUserService findById > ', id);
return Promise.resolve({
id: 1,
name: 'BriceChou',
job: '程序员',
gender: 1,
age: 18,
});
}
}
- モジュールモジュール登録、サービスクラス/コントロールクラス
// packages/node-server-demo/src/module/user.ts
import { Module } from '@nestjs/common';
import UserService, { ReadUserService } from '@/service/user';
import { UserController } from '@/controller/user';
@Module({
providers: [UserService, ReadUserService],
controllers: [UserController],
})
export class UserModule {}
// packages/node-server-demo/src/module/index.ts 根模块注入
import { Module } from '@nestjs/common';
import { UserModule } from './user';
import { LogModule } from './log';
@Module({
imports: [
UserModule,
LogModule,
],
})
export class AppModule {}
- main.js は登録されているすべてのクラスを開始します
// packages/node-server-demo/src/main.ts
import { AppModule } from '@/module';
import { NestFactory } from '@nestjs/core';
import { NestExpressApplication } from '@nestjs/platform-express';
async function bootstrap() {
const app = await NestFactory.create<NestExpressApplication>(AppModule);
// 监听端口 3000
await app.listen(3000);
}
bootstrap();
このようにして、スタンドアロン サーバーが起動され、[ https://hoppscotch.io/ ] を使用してリクエストを作成し、リターンの効果を確認できます。Postwoman
コンソールもログを受信しました。これらのログ リクエストは後でファイルとして保存できるため、リクエスト ログも利用できるようになり、完璧です。次に、単一のマシンで泥んこをする必要がないように、データベースへの接続を開始します~.log
ステップ 2: MySQL を構成する
MySQL のインストールは実際には非常に簡単です。私のコンピュータは Mac なので、以下のスクリーンショットはすべて Mac に基づいています。まず、対応するデータベースをダウンロードします。
ダウンロード アドレス: https://dev.mysql.com/downloads/mysql/他のシステムについては、オンラインでチュートリアルを見つけることができますが、これはおそらく非常に一般的なものなので、チュートリアルは繰り返しません。
- 注:インストールされたデータベースのパスワードを設定する必要があります。また、データベースに接続するにはパスワードが必要です。そうしないと、データベース接続が失敗します。
- MySQL の場合はデータベースをインストールするだけなので、手順に慣れていればコマンドラインから直接操作することができます。
- 慣れていない場合は、グラフィカル管理ツールをダウンロードしてください。
PS: ワークベンチをインストールするときに、要件が上記であることがわかりました。私のコンピューターは です。MacOS 13
MacOS 12
ダウンロードは無駄なので、https://downloads.mysql.com/archives/workbench/のアーカイブからのみ下位バージョンを見つけることができます。データベース サービスにもバージョン要件があり、コンピュータのバージョンに応じてサポートされているバージョンを選択できます。。ここで私が選択したのは、デフォルトで最新バージョンです。それをダウンロードして直接インストールし、最後まで入力した root パスワードを覚えておいてください。!!8.0.31
https://downloads.mysql.com/archives/community/
8.0.34
Next
現在のデータベースが実行されているかどうかを確認し、Workbench を起動してステータスを確認します。
1.データベースの作成
データベースには文字セットの選択があります。さまざまな文字セットと検証ルールは保存されたデータに影響を与えるため、自分でクエリを実行し、独自のデータ保存原則に従って選択できます。私はデフォルトで最も幅広いものを選択しています。確認後、右下の「適用」ボタンを選択します。
回答の選択肢:
PRIMARY KEY
Not NULL
Unique
GENERATED
CREATE TABLE people (
first_name VARCHAR(100),
last_name VARCHAR(100),
full_name VARCHAR(200) AS (CONCAT(first_name, ' ', last_name))
);
UNSIGNED
この数値型は正の数 (ゼロを含む) のみを格納でき、負の数は格納できません。ZEROFILL
数値型フィールドの先頭をゼロで埋めると、フィールドが宣言された長さに達するまでフィールドが自動的に変更されます (例: 00007)。UNSIGNED
BINARY
バイナリ文字列の格納に使用されます。フィールドが BINARY(5) として宣言されている場合、このフィールドに格納されている文字列は長さ 5 のバイナリ文字列として処理されます。
- さらに、迅速な検索を容易にするためのインデックスを簡単に作成することもできます。
CREATE TABLE `rrweb`.`test_sys_req_log` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`content` TEXT NOT NULL,
`l_level` INT UNSIGNED NOT NULL,
`l_category` VARCHAR(255) NOT NULL,
`l_created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`l_updated_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE INDEX `id_UNIQUE` (`id` ASC) VISIBLE,
INDEX `table_index` (`l_level` ASC, `l_category` ASC, `l_time` ASC) VISIBLE);
現在、Apple Silicon アーキテクチャ用の公式プリコンパイル済みバイナリは存在しないためです。その結果、現在Mac x86 チップのみをサポートしているMac M1 チップでは、リンクされたデータベース操作を使用できません。ああ~、長い間苦労していろいろな書類を確認した結果、こんな落とし穴があったのですが、どうでもいいので、別の方法で開けましょう。node-oracledb
TypeORM
諦めてhttps://docs.nestjs.com/techniques/database#sequelize-integrationを選択するしかありませんでした。バンバンバン〜 虎のように激しい操作で、完了しました。
- インストール
Sequelize
# 安装连接库
npm install --save @nestjs/sequelize sequelize sequelize-typescript mysql2
# 安装 type
npm install --save-dev @types/sequelize
- 基本的なデータベース情報を構成する
// packages/node-server-demo/src/module/index.ts
import { Module } from '@nestjs/common';
import { UserModule } from './user';
import { LogModule } from './log';
import { Log } from '@/entities/Log';
import { SequelizeModule } from '@nestjs/sequelize';
@Module({
imports: [
SequelizeModule.forRoot({
dialect: 'mysql',
// 按数据库实际配置
host: '127.0.0.1',
// 按数据库实际配置
port: 3306,
// 按数据库实际配置
username: 'root',
// 按数据库实际配置
password: 'hello',
// 按数据库实际配置
database: 'world',
synchronize: true,
models: [Log],
autoLoadModels: true,
}),
LogModule,
UserModule,
],
})
export class AppModule {}
- エンティティとデータベース間の 1 対 1 マッピング
import { getNow } from '@/common/date';
import {
Model,
Table,
Column,
PrimaryKey,
DataType,
} from 'sequelize-typescript';
@Table({ tableName: 'test_sys_req_log' })
export class Log extends Model<Log> {
@PrimaryKey
@Column({
type: DataType.INTEGER,
autoIncrement: true,
field: 'id',
})
id: number;
@Column({ field: 'content', type: DataType.TEXT })
content: string;
@Column({ field: 'l_level', type: DataType.INTEGER })
level: number; // 3严重,2危险,1轻微
@Column({ field: 'l_category' })
category: string; // 模块分类/来源分类
@Column({
field: 'l_created_at',
type: DataType.NOW,
defaultValue: getNow(),
})
createdAt: number;
@Column({
field: 'l_updated_at',
type: DataType.NOW,
defaultValue: getNow(),
})
updatedAt: number;
}
- モジュール登録エンティティ
// packages/node-server-demo/src/module/log.ts
import { Module } from '@nestjs/common';
import { SequelizeModule } from '@nestjs/sequelize';
import { Log } from '@/entities/Log';
import LogServices, {
CreateLogService,
UpdateLogService,
DeleteLogService,
ReadLogService,
} from '@/service/log';
import {
CreateLogController,
RemoveLogController,
UpdateLogController,
} from '@/controller/log';
@Module({
imports: [SequelizeModule.forFeature([Log])],
providers: [
LogServices,
CreateLogService,
UpdateLogService,
DeleteLogService,
ReadLogService,
],
controllers: [CreateLogController, RemoveLogController, UpdateLogController],
})
export class LogModule {}
- サービスはデータベースを操作してデータを処理します
import { Log } from '@/entities/Log';
import { Injectable } from '@nestjs/common';
import { AddLogDto } from '@/dto/log';
import { InjectModel } from '@nestjs/sequelize';
import { ResponseStatus } from '@/types/BaseResponse';
import { getErrRes, getSucVoidRes } from '@/common/response';
@Injectable()
export class CreateLogService {
constructor(
@InjectModel(Log)
private logModel: typeof Log,
) {}
async create(createLogDto: AddLogDto): Promise<ResponseStatus<null>> {
console.info('CreateLogService create > ', createLogDto);
const { level = 1, content = '', category = 'INFO' } = createLogDto || {};
const str = content.trim();
if (!str) {
return getErrRes(500, '日志内容为空');
}
const item = {
level,
category,
// Tips: 为防止外部数据进行数据注入,我们可以对内容进行 encode 处理。
// content: encodeURIComponent(str),
content: str,
};
await this.logModel.create(item);
return getSucVoidRes();
}
}
虎の如く熾烈な作戦で、振り返るとふふふ~、ついに外界から最初のデータを受け取りました! hello world!
接続とデータの作成が成功しました。この時点で、基本的な機能は完成しました〜
ステップ 3:基本機能の実装CRUD
実際、データベースの操作ロジックと呼ばれるコンテンツの残りの部分は誰もが自分で理解できます。まずは何について話しましょうCRUD
C
作成するR
読んで読んでU
アップデートアップデートD
削除削除
以下は誰でも参照できる簡単な例です。残りはドキュメントを見つけてビジネス ロジックを実装するだけです。
import { Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/sequelize';
import { User } from './user.model';
@Injectable()
export class UserService {
constructor(
@InjectModel(User)
private userModel: typeof User,
) {}
// 创建新数据
async create(user: User) {
const newUser = await this.userModel.create(user);
return newUser;
}
// 查找所有数据
async findAll() {
return this.userModel.findAll();
}
// 按要求查找单个
async findOne(id: string) {
return this.userModel.findOne({ where: { id } });
}
// 按要求更新
async update(id: string, user: User) {
await this.userModel.update(user, { where: { id } });
return this.userModel.findOne({ where: { id } });
}
// 按要求删除
async delete(id: string) {
const user = await this.userModel.findOne({ where: { id } });
await user.destroy();
}
}
Tips:
削除する場合、バックアップ データベースとメイン データベースの 2 つのデータベースを疑似的に削除できます。マスター データベースは直接削除することも、削除を示すフラグを追加することもできます。データベースをバックアップすると、データの復元操作を実行できるように、削除せずに書き込みと更新操作のみが可能になります。
また、SQLデータベースインジェクションを防ぐために、全員が一律にデータソースを検証するか、直接エンコードする必要があり、重要なデータはMD5で直接暗号化することができ、データベースが直接ダウンロードされて漏洩することを防ぎます。SQLデータベースのセキュリティ処理に関しては、オンラインチュートリアルがたくさんありますので、探してみてください~
デプロイは比較的シンプルなので、いちいち詳しく説明する必要はありませんが、データベースはグループが提供するクラウドデータベースを利用でき、Nestは通常のノードデプロイです。
オープンソース フレームワーク NanUI の作者がスチールの販売に切り替えたため、プロジェクトは中断されました。Apple App Store の無料リストのナンバー 1 はポルノ ソフトウェア TypeScript です。人気が出てきたばかりなのに、なぜ大手はそれを放棄し始めるのでしょうか。 ? TIOBE 10月リスト:Javaが最大の下落、C#はJavaに迫る Rust 1.73.0リリース AIガールフレンドにイギリス女王暗殺を勧められた男性に懲役9年の実刑判決 Qt 6.6正式リリース ロイター:RISC-Vテクノロジーが中米テクノロジー戦争の鍵となる 新たな戦場 RISC-V: 単一の企業や国に支配されない レノボ、Android PC の発売を計画著者: JD Retail 周明良
出典:JD Cloud Developer Community 転載の際は出典を明記してください