Nestjsをローカルで動かしてみる
まずはやってみるところから。 プロジェクト作成 やってみた系なので、とりあえずnpxでさっとやる。 npmかyarnかどっちつかうか聞かれます。 このコマンドが案内されたら準備OK Nestjs APIをローカルで動かす […]
目次
まずはやってみるところから。
プロジェクト作成
やってみた系なので、とりあえずnpxでさっとやる。
$ npx @nestjs/cli new my-nestjs-app
⚡ We will scaffold your app in a few seconds..
CREATE /my-nestjs-app/README.md (3370 bytes)
CREATE /my-nestjs-app/nest-cli.json (64 bytes)
CREATE /my-nestjs-app/package.json (1697 bytes)
CREATE /my-nestjs-app/tsconfig.build.json (97 bytes)
CREATE /my-nestjs-app/tsconfig.json (336 bytes)
CREATE /my-nestjs-app/tslint.json (426 bytes)
CREATE /my-nestjs-app/src/app.controller.spec.ts (617 bytes)
CREATE /my-nestjs-app/src/app.controller.ts (274 bytes)
CREATE /my-nestjs-app/src/app.module.ts (249 bytes)
CREATE /my-nestjs-app/src/app.service.ts (142 bytes)
CREATE /my-nestjs-app/src/main.ts (208 bytes)
CREATE /my-nestjs-app/test/app.e2e-spec.ts (630 bytes)
CREATE /my-nestjs-app/test/jest-e2e.json (183 bytes)
npmかyarnかどっちつかうか聞かれます。
? Which package manager would you ❤️ to use? (Use arrow keys)
❯ npm
yarn
このコマンドが案内されたら準備OK
$ cd my-nestjs-app
$ yarn run start
Nestjs APIをローカルで動かす
デフォルトだとlocalhost:3000を使用します。
$ curl https://localhost:3000/
Hello World!
Port3000が使用中だとエラーが出ます。
events.js:174
throw er; // Unhandled 'error' event
^
Error: listen EADDRINUSE: address already in use :::3000
後半で紹介しますが、NestjsもExpressなどと同じくコード内でポートを指定する仕組みな様子です。
なのでCreate React Appあたりのport3000を使用してくるアプリと並行して作業する場合は環境変数などを使って外からポートを変えれるようにするとよいかもしれません。
開発中はyarn run start:dev
yarn start
はコードの変更をwatchしません。
$ cat package.json | jq .scripts | grep start
"start": "nest start",
"start:dev": "nest start --watch",
"start:debug": "nest start --debug --watch",
"start:prod": "node dist/main",
dev
, debug
, prod
の3種類がありますので、使い分けましょう。
ちょっとだけNestjsのソースを触ってみる
作るだけだとつまらないので、ちょっとだけいろいろ触ってみます。
APIのportを変更する
APIのportはsrc/main.ts
に定義されています。
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
await app.listen(3000);
}
bootstrap();
変更したい場合は、ここのapp.listen
の数字を変えましょう。
環境変数でポートを変える
環境変数を使ってportを上書きできるようにしておくと便利そうです。
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
const port = Number(process.env.PORT) || 3000
await app.listen(port);
}
bootstrap();
起動時は$ export PORT=3001; yarn start
のようにしましょう。
APIを追加する
とりあえずAPIを2つほど追加してみましょう。
エンドポイント追加だけを試すため、今回は敢えてcontrollerにレスポンスを直書きしてます。
実践時はちゃんとserviceクラスを作りましょう。
シンプルなGET APIエンドポイント
まずはパラメータのないシンプルなGETを作ります。
import { Controller, Get, Param } from '@nestjs/common';
import { AppService } from './app.service';
@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
@Get()
getHello(): string {
return this.appService.getHello();
}
// ここから追加コード
@Get('my-custom')
myCustomAPI(): {message: string} {
return {
message: 'Hello!'
}
}
// ここまで追加コード
}
簡単ですね。保存するとmy-custom
というパスを使えるようになります。
$ curl https://localhost:3000/my-custom | jq .
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 20 100 20 0 0 2869 0 --:--:-- --:--:-- --:--:-- 3333
{
"message": "Hello!"
}
// 適当に叩くと404
$ curl https://localhost:3000/my-custom-2 | jq .
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 74 100 74 0 0 7718 0 --:--:-- --:--:-- --:--:-- 8222
{
"statusCode": 404,
"error": "Not Found",
"message": "Cannot GET /my-custom-2"
}
パスパラメーターやクエリストリングをつける
パスパラメータやクエリストリングなども設定できます。
import { Controller, Get, Param, Query } from '@nestjs/common';
@Controller()
export class AppController {
@Get('my-custom/:name')
myCustomAPIWithPath(@Param('name') name: string, @Query() query: {
s: string;
d: number
}): {
message: string;
name: string;
query: {
s: string;
d: number
}
} {
return {
message: `Hello. ${name}-san!`,
name,
query
}
}
}
この場合、my-custom/:name
という形でname
を変数に、クエリストリングでs
とd
を想定しているGET APIができあがります。
$ curl "https://localhost:3000/my-custom/john?s=hi&d=1&h=true" | jq .
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 82 100 82 0 0 2975 0 --:--:-- --:--:-- --:--:-- 3037
{
"message": "Hello. john-san!",
"name": "john",
"query": {
"s": "hi",
"d": "1",
"h": "true"
}
}
ただし上のサンプルのようにd
がstring型で来ていたりh
という未定義の値も受け付ける挙動となります。
APIに投げられた値を検証するわけではなく、「この型で来るはずなので、処理してください」という意味合いになることを注意する必要があります。Nest.jsに限った話ではありませんが。
おわりに
デコレーターベースでAPIの定義をもろもろ設定できますので、直感的に触れる印象はあります。
ただしデコレーターというか@を使う書き方に慣れていないとちょっと戸惑うかもしれません。
Express.js未経験でいきなりNest.js触るという一足飛ばしなことをしていますが、個人的にはNest.jsベースでやるのが手軽そうかなとは思いました。
尤も、実案件でいろいろ依存関係が出てきたときに地雷を踏みやすいかどうかはやってみてのお楽しみですが・・・