api 에 mutation 추가하기
mutation 이란
Mutation 은 데이터베이스 상태가 변할 때 사용되는 것이다.
mutation 을 설정하는 context 와 입력 받는 인자와 같은 arg 에 대해서 배워볼 것이다.
- Writing GraphQL mutations
- Exposing GraphQL objects for mutation operations
- Working with GraphQL Context
- Working with GraphQL arguments
context 연결
https://nexusjs.org/docs/getting-started/tutorial/chapter-adding-mutations-to-your-api/
이 부분은 자세한 방법은 생략.
// api/server.ts
import { ApolloServer } from 'apollo-server'
import { context } from './context'
import { schema } from './schema'
export const server = new ApolloServer({
schema,
context // 추가
})
// api/schema.ts
import { makeSchema } from 'nexus'
import { join } from 'path'
import * as types from './graphql'
export const schema = makeSchema({
types,
outputs: {
typegen: join(__dirname, '..', 'nexus-typegen.ts'),
schema: join(__dirname, '..', 'schema.graphql')
},
contextType: { // 1
module: join(__dirname, "./context.ts"), // 2
export: "Context", // 3
},
})
- 컨텍스트 유형을 설정하는 옵션
- 컨텍스트 유형을 내보낸 모듈의 경로
- 해당 모듈의 내보내기 이름
context 사용
이제 이 데이터를 이렇게 바꿔보자.
예전
// api/graphql/Post.ts
export const PostQuery = extendType({
type: 'Query',
definition(t) {
t.list.field('drafts', {
type: 'Post',
resolve() {
return [{ id: 1, title: 'Nexus', body: '...', published: false }]
},
})
},
})
현재
// api/graphql/Post.ts
export const PostQuery = extendType({
type: 'Query',
definition(t) {
t.list.field('drafts', {
type: 'Post',
resolve(_root, _args, ctx) { // 1
return ctx.db.posts.filter(p => p.published === false) // 2
},
})
},
})
- context 는 일반적으로 다음과 같이 식별되는 세 번째 매개변수입니다. -> ctx
- 반환 : unpubliched 된 post -> draft.
첫번째 mutation
자, 이제 컨텍스트에 연결하는 방법을 알았으므로 첫 번째 mutation를 구현해 보겠다. API 클라이언트가 새 drafts 을 만들 수 있도록 하겠다.
이 mutation 은 이름이 필요하다.
createPost 라고 하자.
리졸버를 완료하려면 클라이언트의 입력 데이터를 가져와야 한다.
이것은 우리에게 새로운 개념인 GraphQL args 를 제공한다. GraphQL의 모든 필드는 이를 받아들일 수 있다.
효과적으로 GraphQL의 각 필드를 함수처럼 생각할 수 있다.
일부 입력을 수락하고, 무언가를 수행하고, 출력을 반환한다.
대부분의 경우 "무언가 수행"은 읽기와 유사한 작업의 문제이지만... Mutation필드에서 "무언가 수행"은 일반적으로 부작용이 있는 프로세스(예: 데이터베이스에 쓰기)를 수반한다.
GraphQL args 로 구현을 수정해 보겠다.
import { objectType, extendType } from 'nexus'
import { objectType, extendType, stringArg, nonNull } from 'nexus'
export const PostMutation = extendType({
type: 'Mutation',
definition(t) {
t.nonNull.field('createDraft', {
type: 'Post',
args: { // 1
title: nonNull(stringArg()), // 2
body: nonNull(stringArg()), // 2
},
resolve(_root, args, ctx) {
const draft = {
id: ctx.db.posts.length + 1,
title: args.title, // 3
body: args.body, // 3
published: false,
}
ctx.db.posts.push(draft)
return draft
},
})
},
})
- args필드 정의에 속성을 추가하여 해당 인수를 정의합니다. 키는 인수 이름이고 값은 type 사양입니다.
- arg 유형을 정의하기 위해 Nexus 헬퍼를 사용하십시오. intArg및 와 같은 모든 GraphQL 스칼라에 대해 이러한 도우미가 하나 있습니다 booleanArg. 일부 InputObject와 같은 유형을 참조하려면 arg({ type: "..." }). 도우미를 사용 nonNull하고 nullable -> arg의 null 허용 여부 유형을 조정할 수 있습니다. 기능적 도우미 list를 사용하여 arg를 목록 유형으로 바꿀 수도 있습니다.
- 리졸버에서 위에서 지정한 args에 액세스하고 사용자 지정 논리에 전달합니다. 매개변수 위로 마우스를 가져가면 정의되지 않을 수 있다는 사실을 포함하여 Nexus가 올바르게 입력한 것을 볼 수 있습니다.
Mutation {
createDraft(title: String!, body: String!): Post!
}
클라이언트가 title 과 body 를 입력하면 draft 가 추가 된다.
도메인 모델링 2부
이 장을 마무리하기 전에 스키마를 좀 더 플러시하겠습니다. publish mutation 을 추가해보겠다.
초안을 실제 게시된 게시물로 변환하는 mutation 을 추가한다
import { objectType, extendType, stringArg, nonNull, intArg } from 'nexus'
export const PostMutation = extendType({
type: 'Mutation',
definition(t) {
// ...
t.field('publish', {
type: 'Post',
args: {
draftId: nonNull(intArg()),
},
resolve(_root, args, ctx) {
let draftToPublish = ctx.db.posts.find(p => p.id === args.draftId)
if (!draftToPublish) {
throw new Error('Could not find draft with id ' + args.draftId)
}
draftToPublish.published = true
return draftToPublish
},
})
},
})
type Mutation {
createDraft(body: String!, title: String!): Post!
publish(draftId: Int!): Post // 추가
}
Then, we'll let API clients read these published posts.
// api/graphql/Post.ts
import { extendType } from 'nexus'
export const PostQuery = extendType({
type: 'Query',
definition(t) {
// ...
t.list.field('posts', {
type: 'Post',
resolve(_root, _args, ctx) {
return ctx.db.posts.filter(p => p.published === true)
},
})
},
})
type Query {
drafts: [Post]!
posts: [Post] // 추가
}
사용해보기
좋습니다. 이제 GraphQL Playground로 이동하여 이 쿼리를 실행합니다(왼쪽). 모든 것이 잘 되었다면 다음과 같은 응답이 표시되어야 합니다(오른쪽).
posts이제 게시된 초안이 쿼리 를 통해 표시되어야 한다 . 이 쿼리를 실행하고(왼쪽) 다음 응답을 기대하세요(오른쪽).
'🌸 GraphQL' 카테고리의 다른 글
useQuery, useLazyQuery (공식 문서 참고) (1) | 2022.03.08 |
---|---|
데이터 유지를 prisma 를 통해 하자 (CRUD) (0) | 2022.02.28 |
nexus 이해하기2 (공식문서 참고) (0) | 2022.02.26 |
nexus 이해하기1 (공식문서 참고) (0) | 2022.02.26 |
GraphQL 로 영화 API 만들기(4) (0) | 2022.02.09 |