Closed lotstar87 closed 4 years ago
적용결과 type이 중복해서 적용된다는 오류가 발생 (Schema must contain uniquely named types but contains multiple types named XXX)
write graphql types
import gql from 'graphql-tag'
export const Domain = gql`
type Domain {
id: String
name: String
description: String
timezone: String
systemFlag: Boolean
subdomain: String
brandName: String
brandImage: String
contentImage: String
theme: String
createdAt: String
updatedAt: String
}
`
write resolvers in separate file.
// domain.ts
import { getRepository } from 'typeorm'
import { Domain } from '../../../entities'
export const domainResolver = {
async domain(_, { name }: Record<string, string>, context, info): Promise<Domain> {
const repository = getRepository(Domain)
return await repository.findOne({ name })
}
}
// domains.ts
import { Context } from 'koa'
import { getRepository } from 'typeorm'
import { Domain } from '../../../entities'
import { buildQuery } from '../../list-query-builder'
import { DomainList } from '../../types/domain/domain-list'
import { ListParam } from '../../types/list-param'
export const domainsResolver = {
async domains(_: any, params: ListParam, context: Context): Promise<DomainList> {
const queryBuilder = getRepository(Domain).createQueryBuilder()
buildQuery(queryBuilder, params, context, false)
const [items, total] = await queryBuilder.getManyAndCount()
return { items, total }
}
}
// create-domain.ts
import { getRepository } from 'typeorm'
import { Domain } from '../../../entities'
export const createDomain = {
async createDomain(_: any, { domain }: any): Promise<Domain> {
return await getRepository(Domain).save(domain)
}
}
// update-domain.ts
import { getRepository } from 'typeorm'
import { Domain } from '../../../entities/domain'
import { DomainPatch } from '../../types/domain/domain-patch'
type UpdateDomainInput = {
name: string
patch: DomainPatch
}
export const updateDomain = {
async updateDomain(_: any, { name, patch }: UpdateDomainInput) {
const repository = getRepository(Domain)
const domain = await repository.findOne({ name })
return await repository.save({
...domain,
...patch
})
}
}
// delete-domain.ts
import { DeleteResult, getRepository } from 'typeorm'
import { Domain } from '../../../entities/domain'
export const deleteDomain = {
async deleteDomain(_: any, { name }: Record<string, string>): Promise<DeleteResult> {
return await getRepository(Domain).delete({ name })
}
}
write the graphql SDL for queries, mutations, subscriptions and export it
import { Domain } from './domain'
import { NewDomain } from './new-domain'
import { DomainPatch } from './domain-patch'
import { DomainList } from './domain-list'
export const Mutation = /* GraphQL */ `
createDomain (
domain: NewDomain!
): Domain
updateDomain (
name: String!
patch: DomainPatch!
): Domain
deleteDomain (
name: String!
): Domain
`
export const Query = /* GraphQL */ `
domains(filters: [Filter], pagination: Pagination, sortings: [Sorting]): DomainList
domain(name: String!): Domain
`
export const Types = [Domain, NewDomain, DomainPatch, DomainList]
export resolvers
import * as Domain from './domain'
export const queries = [Domain.Query]
export const mutations = [Domain.Mutation]
export const subscriptions = []
add decorator for type-graphql in entity
// domain.ts
import { Field, ID, ObjectType } from 'type-graphql'
import { Column, CreateDateColumn, Entity, Index, PrimaryGeneratedColumn, UpdateDateColumn } from 'typeorm'
@ObjectType('Domain')
@Entity('domains')
@Index('ix_domain_0', (domain: Domain) => [domain.name], { unique: true })
@Index('ix_domain_1', (domain: Domain) => [domain.subdomain])
@Index('ix_domain_2', (domain: Domain) => [domain.systemFlag])
export class Domain {
@Field(type => ID)
@PrimaryGeneratedColumn('uuid')
id: string
@Field()
@Column({ unique: true })
name: string
@Field({ nullable: true })
@Column({ nullable: true })
description?: string
@Field({ nullable: true })
@Column({ nullable: true })
timezone?: string
@Field({ defaultValue: false })
@Column({ default: false })
systemFlag: boolean
@Field({ nullable: true })
@Column({ nullable: true })
subdomain?: string
@Field({ nullable: true })
@Column({ nullable: true })
brandName?: string
@Field({ nullable: true })
@Column({ nullable: true })
brandImage?: string
@Column({ nullable: true })
contentImage?: string
@Field({ nullable: true })
@Column({ nullable: true })
theme?: string
@Field()
@CreateDateColumn()
createdAt: Date
@Field()
@UpdateDateColumn()
updatedAt: Date
}
write resolver
import { Context } from 'koa'
import { Arg, Args, Ctx, Mutation, Query, Resolver } from 'type-graphql'
import { Repository } from 'typeorm'
import { InjectRepository } from 'typeorm-typedi-extensions'
import { Domain } from '../../entities'
import { buildQuery } from '../list-query-builder'
import { CreateDomainInput } from '../types/domain/create-domain-input'
import { DomainList } from '../types/domain/domain-list'
import { UpdateDomainInput } from '../types/domain/domain-patch'
import { ListParam } from '../types/list-param'
@Resolver(Domain)
export class DomainResolver {
constructor(@InjectRepository(Domain) private readonly domainRepository: Repository<Domain>) {}
@Query(returns => Domain)
async domain(@Arg('name') name: string) {
return this.domainRepository.findOne({ name })
}
@Query(returns => DomainList)
async domains(@Args() params: ListParam, @Ctx() context: Context & Record<string, any>) {
const queryBuilder = this.domainRepository.createQueryBuilder()
buildQuery(queryBuilder, params, context, false)
const [items, total] = await queryBuilder.getManyAndCount()
return { items, total }
}
@Mutation(returns => Domain)
async createDomain(@Arg('domain') domain: CreateDomainInput) {
return this.domainRepository.save(domain)
}
@Mutation(returns => Boolean)
async deleteDomain(@Arg('name') name: string) {
return this.domainRepository.delete({ name })
}
@Mutation(returns => Domain)
async updateDomain(@Args() { name, patch }: UpdateDomainInput) {
const repository = this.domainRepository
const domain = await repository.findOne({ name })
return await repository.save({
...domain,
...patch
})
}
}
import { DomainResolver } from './domain.resolver'
export default [DomainResolver]
graphql의 type을 typescript의 type으로 사용할 수 있게 하기위해, type-graphql를 적용