들어가기
Entity와 Dto를 다 만들었으면,
다음은, resolver와 service를 만들어보자.
import { Resolver, Mutation, Args } from '@nestjs/graphql'; ///from된는 부분확인.
import {
CreateAccountInput,
CreateAccountOutput,
} from './dtos/create-account.dto';
import { LoginInput, LoginOutput } from './dtos/login.dto';
import { User } from './entities/user.entity';
import { UserService } from './users.service';
@Resolver(() => User) ///시작하기에 앞서 가장먼저 type을 Resolver로 정해주고 Return은
/// User Entity로 한다.
export class UserResolver {
constructor(private readonly usersService: UserService) {}
///constructor를 만드는데, usersService를 사용한다는 부분 주의깊게 볼것.
///usersService: UserService는 UserService type의 usersService를 사용하겠다는 의미.
@Mutation(() => CreateAccountOutput) ///Mutation으로 정의, return은
///CreateAccountOutput이라는 뜻.
async createAccount(
@Args('input') createAccountInput: CreateAccountInput,
): Promise<CreateAccountOutput> {
///@Args('input')는 create-account.dto.ts에서 만든 CreateAccuntInput
///을 createAccountInput로 사용하겠다는 의미,
/// CreateAccountInputdl InputTypedlrl 때문에 @Args('input')을 쓴다.
/// output(return)은 : Promise<CreateAccountOutput>으로 적어줌.
try {
return this.usersService.createAccount(createAccountInput);
///resolver에서는 return 부분과 service에서 사용되는 함수, dto만 정의
/// 반드시 this붙일것.
} catch (error) {
return {
error,
ok: false,
};
}
}
///try~catch로 작성함.
///login부분은 createAccount Mutation 설명 부분과 거의 동일.
@Mutation(() => LoginOutput)
async login(@Args('input') loginInput: LoginInput): Promise<LoginOutput> {
try {
return this.usersService.login(loginInput);
} catch (error) {
return {
ok: false,
error,
};
}
}
}
실제로 Mutation 및 Query가 실행되는 Logic을 만드는 부분.
import { User } from './entities/user.entity';
import { Injectable } from '@nestjs/common';
import { Repository } from 'typeorm';
import { InjectRepository } from '@nestjs/typeorm';
import { CreateAccountInput } from './dtos/create-account.dto';
import { LoginInput } from './dtos/login.dto';
@Injectable() ///type은 Injectable()로 한다.
export class UserService {
constructor(
@InjectRepository(User) private readonly users: Repository<User>,
) {}
///constructor에 @InjectRepository(User)은 User Entity를 사용하겠다는 의미
///users: Repository<User>, 은 users라는 name으로 User Entity를 사용하겠다는 의미
async createAccount({
email,
password,
role,
}: CreateAccountInput): Promise<{ ok: boolean; error?: string }> {
///CreateAccounInput Dto의 email, password, role을 사용하겠다는 의미.
///return type은 Promise<{ok:boolean, error?:string}>로 해줌.
///다양한 방법이 존재하나 ObjectType으로 설정함.
try {
const exists = await this.users.findOneBy({ email });
if (exists) {
return { ok: false, error: 'There is a user with that email already' };
}
await this.users.save(this.users.create({ email, password, role }));
return { ok: true };
} catch (e) {
return { ok: false, error: 'Could not create account' };
}
}
///users.findOneBy({email})을 통해 같은 email이 있는지 찾은 후에,
///email이 존재하면, error날림.
///email이 존재하지 않으면,
///await this.users.save(this.users.create({ email, password, role }));
///User DB애 create 및 save함. 그리고 ok:true 날림~
async login({
email,
password,
}: LoginInput): Promise<{ ok: boolean; error?: string; token?: string }> {
try {
const user = await this.users.findOneBy({ email });
if (!user) {
return {
ok: false,
error: 'User not found',
};
}
///여기까지는 createAccount와 비슷.
///return에서 Peomise에 token?도 넣어줌.
const passwordCorrect = await user.checkPassword(password);
if (!passwordCorrect) {
return {
ok: false,
error: 'Wrong password',
};
}
///Entity의 beforeInsert에서 만들어준 checkPassword 사용힘..
return {
ok: true,
token: 'lalalala',
};
} catch (error) {
return {
ok: false,
error,
};
}
}
}
token부분은 이어서 코딩해 줄 예정.~