autoSchmaFile
지정: path or memorytypePaths
지정: SDL files pathts-node generate-typings
: TS 클래스 생성 가능@ObjectType
@ObjectType({description: 'Author Model'})
export class Author {
@Field(type => Int)
id: number;
@Field({nullable: true})
firstName?: string;
@Field({nullable: true)}
lastName?: string;
@Field(tpye => [Post])
posts: Post[];
}
@Field
number
→ Int
or Float
nullable
nullable: ‘items’
nullable: ‘itemsAndList’
description
deprecationReason
SDL: Schema Definition Language
type Author {
id: Int!
firstName: String
lastName: String
posts: [Post]
}
@Resolver
@ResolveField
가 포함될 때마다 필요@Resolver(of => Author)
export class AuthorsResolver {
constructor(
private authorsService: AuthorsService,
private postsService: PostsService,
) {}
@Query(returns => Author)
async author(@Args('id', { type: () => Int }) id: number) {
return this.authorsService.findOneById(id);
}
@ResolveField()
async posts(@Parent() author: Author) {
const { id } = author;
return this.postsService.findAll({ authorId: id });
}
@Mutation(returns => Post)
async upvotePost(@Args({ name: 'postId', type: () => Int }) postId: number) {
return this.postsService.upvoteById({ id: postId });
}
@Subscription(returns => Comment)
commentAdded() {
return pubSub.asyncIterator('commentAdded');
}
}
// SDL schema
type Query {
author(id: Int!): Author
}
type Mutation {
upvotePost(postId: Int!): Post
}
type Subscription {
commentAdded(): Comment!
}
@Query
get
, find
와 같은 네이밍 지양name
: 쿼리 유형이름 별도 설정 가능@Query({ name: ‘author’ })
description
deprecationReason
nullable
@Mutation
@InputType
입력 유형 선언@InputType()
export class UpvotePostInput {
@Field()
postId: number;
}
@Mutation(returns => Post)
async upvotePost(
@Args('upvotePostData') upvotePostData: UpvotePostInput,
) {}
@Subscription
installSubscriptionHandlers: true
Pubsub
인스턴스화Pubsub
provider 정의 및 생성자를 통한 삽입Pubsub#asyncIterator
: 이벤트에 대한 구독 처리triggerName
filter
: 특정 이벤트 필터링@Subscription(returns => Comment, {
filter: (payload, variables) =>
payload.commentAdded.title === variables.title,
})
commentAdded(@Args('title') title: string) {
return pubSub.asyncIterator('commentAdded');
}
Pubsub#publish
: 이벤트 게시
- 매개변수: triggerName
, eventPayload
- 이벤트 페이로드 모양이 구독에서 반환되는 값의 모양과 일치해야 함
- 클라이언트 측 업데이트를 트리거하기 위해 뮤테이션내에서 자주 사용
@Mutation(returns => Post)
async addComment(
@Args('postId', { type: () => Int }) postId: number,
@Args('comment', { type: () => Comment }) comment: CommentInput,
) {
const newComment = this.commentsService.addComment({ id: postId, comment });
pubSub.publish('commentAdded', { commentAdded: newComment });
return newComment;
}
resolve
: 게시된 이벤트 페이로드 변경
@Args
@Args() args: GetAuthorArgs
// get-author.args.ts
@ArgsType()
class GetAuthorArgs {
@Field({ nullable: true })
firstName?: string;
@Field({ defaultValue: '' })
@MinLength(3)
lastName: string;
}
type
: TS 유형에서 예상되는 GraphQL 유형이 없는 경우 명시적 전달@Args('id', { type: () => Int }) id: number)
defaultValue
description
deprecationReason
nullable
@ResolveField
@Parent
부모 객체 정의 필요ID
Int
Float
GraphQLISODateTime
GraphQLTimestamp
@Scalar
사용자 지정 스칼라
provider로 등록 필요
@Scalar('Date', (type) => Date)
export class DateScalar implements CustomScalar<number, Date> {
description = 'Date custom scalar type';
parseValue(value: number): Date {
return new Date(value); // value from the client
}
serialize(value: Date): number {
return value.getTime(); // value sent to the client
}
parseLiteral(ast: ValueNode): Date {
if (ast.kind === Kind.INT) {
return new Date(ast.value);
}
return null;
}
}
@include(if: Boolean)
@skip(if: Boolean)
@deprecated(reason: String)
SchemaDirectiveVisitor
클래스를 확장하는 클래스 선언export class UpperCaseDirective extends SchemaDirectiveVisitor {
visitFieldDefinition(field: GraphQLField<any, any>) {
const { resolve = defaultFieldResolver } = field;
field.resolve = async function(...args) {
const result = await resolve.apply(this, args);
if (typeof result === 'string') {
return result.toUpperCase();
}
return result;
};
}
}
GraphQLModule.forRoot({
// ...
schemaDirectives: {
upper: UpperCaseDirective,
},
});
@Directive('@deprecated(reason: "This query will be removed in the next version")')
@Query(returns => Author, { name: 'author' })
async getAuthor(@Args({ name: 'id', type: () => Int }) id: number) {
return this.authorsService.findOneById(id);
}
directive @upper on FIELD_DEFINITION
type Post {
id: Int!
title: String! @upper
votes: Int
}
@InterfaceType()
으로 정의@InterfaceType()
export abstract class Character {
@Field(type => ID)
id: string;
@Field()
name: string;
}
// 인터페이스 구현
@ObjectType({
implements: () => [Character],
})
export class Human implements Character {
id: string;
name: string;
}