설정
typescript 기반 프로젝트를 생성한다.
1 |
npx typeorm init --name hero-ql --database mysql |
ormconfig.json 화일에 데이터베이스 관련 정보를 수정한다.
엔티티 설정
entity 폴더 아래에 hero 엔티티 생성
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
@Entity() export class Hero { @PrimaryGeneratedColumn() id: number; @Column() name: string; @Column() email: string; @Column({nullable: true}) sex: string; @Column({nullable: true}) country: string; @Column({nullable: true}) address: string; @CreateDateColumn() created: Date; @UpdateDateColumn() updated: Date; @OneToMany(type => Power, power => power.hero) powers: Power[]; } |
power 엔티티 생성. hero와 power는 one to many 관계를 가진다.
1 2 3 4 5 6 7 8 9 10 11 |
@Entity() export class Power { @PrimaryGeneratedColumn() id: number; @Column() name: string; @ManyToOne(type => Hero, hero => hero.powers) hero: Hero; } |
테스트 데이터 생성
index.ts에 데이터를 생성하여 테스트한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
createConnection().then(async connection => { console.log("Inserting a new hero into the database..."); let power1 = new Power(); power1.name = "strength"; await connection.manager.save(power1); let power2 = new Power(); power2.name = "flying"; await connection.manager.save(power2); const hero = new Hero(); hero.name = "Superman"; hero.email = "superman@gmail.com"; hero.sex = "male"; hero.powers= [power1, power2]; await connection.manager.save(hero); const findHero = await connection.manager.find(Hero); console.log("Loaded findHero: ", findHero); console.log("Here you can setup and run express/koa/any other framework."); }).catch(error => console.log(error)); |
graphql 설정
graphql 라이브러리 설치. merge-graphql-schemas 는 모듈화를 위해서 필요
1 |
yarn add graphql graphql-yoga merge-graphql-schemas |
graphql plugin 설치
IDEA settings에서 plugin 으로 들어가서 marketplace 에서 graphql 플러그인을 찾아서 설치한다.

graphql 서버 세팅
Database 연동없이 graphql 서버를 구동한다. typeDef, resolver는 모듈화를 한다.
typeDef 폴더를 만들고 아래에 index.ts hero.graphqls 파일을 차례대로 만든다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
type Hero { id: Int! name: String! email: String sex: String country: String address: String created: String updated: String powers: [Power] } input InputHero { name: String! email: String sex: String country: String address: String } type Power { id: Int! name: String! } input InputPower { name: String } type Query { hero(id: Int): Hero heroes(start_index: Int, page_size: Int): [Hero] } type Mutation { addHero(hero: InputHero, powers: [InputPower]): Hero } |
1 2 3 4 5 6 7 |
import * as path from "path"; import { fileLoader, mergeTypes } from "merge-graphql-schemas"; const typesArray = fileLoader(path.join(__dirname, "./")); const typesMerged = mergeTypes(typesArray); export default typesMerged; |
resolver 폴더를 생성하고 index.ts와 hero.resoler.ts를 생성한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
export default { Query: { hero: async (_, {id}) => { return { id: 1, name: 'aaa', email: 'aaa@a.com' } }, heroes: async (_, args) => { return [ { id: 1, name: 'aaa', email: 'aaa@a.com' }, { id: 2, name: 'bbb', email: 'bbb@a.com' } ] } } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 |
import * as path from 'path' import { fileLoader } from 'merge-graphql-schemas' /* MANUAL APPROACH: Update this file manually with each resolver file */ // import userResolvers from "./user.resolvers"; // import welcomeResolvers from "./welcome.resolvers"; // const resolversArray = [userResolvers, welcomeResolvers]; /* AUTOMATED APPROACH: Put your resolvers anywhere with ".resolvers.[js/ts]" naming convention */ const resolvers = fileLoader(path.join(__dirname, './**/*.resolver.*')) export default resolvers |
graphql Server 를 index.ts 맨아래에서 구동한다.
1 2 3 4 5 6 7 8 9 10 11 12 |
... console.log("Here you can setup and run express/koa/any other framework."); // start GraphQL Server const options = { port: 4000 }; const server = new GraphQLServer({ typeDefs, resolvers, }) server.start(options) .then(() => console.log(`Server is running on localhost:${options.port}`)); |