點燈坊

失くすものさえない今が強くなるチャンスよ

使用 Apollo GraphQL 建立 Fragment

Sam Xiao's Avatar 2019-12-22

實務上可能會遇到多個 GraphQL Query 卻有相同的 Field,此時可將相同 Field 宣告成 Fragment 共用。

Version

macOS Catalina 10.15.2
WebStorm 2019.3.1
Node 12.14.0
Apollo GraphQL 2.9.14

Apollo GraphQL

Schema

/src/schema/query.graphql

type Query {
  books: [Book]
}

type Book {
  title: String
  price: Int
  quantity: Int
}

query.graphql 定義 books query 與 Book type。

Resolver

/src/resolvers.js

let data = [
  { title: 'FP in JavaScript', price: 100, quantity: 10 },
  { title: 'RxJS in Action', price: 200, quantity: 20 },
  { title: 'Speaking JavaScript', price: 300, quantity: 30 }
]

let books = () => data

export let resolvers = {
  Query: {
    books
  }
}

resolvers.js 實作 books query。

Main

src/index.js

import { ApolloServer } from 'apollo-server'
import typeDefs from './schema/query.graphql'
import { resolvers } from './resolvers'

new ApolloServer({ typeDefs, resolvers })
  .listen()
  .then(({ url }) => `GraphQL Server ready at ${ url }`)
  .then(console.log)

index.js 引入 schema 與 resolver,並啟動 Apollo GraphQL。

GraphQL Playground

query {
  books {
    title
    price
    quantity
  }
}

使用 books query,且回傳 titlepricequantity 3 個 field。

fragment000

query {
  books {
    ...bookFields
  }
}

fragment bookFields on Book {
  title
  price
  quantity
}

titlepricequantity 3 個 field 在其他 query 也使用,可使用 fragment 將這些 field 宣告成 fragment,on 後面接 type。

之後在 query 可使用類似 ES6 的 ... spread operator 將其展開,如此多個 query 都可共用該 fragment。

fragment001

Conclusion

  • 透過 fragment 可解決各 query 間 field 重複問題,且語法非常優雅

Reference

Eve Porcello, Reuse GraphQL Selection Sets with Fragments