iT邦幫忙

2022 iThome 鐵人賽

DAY 27
0
Modern Web

Full Stack Web Development 網站實作系列 第 27

Day27 GraphQL(6) - Apollo Server - Gúa ê Tâi-gí chheh tô͘-su-koán(我的台語冊圖書館) app(3)

  • 分享至 

  • xImage
  •  

繼續修改程式:
(1)列出每一位作者的所有著作。
(2)列出每一本書的作者的明細資料。

目前我們的 schema 有兩個 object types:Author 和 Book。

const typeDefs = gql`
    type Author {
      name: String!     // 驚嘆號表示欄位不可空白
      id: ID!
      born: String
      books:[Book]  // 放作者寫的書
    }

    type Book {
      title: String!
      published: String!
      author: Author   // 欄位型態為 Author 型態
      id: ID!
      genres: [String!]!
    }

    type Query {
      bookCount: Int!
      authorCount: Int!
      allBooks: [Book!]!    // query 書名時,會收到一個陣列(array) 的 Book objects
      allAuthors: [Author]
    }
  `

透過 Author 的 name 欄位,和 Book 的 author 欄位,可以將這兩個資料集鏈結起來。
Data sets 的詳細內容在 Day25

我們的 resolvers 有四個函數(functions):

const resolvers = {
    Query: {
      bookCount: () => books.length,   // 傳回書籍數目
      authorCount: () => authors.length,  // 傳回作者數目
      allBooks: () => books,     // 傳回書籍的資料集(data set) 
      allAuthors: () => authors,  // 傳回作者的資料集(data set)
     },
};

要 query 作者所有的著作 需要再增加 resolver function。

const resolvers = {
    Query: {
      bookCount: () => books.length,   // 傳回書籍數目
      ...
    },
    Book: {
      // 傳回 author 欄位的來源資料  下圖一
      author(parent) => console.log(parent);
    },
    Author: {
      // 傳回 books 欄位的來源資料  下圖二
      books(parent) => console.log(parent);
    },
};

執行下面 query,也會得到圖一結果,來源object -- author

query {
  allAuthors {
    name
    books {
      name
    }
  }
}

圖一
https://ithelp.ithome.com.tw/upload/images/20221012/20129584Yg0Ch6myUi.png
圖二
https://ithelp.ithome.com.tw/upload/images/20221012/20129584tFcPtIb1Ti.png

接下來,修改程式如下:

    Book: {
      // 找作者 name 和書籍 author 相同者,並傳回
      author(parent) {
        return authors.find((author) => author.name === parent.author);
      },
    },

    Author: {
      // 列出書籍 author 和 作者 name 相同的圖書,並傳回
      books(parent) {
       return books.filter((book) => book.author === parent.name);
      },
    },

https://ithelp.ithome.com.tw/upload/images/20221012/20129584NAXxVLrsQA.png

只查詢單一作者或單一圖書
修改程式如下:

...
    type Query {
      bookCount: Int!
      ...
      findBook(title: String!) : Book
      findAuthor(name: String!) : Author
    }
  `
const resolvers = {
    Query: {
      bookCount: () => books.length,
      ...
      findBook(parent, args, context, info) {
        console.log(args);
      },
      findAuthor(parent, args, context, info) {
        console.log(args);
      }
     },

當我們執行

query {
  findBook(title : "日臺大辭典(上冊)"){
    title
  }
}

會得到的 args,是 { title: '日臺大辭典(上冊)' }。確定得到 args 後,可以用 args 參數,去取得單一作者或單一圖書的資料了。
修改程式如下:

      findBook(parent, args, context, info) {
        return books.find((book) => book.title === args.title);
      },
      findAuthor(parent, args, context, info) {
        return authors.find((author) => author.name === args.name);
      }

查詢單一書籍:

query {
  findBook(title: "新撰註解日台會話獨修"){
    title
    published  
  }
}

查詢單一作者:

query {
  findAuthor(name: "小川尚義"){
    name
    born
  }
}

在 schemas 裡,我們定義 Book 的作者型態是 Author,而 Author 又有他自己的欄位,所以,我們查詢到一本書後,可以鏈結到作者資料。

query {
  findBook(title: "新撰註解日台會話獨修"){
    title
    published 
    author {
      name
      born
    }
  }
}

同樣的,以作者鏈結到圖書明細。

query {
  findAuthor(name: "小川尚義"){
    name
    born
    books{
      title
    }
  }
}

上一篇
Day 26 GraphQL(5) - Apollo Server - Gúa ê Tâi-gí chheh tô͘-su-koán(我的台語冊圖書館) app(2)
下一篇
Day 28 GraphQL(7) - Apollo Server -Mutation - Gúa ê Tâi-gí chheh tô͘-su-koán(我的台語冊圖書館) app(4)
系列文
Full Stack Web Development 網站實作30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言