1
/
5

NestJSでREST(その2)

前回まで


NestJSでREST(その1) | 株式会社ROBON
はじめに当社では、クラウドネイティブなSaaSの開発をしており、いつもはWebAPIの実装ならサーバーレスで。となるのですが、今回は、サーバーレスでないWebAPIの実現方法として、NestJS...
https://www.wantedly.com/companies/company_5181558/post_articles/897233


NestJSのCLIでWebサーバー部分はできちゃいました。👏

データベースと繋ぐ

TypeORM(とPostgres)を導入

本家を含めて、mysqlが多いような気がしますが、今回は、別件でPostgesを使っていたので、Postgresでやります。

$ npm install --save @nestjs/typeorm typeorm pg


customersを実装する

まず、テーブルを作ります。


CREATE TABLE CUSTOMER (

CUSTOMER_ID int,
NAME text,
ADDRESS text,
CONSTRAINT PK_CUSTOMER PRIMARY KEY(CUSTOMER_ID)
);

ここで英大文字で書いても、Postgresさんは英小文字で認識されていて、後でハマります。

TypeORMの設定

TypeORMにデータベースの設定をしつつ、NestJSのモジュールとしてAppModuleに組み込みます。


@@ -1,10 +1,25 @@

import { Module } from '@nestjs/common';
+import { TypeOrmModule } from '@nestjs/typeorm';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { CustomersModule } from './customers/customers.module';
+import { Customer } from './customers/entities/customer.entity';

@Module({
- imports: [CustomersModule],
+ imports: [
+ CustomersModule,
+ TypeOrmModule.forRoot({
+ type: 'postgres',
+ host: '■■■■',
+ port: 5432,
+ username: '■■■■',
+ password: '■■■■',
+ database: 'postgres',
+ entities: [Customer],
+ logging: true,
+ synchronize: false,
+ }),
+ ],
controllers: [AppController],
providers: [AppService],
})

loggingをtrueにしておくとハマったときに助かります。(ハマってからtrueにしました)
設定がこんな感じだと丸見えなので、あとでなんとかします。

エンティティの設定

Java界隈でお馴染みの香りがします。


@@ -1 +1,13 @@

-export class Customer {}
+import { Entity, Column, PrimaryColumn } from 'typeorm';
+
+@Entity()
+export class Customer {
+ @PrimaryColumn({ name: 'customer_id' })
+ customerId: number;
+
+ @Column()
+ name: string;
+
+ @Column()
+ address: string;
+}

ここでハマりました。TypeORMさんは、テーブル名やカラム名をダブルクォートで囲んで渡してます。SQLの世界では大文字小文字の区別はしないのですが、Postgresさんは、ダブルクォートで囲むと書かれたとおりの文字列としてマッチングするそうです。

ですから、上で、@PrimaryColumn({ name: 'customer_id' })としているところをCREATE TABLE文のとおりに'CUSTOMER_ID'としてしまうと、「そんなカラムはありません」の一点張りで動きません。

今回に限らず、実は、ORマッパー嫌いです(笑)。今回は、logging: trueにして、TypeORMが表示したSQLを直叩きしないと解決できませんでした。「な。だから最初から俺にSQL書かせろよ」

DTOの設定

前回のイメージのJSONになるように定義します。


@@ -1 +1,5 @@

-export class CreateCustomerDto {}
+export class CreateCustomerDto {
+ customerId: number;
+ name: string;
+ address: string;
+}

Update用のクラスは、以下のように、生成された状態のまま変更しなくても大丈夫です。

export class UpdateCustomerDto extends PartialType(CreateCustomerDto) {}

PartialTypeって何?ってなりますよね。

The PartialType() function returns a type (class) with all the properties of the input type set to optional.


Documentation | NestJS - A progressive Node.js framework
Nest is a framework for building efficient, scalable Node.js server-side applications. It uses progressive JavaScript, is built with TypeScript and combines elements of OOP (Object Oriented Programming), FP (Functional Programming), and FRP (Functional Re
https://docs.nestjs.com/openapi/mapped-types

むむむ。ということで、ソースコードを遡ると

/**

* Make all properties in T optional
*/
type Partial<T> = {
[P in keyof T]?: T[P];
};

ということで、?が付いてオプショナル。作成の時は全部だけど、更新の時は欠けてもいい。というのができるのね。TypeScriptは深い。

次回は

serviceからやります。

Invitation from 株式会社ROBON
If this story triggered your interest, have a chat with the team?
株式会社ROBON's job postings

Weekly ranking

Show other rankings
Like 荒木 岳夫's Story
Let 荒木 岳夫's company know you're interested in their content