요즘 NestJS를 공부하고 있다. NestJS로 이것저것 만들어보다 Graphql과 Mongoose를 사용하여 API를 만들어보고 싶었다. 공식 문서와 구글링한 정보를 조합하여 정보도 공유할 겸, 다음에 내가 활용하기 위해 기록하고자 한다.
$ npm i -g @nestjs/cli
$ nest new {your project name}
💡 설치 중 'Which package manager would you to use?' 라는 문구가 뜨면 본인이 원하는 패키지 매니저를 선택하면 된다. 나는 npm을 사용할 것이라 npm으로 설치했다.
프로젝트가 생성되면 프로젝트를 열어서 다음 코드 실행
$ npm install
$ npm run start:dev
웹브라우에 다음과 같이 입력한다.
http://localhost:3000/
화면에 'Hello World!' 라고 나오면 NestJS 프로젝트 생성이 끝났다.
(+) PORT 번호 바꾸기
src/main.ts
import { NestFactory } from "@nestjs/core";
import { AppModule } from "./app.module";
async function bootstrap() {
const app = await NestFactory.create(AppModule);
const PORT = 9000;
await app.listen(PORT);
}
bootstrap();
$ npm i @nestjs/graphql @nestjs/apollo graphql apollo-server-express
Graphql Module 입력하기
import { Module } from "@nestjs/common";
import { GraphQLModule } from "@nestjs/graphql";
import { ApolloDriver, ApolloDriverConfig } from "@nestjs/apollo";
@Module({
imports: [
GraphQLModule.forRoot<ApolloDriverConfig>({
driver: ApolloDriver,
autoSchemaFile: "schema.gql"
})],
controllers: [],
providers: []
})
export class AppModule {
}
💡 모든 코드가 작성될때 까지 오류 코드 계속 뜸
import { Field, ID, ObjectType } from "@nestjs/graphql";
@ObjectType()
export class User {
@Field(() => ID)
uid: string;
@Field(() => String)
email: string;
@Field(() => String)
displayName: string;
@Field(() => String, { nullable: true })
photoURL: string;
@Field(() => String, { nullable: true })
intro: string;
@Field(() => String, { nullable: true })
date_crated: string;
@Field(() => String, { nullable: true })
access_token: string;
password: string;
}
@ArgsType()
@InputType()
export class UserInputType {
@IsEmail()
@Field()
email: string;
@Length(2, 8)
@Field()
displayName: string;
@Field({ nullable: true })
photoURL: string;
@Field({ nullable: true })
intro: string;
@Field()
password1: string;
@Field()
password2: string;
}
import { Query, Resolver, Args, Mutation } from "@nestjs/graphql";
import { User } from "../schemas/user.schema";
import { ApolloError } from "apollo-server-express";
@Resolver()
export class UsersResolver {
constructor() {
}
@Query(() => [User])
async findAll() {
try {
return [
{uid:"1", email:"apple@test.com", displayName:"돌아온애쁠"},
{uid:"2", email:"banan@test.com", displayName:"바나나반하나"}
]
} catch (e) {
throw new ApolloError(e);
}
}
}
import { Module } from "@nestjs/common";
import { UsersResolver } from "./users.resovler";
@Module({
providers: [UsersResolver] //추가
})
export class UsersModule {
}
import { Module } from "@nestjs/common";
import { GraphQLModule } from "@nestjs/graphql";
import { ApolloDriver, ApolloDriverConfig } from "@nestjs/apollo";
import { UsersModule } from './users/users.module';
@Module({
imports: [
GraphQLModule.forRoot<ApolloDriverConfig>({
driver: ApolloDriver,
autoSchemaFile: "schema.gql"
}),
UsersModule // 추가
],
controllers: [],
providers: []
})
export class AppModule {
}
웹브러우저
http://localhost:{PORT}/graphql
npm install --save mongoose
import * as mongoose from 'mongoose';
const database_name = "nest"
export const databaseProviders = [
{
provide: 'DATABASE_CONNECTION',
useFactory: (): Promise<typeof mongoose> =>
mongoose.connect(`mongodb://localhost/${database_name}`),
},
];
import { Module } from '@nestjs/common';
import { databaseProviders } from './database.providers';
@Module({
providers: [...databaseProviders],
exports: [...databaseProviders],
})
export class DatabaseModule {}
import { Field, ID, ObjectType, ArgsType, InputType } from "@nestjs/graphql";
import * as mongoose from "mongoose";
import { Document } from "mongoose";
// 추가
export const UserSchema = new mongoose.Schema({
_id: { type: mongoose.Schema.Types.ObjectId, auto: true },
displayName: String,
email: String,
photoURL: String,
password: String,
intro: String,
date_crated: String
});
@ObjectType()
export class User extends Document {
@Field(() => ID)
uid: string;
@Field(() => String)
email: string;
@Field(() => String)
displayName: string;
@Field(() => String, { nullable: true })
photoURL: string;
@Field(() => String, { nullable: true })
intro: string;
@Field(() => String, { nullable: true })
date_crated: string;
@Field(() => String, { nullable: true })
access_token: string;
password: string;
}
@ArgsType()
@InputType()
export class UserInputType {
@Field()
email: string;
@Field()
displayName: string;
@Field({ nullable: true })
photoURL: string;
@Field({ nullable: true })
intro: string;
@Field()
password: string;
}
import { Connection } from "mongoose";
import { UserSchema } from "../schemas/user.schema";
export const UsersProviders: any = [
{
provide: "USER_MODEL",
useFactory: (connection: Connection) => connection.model("User", UserSchema,'users'),
inject: ["DATABASE_CONNECTION"]
}
];
import { Injectable, Inject } from "@nestjs/common";
import { User, UserInputType } from "../schemas/user.schema";
import { Model } from "mongoose";
import { ApolloError } from "apollo-server-express";
@Injectable()
export class UsersService {
constructor(
@Inject("USER_MODEL")
private readonly userModel: Model<User>
) {
}
async findAll(): Promise<User[]> {
try {
return this.userModel.find().exec();
} catch (e) {
throw new ApolloError(e);
}
}
async createUser(user: UserInputType) {
try {
// CREATE DATA
const data = {
...user,
date_crated: new Date()
};
const result = await this.userModel.create(data);
return {
uid: result._id,
...data
};
} catch (e) {
throw new ApolloError(e);
}
}
}
import { Query, Resolver, Args, Mutation } from "@nestjs/graphql";
import { User, UserInputType } from "../schemas/user.schema";
import { UsersService } from "./users.service";
import { ApolloError } from "apollo-server-express";
@Resolver()
export class UsersResolver {
constructor(private usersService: UsersService) {
}
@Query(() => [User])
async findAll() {
try {
return await this.usersService.findAll();
} catch (e) {
throw new ApolloError(e);
}
}
@Mutation(() => User)
async createUser(@Args("input") user: UserInputType) {
try {
return await this.usersService.createUser(user);
} catch (e) {
throw new ApolloError(e);
}
}
}
import { Module } from "@nestjs/common";
import { UsersResolver } from "./users.resovler";
import {UsersService} from "./users.service";
import {UsersProviders} from "./users.providers";
import {DatabaseModule} from "../database.module";
@Module({
imports:[DatabaseModule],
providers: [UsersResolver,UsersService, ...UsersProviders],
exports: [UsersService]
})
export class UsersModule {
}
import { Module } from "@nestjs/common";
import { GraphQLModule } from "@nestjs/graphql";
import { ApolloDriver, ApolloDriverConfig } from "@nestjs/apollo";
import { UsersModule } from "./users/users.module";
@Module({
imports: [
GraphQLModule.forRoot<ApolloDriverConfig>({
driver: ApolloDriver,
autoSchemaFile: "schema.gql"
}),
UsersModule],
controllers: [],
providers: []
})
export class AppModule {
}
'nest' 데이터베이스에 user collection에 방금 작성한 유저 정보가 제대로 입력된 것을 볼 수 있다.
전체코드 보기 : github