ぽぴなび

知って感動した技術情報・生活情報や買ってよかったものの雑記です。

【NestJS x Auth0】NestJSで作成したAPIにAuth0の認証/認可を追加する 〜準備編 その2〜

前回の続きです。

popy1017.hatenablog.com

APIの中身は凝らないと言っていたのですが、 さすがに味気なかったのでテストデータを作成してそれを操作するようにしたいと思います。

1. Item エンティティの修正

src/items/entities/item.entity.tsを修正します。
今回は適当にidnamepriceを持つようにしました。

export class Item {
  id: string;
  name: string;
  price: number;
}

ついでに Itemに合わせてCreateItemDtoも修正しておきます。

export class CreateItemDto {
  name: string;
  price: number;
}

2. リポジトリクラスの作成

item-repository.tsを作成して、適当な3つのItemが保存されている状態にしました。
あとでitem.service.tsから呼び出すため、@Injectableをつけています。

import { Injectable } from '@nestjs/common';
import { CreateItemDto } from './items/dto/create-item.dto';
import { UpdateItemDto } from './items/dto/update-item.dto';
import { Item } from './items/entities/item.entity';
import * as crypto from 'crypto';

@Injectable()
export class ItemRepository {
  private _items: Item[] = [
    { id: 'e86639d1-65c8-75ad-005b-f2ec8a5e374a', name: 'Item A', price: 1000 },
    { id: '65d8b7eb-fdf4-4e71-4eb6-5dfb82e2fc3f', name: 'Item B', price: 2000 },
    { id: '9c35486d-efca-9f17-ce89-aa5299e423a9', name: 'Item C', price: 3000 },
  ];

  create(createItemDto: CreateItemDto): Item {
    const item: Item = {
      id: crypto.randomUUID(),
      ...createItemDto,
    };
    this._items.push(item);
    return item;
  }

  get(id: string): Item | undefined {
    return this._items.find((item) => item.id === id);
  }

  getAll(): Item[] {
    return this._items;
  }

  update(id: string, updateItemDto: UpdateItemDto): Item | undefined {
    let item: Item;

    const index = this._items.findIndex((_item) => _item.id === id);
    if (index >= 0) {
      this._items[index] = {
        ...this._items[index],
        ...updateItemDto,
      };
      item = this._items[index];
    }

    return item;
  }

  delete(id: string) {
    this._items = this._items.filter((item) => item.id !== id);
  }
}

3. ItemsService を修正する

上記で作成したItemRepositoryを使用するようにItemsServiceを修正します。
まず、ItemsServiceItemRepositoryを使用するために、ItemsModuleを修正します。
providersItemRepositoryを追加します。

import { Module } from '@nestjs/common';
import { ItemsService } from './items.service';
import { ItemsController } from './items.controller';
import { ItemRepository } from 'src/item-repository';

@Module({
  controllers: [ItemsController],
  providers: [ItemsService, ItemRepository],
})
export class ItemsModule {}

ItemsServiceではconstructorItemRepositoryを受け取り、各処理でそれを使うように修正します。

import { Injectable } from '@nestjs/common';
import { ItemRepository } from 'src/item-repository';
import { CreateItemDto } from './dto/create-item.dto';
import { UpdateItemDto } from './dto/update-item.dto';

@Injectable()
export class ItemsService {
  constructor(private itemRepository: ItemRepository) {}

  create(createItemDto: CreateItemDto) {
    return this.itemRepository.create(createItemDto);
  }

  findAll() {
    return this.itemRepository.getAll();
  }

  findOne(id: string) {
    return this.itemRepository.get(id);
  }

  update(id: string, updateItemDto: UpdateItemDto) {
    return this.itemRepository.update(id, updateItemDto);
  }

  remove(id: string) {
    return this.itemRepository.delete(id);
  }
}

動作確認

Postmanなどで動作確認します。

まず GET /itemsを実行してみます。
ハードコーディングしているItemのリストが返却されました。

curl --location --request GET 'http://localhost:3000/items'

[
    {
        "id": "e86639d1-65c8-75ad-005b-f2ec8a5e374a",
        "name": "Item A",
        "price": 1000
    },
    {
        "id": "65d8b7eb-fdf4-4e71-4eb6-5dfb82e2fc3f",
        "name": "Item B",
        "price": 2000
    },
    {
        "id": "9c35486d-efca-9f17-ce89-aa5299e423a9",
        "name": "Item C",
        "price": 3000
    }
]

次に、POST /itemsItemを追加します。

curl --location --request POST 'http://localhost:3000/items' \
--header 'Content-Type: application/json' \
--data-raw '{
    "name": "Item D",
    "price": 4000
}'

{
    "id": "af938f5c-8948-4f23-9d04-6354ab07e054",
    "name": "Item D",
    "price": 4000
}

再度GET /itemsを実行すると、createしたItemが追加されていることが確認できました。

curl --location --request GET 'http://localhost:3000/items'

[
    {
        "id": "e86639d1-65c8-75ad-005b-f2ec8a5e374a",
        "name": "Item A",
        "price": 1000
    },
    {
        "id": "65d8b7eb-fdf4-4e71-4eb6-5dfb82e2fc3f",
        "name": "Item B",
        "price": 2000
    },
    {
        "id": "9c35486d-efca-9f17-ce89-aa5299e423a9",
        "name": "Item C",
        "price": 3000
    },
    {
        "id": "af938f5c-8948-4f23-9d04-6354ab07e054",
        "name": "Item D",
        "price": 4000
    }
]

以上でそれっぽいAPIができたので準備完了です。
次回からAuth0と連携して認証/認可できるようにしていきます。

この時点のソースコード

github.com