今回は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
schema.prisma
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の構築
詳しくはこちらの記事をご覧ください
touch docker-compose.yml
mkdir -p docker/mysql/sql
touch ./docker/mysql/sql/1_init.sql
touch .env
docker-compose.yaml
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:
ポートに注意
docker/mysql/sql/1_init.sql
GRANT CREATE, ALTER, DROP, REFERENCES ON *.* to 'docker' @'%';
.env
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
src/prisma.service.ts
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とテストのテンプレが作成されました
以下のように修正します
src/users/users.service.ts
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
自動追加を修正
src/users/users.controller.ts
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
修正
src/users/users.module.ts
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 {}
src/app.module.ts
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 {}