使用GraphQL查詢引數來設計強大的API

yzf01發表於2021-09-09
原文出處                          

           

GraphQL API 設計的學習與最佳實踐

GraphQL 查詢提供了一種有效的方式來獲取資料,甚至可以跨越多種語言。這使得資料層上有很好的抽象層,但有時候需要更多,來滿足現代應用程式對特殊資料的需求。

我們的 GraphQL API 透過暴露不同的請求引數,來讓客戶端控制資料,並給予開發者更好的體驗(DX)。類似於我們的,這也被越來越多的公司採用。我們 Graphcool 很高興可以在 GraphQL 社群分享這一強大的最佳設計實踐 GraphQL API。

本文探討了我們的部分 GraphQL API 功能,包含:

  • 過濾:透過用一個或多個匹配規則來過濾節點。

  • 排序:由一個欄位來升序或降序集合。

  • 分頁:在不同的頁面中組合查詢到的節點,包括前進或者向後查詢。

過濾可以降低客戶端的複雜度

你通常會想要查詢資料的特殊部分。以一部電影的資料庫為例子,你可能會查詢在某個特定日子後的電影或者是有特別名字的。當然你總是可以查詢所有的電影,並在客戶端側過濾他們,而這會導致不必要的資料--這是 GraphQL 可以避免的。

這是個使用 GraphQL 的好例子 !透過新增 filter 引數到查詢裡面,以上場景可以被迅速解決。如果你想要名稱是《黑暗騎士》 的電影,你只需要在 filters 裡面指定 title 欄位就好了:

query darkKnightMovie {
  allMovies(filter: {
    title: "The Dark Knight"
  }) {
    releaseDate
  }
}

透過名稱過濾可以有效的獲取單個電影。實際上,過濾系統比這還要更加強大,因為它編碼 。透過邏輯操作可以有更高層次的表現。

你可以在過濾條件中結合 ORAND 操作,來選擇多部你感興趣的電影。例如,如果你想要查詢電影《盜夢空間》以及2009年後釋出的名稱是《黑暗騎士》的電影,你可以用 OR 來結合這兩個查詢條件。

query combineMovies {  allMovies(filter: {    OR: [{      AND: [{        releaseDate_gte: "2009"
      }, {        title_starts_with: "The Dark Knight"
      }]
    }, {      title: "Inception"
    }]
  }) {    title
    releaseDate
  }
}

在資料需求上,透過提供 filter 查詢引數,服務端做著繁重的工作,同時客戶端保持完全的控制。這就生成了清晰並且有表象的 API ,並分離前後端之間的顧慮。

表達甚至更加複雜的資料需求

一個經典的需求就是資料排序 - 這又是透過服務端要比客戶端好的地方。讓我們結合資料排序和過濾器。

這次我們想要2009年後釋出的電影的演員。filter 引數對這類請求有著強大系統。我們可以用 movies_some 並巢狀  releaseDate_gte:2009,這個含義是我們想要的演員,其飾演的_部分_電影能夠滿足巢狀條件。

最重要的是,我們透過 orderBy: name_ASC 欄位來排序。

query actorsAfter2009 {
  allActors(    filter: {      movies_some: {        releaseDate_gte: "2009"
      }
    }    first: 3    orderBy: name_ASC
  ) {
    name    movies {
      title
    }
  }
}

像這樣結合過濾器和排序引數,可以讓你簡單的表達甚至更加複雜的資料請求。我們也可以用 movies_none 或者 movies_all 來表示查詢的演員的所有電影_沒有_或者_全部_滿足的這些條件。

如果你仔細看,還會在上面的查詢中發現 first: 3 引數。讓我們看看這是什麼

在相同規格的頁面上瀏覽資料

想象一下一個羅列電影及其演員的網站。你的資料可能包含數千部電影,每部都包含很多演員。一個典型的場景是一次只展示幾部電影,並允許使用者向前或向後查詢瀏覽整個電影列表。

在這裡,你可以在查詢中映象表示引數,只獲取現在需要的資料,來替代一次性獲取所有資料的做法。這再次大大地簡化客戶端需要的邏輯,並且減少需要傳送的資料。這種方式也叫做offset-base pagination。一個甚至更先進的分頁變種叫做 cursor-based pagination,這也是透過結合 firstafter 或者 lastbefore 來實現的。這裡我們將重點關注偏移分頁。

翻頁引數與過濾器和排序無縫整合。透過這個方式,我們不再用簡單的查詢來滿足複雜的請求。我們看看下面的查詢是如何應用我們所學到的。我們展示2000年後釋出的頭兩部電影,透過其釋出時間來排序,並且對其演員名單排序。你自己看看:

query paginateMoviesAndActors($movieFirst: Int, $movieSkip: Int, $actorFirst: Int, $actorSkip: Int, $movieOrder: MovieOrderBy) {
  allMovies (
    filter: {
      releaseDate_gt: "2000"
    }
    orderBy: $movieOrder
    first: $movieFirst
    skip: $movieSkip
  ) {
    title
    actors(
      orderBy: name_ASC,
      first: $actorFirst,
      skip: $actorSkip
    ) {
      name
    }
    releaseDate
  }
}

你可以透過提供的查詢變數來實踐,看看他們有什麼效果。例如,你可以設 movieSkip2movieOrdertitle_DESC,然後再查詢。將會按照名字的降序返回第二頁電影。

總結

我們精心設計 GraphQL APIs,讓客戶端應用有很好的靈活性和控制。透過不同的規則來 和 ,以及 你的資料,你可以準確的表達你想要的資料,讓後端找出來。.

你對我們的 API 有沒有什麼疑問?可以參與我們的 來討論,或者瀏覽 獲取更多資訊。如果你還沒有賬戶,可以在 Graphcool 註冊。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/2334/viewspace-2808413/,如需轉載,請註明出處,否則將追究法律責任。

相關文章