NestJSとは何ですか?
NestJSは、ExpressやFastifyなどの一般的なNodeJSフレームワークを内部で利用する最新のNodeJSフレームワークです。 NestJSは主にAngularに触発され、その結果、Angularスタイルのモジュールシステムを採用しています。 NestJSはTypeScriptで記述されていますが、ネイティブJavaScriptもサポートしています。
前提条件
このチュートリアルに従うには、次の要件を満たす必要があります
- PostManまたはその他のAPIテストツールの能力。
- NodeJSおよびExpressアプリの基本的な知識。
- TypeScriptの基本的な知識。
- MongoDB(Mongoose)の能力。
以下をシステムにインストールする必要があります
- NodeJSv.14以降。
- Visual Studio Code(推奨)またはその他のIDE。
- PostManまたはその他のAPIテストツール。
NestJSで使用される一般的な用語;
NestJSで最もよく使用される用語のいくつかを次に示します。この記事でよく遭遇します。
インターフェース
インターフェイスは型定義です。その結果、関数やクラスなどの型チェッカー/エンフォーサーとして利用されます。
interface humanInterface{
name:string;
gender:string;
age:number;
}
const kevin: humanInterface={
name:'Kevin Sunders',
gender:'Male',
age: 25,
}
humanInterface
上記は、kevin
に対して厳密な型チェックを実行します 物体。別のフィールドを追加したり、オブジェクトプロパティのタイプを変更したりすると、Typescriptはエラーをスローします。
コントローラー
コントローラは、着信要求の受信とクライアントへの応答を担当します。コントローラは、関連するサービスと連携します。
サービス
サービスは、データを保存および取得し、対応するコントローラーで使用されるプロバイダーです。
デコレータ
デコレータは、target
を受け入れる関数を返す式です。 、name
、およびproperty descriptor
オプションの引数として。デコレータは@decorator-name
と書かれています 。これらは通常、クラス宣言、メソッド、およびパラメーターに付加されます。
@Get()
getAll(): Model[] {
return this.testService.getAll();
}
@Get
上のデコレータは、その下のコードブロックをGET
としてマークします リクエスト。これについては後で詳しく説明します。
モジュール
モジュールは、特定のタスクを処理するプログラムの一部です。 NestJSのモジュールは、@Module()
でアノテーションが付けられたクラスにアノテーションを付けることでマークされます。 デコレータ。 Nestは、@Module()
によって提供されるメタデータを使用します アプリケーション構造を整理するためのデコレータ。
CLIのインストール
開始するには、npm
を使用してNestJSCLIをインストールする必要があります**** 。システムにNestJSCLIがすでにインストールされている場合は、この手順をスキップできます。
npm i -g @nestjs/cli
上記のコードブロックは、ネストCLIをシステムにグローバルにインストールします。
新しいプロジェクトの作成
新しいプロジェクトを生成するには、nest new
を実行します 希望するプロジェクト名が続きます。この記事では、RESTful標準に準拠しながら、CRUD機能を備えたシンプルなブログAPIを作成します。
nest new Blog-Api
このコマンドは、パッケージマネージャーを選択するように求めるプロンプトを表示します。npm
を選択します。 。
これにより、ポートが3000
に設定されているテストAPIエンドポイントを使用して、プロジェクト構造全体がスキャフォールディングされます。 デフォルトでは。 http://localhost:3000
でテストできます npm run start:dev
を実行した後 nodemonがエクスプレスアプリで行うのと同様の監視モードでサーバーを起動するコマンド。
エンドポイントをテストした後、デフォルトのファイルの一部を削除する必要があります。これは、それらが不要になるためです。これを行うには;
- srcフォルダとその中を開きます
-
app.controller.spec.ts
を削除します 、 -
app.controller.ts
を削除します 、 -
app.service.ts
を削除します 、 -
app.module.ts
を開きます 、 -
AppController
への参照を削除しますcontrollers
で 配列とインポート、 -
AppService
への参照を削除しますproviders
で 配列とインポート。
README.md
も変更する必要がある場合があります 仕様を満たすために。
app.module.ts
ファイルは次のようになります。
//app.module.ts
import { Module } from '@nestjs/common';
@Module({
imports: [],
controllers: [],
providers: [],
})
export class AppModule {}
環境変数
良い習慣として、コード内の一部の機密情報は公開しないでください。たとえば、PORT
およびMongoDB URI
。
これをコードで修正しましょう。
ターミナルで実行
npm i dotenv
次に、.env
を作成します ディレクトリ内のファイルを.gitignore
に追加します ファイル。 PORT
を保存します 変数の場合、MongoDB URI
も保存する必要があります 後で同じ場所で。次に、公開されたPORT
を置き換えます main.ts
で ファイル。これを行うには、dotenv
をインポートします パッケージ化して.config()
を呼び出します その上でメソッド。
import * as dotenv from 'dotenv';
dotenv.config();
これはmain.ts
である必要があります 上記の手順を実行した後、ファイルします。
//main.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import * as dotenv from 'dotenv';
dotenv.config();
async function bootstrap() {
const app = await NestFactory.create(AppModule);
await app.listen(process.env.PORT);
}
bootstrap();
モジュールの生成
NestJS CLIを使用してNestJSモジュールを生成するには、以下のコードスニペットを実行します。
nest generate module blogs
このコマンドは、blogs
を作成します blogs.module.ts
を含むフォルダー ファイルとレジスタBlogsModule
app.module.ts
で ファイル。
インターフェースの生成
NestJS CLIを使用してインターフェースを生成し、ブログ投稿を表すオブジェクトの型チェックを実行してみましょう。これを実現するには、最初にcd
を実行する必要があります blogs
に それらが関連付けられているドメインオブジェクトの近くに保存することをお勧めするため、フォルダ。
cd src/blogs
次に、以下のコードスニペットを実行してインターフェイスを生成します。
nest generate interface blogs
これにより、blogs.interface.ts
が作成されます ファイル。ここでインターフェースを定義します。インターフェイスにBlogsInterface
という名前を付けます 。
export interface BlogsInterface {
title: string;
body: string;
category: string;
dateCreated: Date;
}
端末でこれ以上コマンドを実行する前に、cd
を忘れないでください。 src
から フォルダを実行してルートフォルダに戻ります
cd ../..
サービスとコントローラーの生成
データを保存および取得し、すべてのロジックを処理するサービスクラスと、すべての着信要求と発信応答を処理するコントローラークラスを生成する必要があります。
サービス
サービスを生成するには、以下のコマンドを実行します。
nest generate service blogs
このコマンドは、blogs.service.spec.ts
に2つのファイルを作成します およびblogs.service.ts
providers
にサービスを登録します blogs.module.ts
の配列 。
コントローラー
コントローラを生成するには、以下のコマンドを実行します。
nest generate controller blogs
このコマンドは、blogs.controller.spec.ts
に2つのファイルを作成します およびblogs.controller.ts
コントローラをcontrollers
に登録します blogs.module.ts
の配列 。
これらのブログ構造はほぼ完成しているので、BlogsService
を作成するだけです。 プログラムの他の部分にアクセスできます。これは、exports
を作成することで実現できます。 blogs.module.ts
の配列 ファイルとBlogsService
の登録 その配列で。
//blogs.module.ts
import { Module } from '@nestjs/common';
import { BlogsService } from './blogs.service';
import { BlogsController } from './blogs.controller';
@Module({
providers: [BlogsService],
controllers: [BlogsController],
exports: [BlogsService],
})
export class BlogsModule {}
MongoDB(マングース)。
実行してマングースをインストールし、
npm install --save @nestjs/mongoose mongoose
インストール後、{MongooseModule}
をインポートします '@nestjs/mongoose’
から app.module.ts
に ファイル。次に、MongoDB URI
を取得します .env
に保存します ファイル。手順を繰り返して、dotenv
をインポートします app.module.ts
内 ファイル。次に、imports
配列は.forRoot()
を呼び出します MongoDB URI
を取得するメソッド MongooseModule
の引数として 。 mongoose.connect()
に似ています 正規表現アプリで。
@Module({
imports: [BlogsModule, MongooseModule.forRoot(process.env.MONGODB_URI)],
スキーマの作成。
コレクション内のブログの形状を定義するスキーマを作成しましょう。これを行うには、
blogs
内にフォルダを作成します フォルダにschemas
という名前を付けます 、schemas
の内部 フォルダを作成し、ファイルを作成してblogs.schema.ts
と呼びます。 。
次に、
まず、次のことを行う必要があります。
-
prop
をインポートします デコレータ、Schema
デコレータ、およびSchemaFactory
@nestjs/mongoose
から 、 - クラスを作成する
Blog
エクスポートします -
@Schema()
を配置して、クラスをスキーマに変換します クラスの上のデコレータ - 定数
BlogSchema
を作成します 、.createForClass(Blog)
の呼び出しの戻り値を割り当てますSchemaFactory
の引数としてクラスの名前を使用します 以前にインポートしたもの。
//blogs.schema.ts
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
@Schema()
export class Blog {}
export const BlogSchema = SchemaFactory.createForClass(Blog);
次に、スキーマのプロパティを定義する必要があります。
スキーマでプロパティを定義するには、各プロパティを@prop()
でマークする必要があります デコレータ。 @prop
デコレータは、オプションオブジェクトまたは複合型宣言を受け入れます。複合型宣言は、配列およびネストされたオブジェクト型宣言である可能性があります。
//blogs.schema.ts
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
@Schema()
export class Blog {
@Prop({ required: true })
title: string;
@Prop({ required: true })
body: string;
@Prop({ required: true })
category: string;
@Prop({ required: true })
dateCreated: Date;
}
export const BlogSchema = SchemaFactory.createForClass(Blog);
次に、{ Document }
をインポートします 'mongoose'
から 。
次に、SchemaクラスとインポートされたDocument
を使用して共用体型を作成します 。そのようです、
//blogs.schema.ts
import { Document } from 'mongoose';
export type BlogDocument = Blog & Document;
最後のblogs.schema.ts
ファイルは次のようになります。
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import { Document } from 'mongoose';
export type BlogDocument = Blog & Document;
@Schema()
export class Blog {
@Prop({ required: true })
title: string;
@Prop({ required: true })
body: string;
@Prop({ required: true })
category: string;
@Prop({ required: true })
dateCreated: Date;
}
export const BlogSchema = SchemaFactory.createForClass(Blog);
スキーマの登録
すべてをblogs.module.ts
にインポートする必要があります ファイル。これを実現するには、次のことを行う必要があります。
- インポート
{MongooseModule}
'@nestjs/mongoose’
から 、 - インポート
{Blog, BlogSchema}
'./schemas/blogs.schema’
から imports
を作成します@module
内の配列 デコレータ-
.forFeature()
を呼び出しますMongooseModule
のメソッド 。これは、name
を定義するオブジェクトを含む配列を取り込みます およびschema
Blog.name
に設定する必要のあるプロパティ およびBlogSchema
それぞれ。
@Module({
imports: [
MongooseModule.forFeature([{ name: Blog.name, schema: BlogSchema }]),
],
挿入スキーマ
blogs
を挿入する必要があります blogs.service.ts
にモデル化する @InjectModel()
を使用する デコレータ。これを達成するには、次のことを行う必要があります
- import
{ Model }
'mongoose'
から 、 - import
{ InjectModel }
'@nestjs/mongoose’
から 、 - インポート
{Blog, BlogDocument}
'./schemas/blogs.schema’
から 、 constructor
を作成しますBlogsService
内 クラス、private
を宣言します 変数をblogModel
と呼びます タイプをModel<BlogDocument>
に割り当てます それに。すべてのマングースメソッドがこの変数で呼び出されます。
BlogDocument
を思い出してください Blog
の共用体タイプです クラスとマングースのModel
以前に作成したもの。変数の総称型として使用されます。
-
blogModel
を飾ります@InjectModel()
を使用Blog.name
を渡します 議論として。
constructor(
@InjectModel(Blog.name)
private blogModel: Model<BlogDocument>,
) {}
ルーティングの仕組み
ここまでで、@Controller
に気付いたはずです。 デコレータの文字列は'blogs'
それに渡されます。これは、コントローラーがすべての応答を送信し、http://localhost/3000/blogs
で行われたすべての要求を処理することを意味します 。
次に、サービスとコントローラーのロジックを実装します。
サービスおよびコントローラーロジック。
いよいよCRUD機能を実装する時が来ました。
始める前に、コントローラーをセットアップする必要があります。いくつかのHTTP
をインポートすることから始めます コントローラへのメソッドデコレータ。
//blogs.controller.ts
import {
Controller,
Body,
Delete,
Get,
Post,
Put,
Param,
} from '@nestjs/common';
次に、サービスにアクセスしてタイプチェック用のインターフェースをインポートできるように、サービスをインポートして登録する必要があります。
//blogs.controller.ts
import { BlogsInterface } from './blogs.interface';
import { BlogsService } from './blogs.service';
サービスを登録するには、constructor
を作成します BlogsController
内 クラスを作成し、private readonly
を宣言します 変数service
タイプをBlogsService
に設定します 。
constructor(private readonly service: BlogsService) {}
これですべての設定が完了したので、始めましょう。
作成
サービスロジック
{ BlogsInterface }
をインポートします './blogs.interface'
から async
を追加します BlogsService
への関数 createBlog
というクラス 、1つのパラメータを取りますblog
、タイプはBlogInterface
、およびPromise
としての戻りタイプ 一般的な<Blog>
タイプ。
async createBlog(blog: BlogsInterface): Promise<Blog> {
return await new this.blogModel({
...blog,
dateCreated: new Date(),
}).save();
}
コントローラーロジック
BlogsController
で クラスはasync
を追加します クラスへの機能。それをcreateBlog
と呼びます @Post
でマークします POST
として定義するデコレータ request。createBlog
1つのパラメータを取りますblog
、タイプはBlogInterface
。パラメータを@Body
でマークします body
全体を抽出するデコレータ req
のオブジェクト オブジェクトを作成し、装飾されたパラメータにbody
の値を入力します 。
@Post()
async createBlog(
@Body()
blog: BlogsInterface,
) {
return await this.service.createBlog(blog);
}
読む
2つのasync
を追加します メソッド。1つは単一のブログ投稿を返し、もう1つはすべてのブログ投稿を返します。
サービスロジック
async getAllBlogs(): Promise<Blog[]> {
return await this.blogModel.find().exec();
}
async getBlog(id: string): Promise<Blog> {
return await this.blogModel.findById(id);
}
コントローラーロジック
@Get()
async getAllBlogs() {
return await this.service.getAllBlogs();
}
@Get(':id')
async getBlog(@Param('id') id: string) {
return await this.service.getBlog(id);
}
async
関数は@Get
でマークされています GET
として定義するデコレータ リクエスト。
2番目のasync
関数のデコレータには引数':id'
があります 。これを@Param
に渡します デコレータ。パラメータは@Param('id')
でマークされています params
を抽出します req
のプロパティ オブジェクトを作成し、装飾されたパラメータにparams
の値を入力します 。
更新
PUT
のロジックを実装しましょう リクエスト。
サービスロジック
async updateBlog(id: string, body: BlogsInterface): Promise<Blog> {
return await this.blogModel.findByIdAndUpdate(id, body);
}
コントローラーロジック
@Put(':id')
async updateBlog(
@Param('id')
id: string,
@Body()
blog: BlogsInterface,
) {
return await this.service.updateBlog(id, blog);
}
async
関数の2番目のパラメーターは、@Body()
でマークされています body
全体を抽出するデコレータ req
のオブジェクト オブジェクトを作成し、装飾されたパラメータにbody
の値を入力します 。
削除
delete
のロジックを実装しましょう リクエスト。
サービスロジック
async deleteBlog(id: string): Promise<void> {
return await this.blogModel.findByIdAndDelete(id);
}
Promise
総称型はvoid
です Delete
リクエストは空のpromiseを返します。
コントローラーロジック
@Delete(':id')
async deleteBlog(@Param('id') id: string) {
return await this.service.deleteBlog(id);
}
APIのテスト
このAPIをテストするには、APIテストツールを使用する必要があります。この記事では、Postmanと呼ばれる人気のあるAPIテストツールを使用します。人気のあるトピックに関するランダムなデータを使用してテストします。
作成
POST
を作成します http://localhost/3000/blogs
へのリクエスト 次のJSONオブジェクトを使用すると、すべてのデータがデータベースに追加されます。
{
"title": "jeen-yuhs",
"body": "The life of superstar rapper Kanye West is currently streaming on Netflix - and according to our jeen-yuhs review, it's a fascinating watch. -credit:Radio Times",
"category":"Music"
}
{
"title": "Why You Should Always Wash Your Hands",
"body": "Germs from unwashed hands can be transferred to other objects, like handrails, tabletops, or toys, and then transferred to another person's hands.-credit cdc.gov",
"category":"Health"
}
{
"title": "Why You Should Follow me on Twitter",
"body": "Well, Because I asked nicely",
"category":"Random"
}
201
を取得する必要があります 応答と、日付と_id
を含む作成されたブログ 追加されました。
読む
GET
を作成します http://localhost/3000/blogs
へのリクエスト 。これは
200
以前に追加したすべてのデータの配列による応答。 _id
をコピーします 配列オブジェクトの1つのプロパティ。
別のGET
を作成します http://localhost/3000/blogs/id
へのリクエスト 以前にコピーされたIDを使用します。これにより、200
が返されます。 IDがリクエストの作成に使用されたオブジェクトのデータによる応答。
更新
PUT
を作成します http://localhost/3000/blogs/id
へのリクエスト 以下のデータで。 id
以前にコピーしたものと交換する必要があります。これにより、200
が返されます。 応答し、id
を持つオブジェクトを更新します 舞台裏。別のGET
を実行した場合 更新されたオブジェクトを取得する必要があります。
{
"title": "why you Should Cut your Nails",
"body": "It's important to trim your nails regularly. Nail trimming together with manicures makes your nails look well-groomed, neat, and tidy.- credit:WebMD",
"category":"Health"
}
削除
DELETE
を作成します http://localhost/3000/blogs/id
へのリクエスト 。これにより、200
が返されます。 応答し、id
を持つオブジェクトを削除します 舞台裏。別のGET
を実行した場合 削除されたオブジェクトが表示されないようにリクエストします。
結論
これで、ようやくこの記事の終わりになりました。カバーした内容を要約してみましょう。
- NestJSとは
- NestJSの用語
- NestJSアプリの作成
- MongoDBをNestJSアプリに統合する
- 操作とNestJSアプリ
これは非常に多くのことです。これまでのところ、おめでとうございます。
コードはgithubにあります。
NestJSの旅に頑張ってください!