🐈

Next.js✖️NestJS✖️GraphQLのフルスタックアプリのための環境構築(バックエンド構築編)

2025/01/14に公開

今回はNestJsを用いたバックエンド

今回構築する技術は

  • NestJS
  • Next.js
  • GraphQL
  • prisma
  • mysql(docker)

1. Nestプロジェクト作成

1. NestJS プロジェクトのセットアップ

npm install -g @nestjs/cli
nest new backend
cd backend

2. Prismaのセットアップ

npm install prisma --save-dev
npm install @prisma/client

今回は、mysqlを利用してDBを構築するためこちらにしています
各自環境に合わせてください

npx prisma init
datasource db {
  provider = "mysql"
  url      = env("DATABASE_URL")
}

generator client {
  provider = "prisma-client-js"
}

model User {
  id    String  @id @default(cuid())
  email String  @unique
  name  String
}

3. Dockerでmysqlの構築

https://qiita.com/Itsuki54/items/d2020be8e85727289c2d

詳しくはこちらの記事をご覧ください

touch docker-compose.yml
mkdir -p docker/mysql/sql
touch ./docker/mysql/sql/1_init.sql
touch .env
version: '3'
services:
  db:
    image: mysql:8.0
    ports:
      - '3311:3306'
    environment:
      MYSQL_ROOT_PASSWORD: 'root'
      MYSQL_USER: 'docker'
      MYSQL_PASSWORD: 'docker'
      MYSQL_DATABASE: 'test_db'
      TZ: 'Asia/Tokyo'
    volumes:
      - db-store:/var/lib/mysql
      - ./docker/mysql/sql:/docker-entrypoint-initdb.d

volumes:
  db-store:

:::note warn
ポートに注意
:::

GRANT CREATE, ALTER, DROP, REFERENCES ON *.* to 'docker' @'%';
MYSQL_ROOT_PASSWORD = your_root_password
MYSQL_DATABASE = mydatabase

DATABASE_URL = mysql://docker:docker@localhost:3307/test_db

起動すればDBコンテナが立ち上がります

docker compose up -d
npx prisma migrate dev --name init

これでprismaのセットアップも完了です!

4. GraphQLのセットアップ

npm install @nestjs/graphql @nestjs/apollo apollo-server-express graphql-tools graphql
import { Injectable, OnModuleInit } from '@nestjs/common';
import { PrismaClient } from '@prisma/client';

@Injectable()
export class PrismaService extends PrismaClient implements OnModuleInit {
  async onModuleInit() {
    await this.$connect();
  }
}
機能追加

serviceの追加

nest g service users

これでserviceとテストのテンプレが作成されました
以下のように修正します

import { Injectable } from '@nestjs/common';
import { PrismaService } from '../prisma.service';
import { User, Prisma } from '@prisma/client';

@Injectable()
export class UsersService {
  constructor(private prisma: PrismaService) {}

  async user(id: string): Promise<User | null> {
    return this.prisma.user.findUnique({
      where: { id },
    });
  }

  async users(): Promise<User[]> {
    return this.prisma.user.findMany();
  }

  async createUser(data: Prisma.UserCreateInput): Promise<User> {
    return this.prisma.user.create({
      data,
    });
  }
}

controllerの追加

nest g controller users

自動追加を修正

import { Controller, Get, Param, Post, Body } from '@nestjs/common';
import { UsersService } from './users.service';
import { User } from '@prisma/client';

@Controller('users')
export class UsersController {
  constructor(private readonly usersService: UsersService) {}

  @Get(':id')
  async findUserById(@Param('id') id: string): Promise<User> {
    return this.usersService.user(id);
  }

  @Get()
  async users(): Promise<User[]> {
    return this.usersService.users();
  }

  @Post()
  async createUser(
    @Body() userData: { name: string; email: string },
  ): Promise<User> {
    return this.usersService.createUser(userData);
  }
}

moduleの作成

nest g module users

修正

import { Module } from '@nestjs/common';
import { UsersService } from './users.service';
import { UsersController } from './users.controller';
import { PrismaService } from '../prisma.service';

@Module({
  controllers: [UsersController,],
  providers: [UsersService, PrismaService]
})
export class UserModule {}
import { Module } from '@nestjs/common';
import { UsersService } from './users.service';
import { UsersController } from './users.controller';
import { PrismaService } from '../prisma.service';

@Module({
  controllers: [UsersController,],
  providers: [UsersService, PrismaService]
})
export class UserModule {}
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { UsersService } from './users/users.service';
import { UsersController } from './users/users.controller';
import { UsersModule } from './users/users.module';

@Module({
  imports: [UsersModule],
  controllers: [AppController, UsersController],
  providers: [AppService, UsersService],
})
export class AppModule {}

これでバックエンドは完成しました!

GitHubで編集を提案

Discussion