일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 안드로이드 테스트
- Kotlin
- 자바기초
- flutter
- LinkedList
- 유니티
- java
- Design Pattern
- MVVM pattern
- graphQL
- ubuntu python
- Apollo GraphQL
- dagger-hilt
- Dependency Injection
- 파이썬 크롤링
- unit test
- Nexus GraphQL
- 우분투 파이썬
- 안드로이드 디자인패턴
- Android test
- Data structure
- 자바
- Apollo Server
- mvvm
- 안드로이드 mvp
- Android
- prisma
- 안드로이드
- PYTHON
- 웹크롤링
- Today
- Total
Hun's Blog
Nexus GraphQL tutorials (3) - Adding mutations to Your API 본문
Nexus GraphQL tutorials (3) - Adding mutations to Your API
jhk-im 2020. 12. 1. 15:53GraphQL을 개인 프로젝트에 적용하기위해 제대로 학습해보기 시리즈
해당 글은 Nexus 를 개인 프로젝트에 적용하고자 제대로 학습하기 위해 Nexus tutorial의 내용을 정리한 것입니다.
Nexus tutorial에도 상세하게 나와있음을 알려드립니다.
Adding mutations to Your API
Overview
- GraphQL mutation 작성.
- mutation에 대한 GraphQL 객체 노출
- GraphQL Context 사용
- GraphQL argument 사용
Wire up the context
먼저 메모리 내 데이터베이스를 설정하고 GraphQL context를 사용하여 resolver에 노출한다.
GraphQL context는 resolver 간에 공유되는 일반 JavaScript 객체이다.
GraphQL 서버는 각 요청에 대해 새로운 요청을 작성한다.
// api/db.ts
export interface Post {
id: number
title: string
body: string
published: boolean
}
export interface Db {
posts: Post[]
}
export const db: Db = {
posts: [{ id: 1, title: 'Nexus', body: '...', published: false }],
}
이제 GraphQL context에 노출하기 위해 2가지를 수행해야한다.
1. db객체를 GraphQL 서버 context에 전달
2. Nexus에 컨텍스트 타입이 무엇인지 알려준다.
// api/server.ts
import { ApolloServer } from 'apollo-server'
import { schema } from './schema'
import { db } from './db'
export const server = new ApolloServer({
schema,
context: () => ({
db
})
})
api/context.ts 파일을 만들어 GraphQL context 타입을 알 수 있도록 Nexus를 구성해보자.
// api/context.ts
import { Db } from './db'
export interface Context {
db: Db
}
마지막으로 api/schema.ts에서 @nexus/schema의 makeSchema 기능에 다음을 추가한다.
// api/schema.ts
import { join } from 'path'
export const schema = makeSchema({
types: [],
outputs: {
typegen: join(__dirname, '..', 'nexus-typegen.ts'),
schema: join(__dirname, '..', 'schema.graphql')
},
// 추가
typegenAutoConfig: {
sources: [
{
source: require.resolve("./context"), // 1
alias: "ContextModule", // 2
},
],
contextType: "ContextModule.Context", // 3
},
})
1. Nexus는 context.ts 파일을 추출하여 available 타입을 추출할 것이다.
2. 이러한 타입은 ContextModule alias를 사용할 수 있게 된다.
3. 그 다음 정의된 모든 타입을 참조하기 위하여 alias를 사용할 수 있다.
Use the context
이제 이전 Query.draft resolver를 다시 구현해 보자.
// api/graphql/Post.ts
export const PostQuery = queryType({
definition(t) {
t.list.field('drafts', {
type: Post,
resolve(_root, _args, ctx) { // 1
return ctx.db.posts.filter(p => p.published === false) // 2
},
})
},
})
1. Context는 세번째 parameter로 일반적으로 ctx로 식별된다.
2. 필터링된 데이터는 draft로 반환. Nexus가 타입이 정렬되도록 한다.
Your first mutation
Mutation은 root type이며 진입점이다.
Mutation filed와 객체를 결합하거나 모든 mutation fileds를 중앙으로 모을 수 있다.
// api/graphql/Post.ts
// ...
export const PostMutation = extendType({
type: 'Mutation',
definition(t) {
t.nonNull.field('createDraft', {
type: Post,
resolve(_root, args, ctx) {
ctx.db.posts.push(/*...*/)
return // ...
},
})
},
})
resolver를 완성하려면 클라이언트의 입력 데이터가 필요하다. 여기서 GraphQL의 arguments를 가져온다.
GraphQL의 모든 필드는 해당 필드를 수용할 수 있다.
GraphQL의 각 필드를 함수처럼 생각하고 일부 입력을받고 무엇인가를 수행하고 출력을 반환할 수 있다.
Mutation 필드 내에서 무엇인가를 수행하는 것은 부작용을 수반한다.
GraphQL arguments를 사용해 수정해보자.
import { extendType, stringArg } from '@nexus/schema'
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
},
})
},
})
1. args 속성을 추가하여 정의한다. 값은 타입의 사양이다.
2. arg 타입을 정의할 때 Nexus의 helper를 사용하자. GraphQL scala에는 intArg, booleanArg와 같은 helper 있다.
만약 InputObject와 같은 타입을 참조하려면 type: "..." 을 사용한다.
null 및 nullable helper를 사용하여 nullability를 조정할 수 있다.
list를 활용하여 arg를 list 타입으로 만들수도 있다.
3. Resolver에서는 위에서 지정한 arg에 접근하여 custom logic 으로 전달.
args위에 마우스를 올려놓으면 제대로 입력되었는지 알수있다.
Model the domain: Part 2
마무리하기 전에 publish mutation을 추가하여 draft를 실제 발행 된 게시물로 바꿔보자.
// api/graphql/Post.ts
import { extendType, intArg, stringArg } from '@nexus/schema'
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
},
})
},
})
그런 후 API 클라이언트에서 해당 게시물을 읽을 수 있도록 할 것이다.
// api/graphql/Post.ts
import { extendType } from '@nexus/schema'
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)
},
})
},
})
Try it out
mutation {
publish(draftId: 1) {
id
title
body
published
}
}
{
"data": {
"publish": {
"id": 1,
"title": "Nexus",
"body": "...",
"published": true
}
}
}
query {
posts {
id
title
body
published
}
}
{
"data": {
"posts": [
{
"id": 1,
"title": "Nexus",
"body": "...",
"published": true
}
]
}
}
'Backend > GraphQL' 카테고리의 다른 글
Nexus GraphQL tutorials (5) - Persisting data (via Prisma) (0) | 2020.12.07 |
---|---|
Nexus GraphQL tutorials (4) - Testing your API (0) | 2020.12.07 |
Nexus GraphQL tutorials (2) - Schema란? / Writing your first schema (0) | 2020.11.30 |
Nexus GraphQL tutorials (1) - GraphQL이란? / setup and first query (0) | 2020.11.29 |
Introducing Major improvements to Prisma v2.6.0 (0) | 2020.11.25 |