平常工作都是串接 RESTful API 居多,最近因為使用了 Rize 這個時間追蹤軟體,他可以自動追蹤我使用電腦應用程式的時長和詳細資料,如下圖所示:

而我自己又會在 Tana App 將每一天做了什麼事情?花了多少時間?一一記錄起來,如下所示:

那麼身為一個懶惰的工程師,我在手動記錄一段時間後開始思考:有沒有辦法直接把 Rize 的資料跟 Tana 串接起來?這樣我就不用每天花時間將資料搬運紀錄了。

恰好 Rize APP 有提供 API 可以取得我們的資料,但 Rize APP 使用的是 GraphQL,不是我熟悉的 RESTful API,所以就稍微研究了怎麼使用與呼叫 GraphQL,並做成筆記分享給有需要的朋友。

拉拉雜雜的說了那麼多,終於要進入正題了 😂

GraphQL 介紹

不免俗的,還是要來介紹一下何為 GraphQL,其實他跟 RESTful API 都是讓 client 端取得數據要求的一種架構,簡單來說,就是打 API 取資料啦。

GraphQL 和 RESTful API 的異同之處

我用 postman 試打 GraphQL 後,發現他們的觀念很類似,不同的是結構和呼叫的方式,以下我簡單整理他們相同與差異之處,如有不足之處歡迎留言補充。

相同點

  1. 使用 HTTP 呼叫
    • 他們都使透過 HTTP 協議進行通訊,所以前端使用非常方便
    • 也都使用 URL 作為 server endpoint (就是俗稱的 API 網址)
  2. 使用 JSON 格式
    • 主要也都是返回 JSON 格式的資料
    • 發送請求時,也可以使用 JSON 傳遞參數
  3. 驗證機制類似
    • 兩者都可以使用 headers 的 bearer token 驗證身份

相異處

  1. 請求方式
    • RESTful API 的每個 endpoint 會對應一個資料,例如處理會員,可能就有三隻 API:
      • GET /users/1
      • POST /users
      • DELETE/users/1
    • 而 GraphQL 所有請求都是發送到單一 endpoint,也就是只會有一個 API 網址,通常是 /graphql (我一開始還傻傻的寫 /graphql/users,結果他回傳 404 😂)
      • 我們可以通過 query (查詢), mutation (變更), subscription (訂閱) 來指定操作和需要的數據結構
  2. 返回的資料
    • RESTful API 會返回後端定義好的資料結構,前端只能被動接收
    • GraphQL 可以讓前端指定需要回傳的資料,我們需要什麼就拿什麼,不會得到一堆用不到的資料。(光是這點就令我超級驚艷惹 !!!)
  3. 串接的靈活性
    • 在使用 RESTful API 時,如果我們需要先透過 A 才能取得 B 資料,就會需要多個 API 請求
    • 而 GraphQL 可以在單一請求中串接多個關聯數據,讓我們只要打一次 API 就能取得多個資料。

AD

GraphQL 文件示例與呼叫

接下來就以 Rize 為例,介紹一下怎麼看 GraphQL 的文件。

▼ 首先一樣申請 Rize API Key

▼ 打開 Rize 的 API 文件:https://rize-io.notion.site/146d25a8136b80c1af63c56e72404803?v=146d25a8136b80f094ae000cc00ee3fb&pvs=74

這份 Notion 文件其實已經介紹很詳細了,所以後續我分享的是我大概是怎麼看這文件,以及如何使用 Postman。除了 Postman 外,Rize App 也提供了 playground,至於如何使用,可以參考 Rize Notion 文件的圖文介紹

▼ Rize 的 GraphQL API endpoint(URL) :

https://api.rize.io/api/v1/graphql

▼ Rize Playground 文件一開始提供的範例是取得「當前使用者的 Email」

query CurrentUser {
  currentUser {
    email
  }
}

我們就以這兩個為例子,放到 Postman 吧。

▼ 設定 endpoint url 與請求,請求是 POST,並在 Bearer Token 輸入從 Rize App 取得的 API KEY

▼ 在 Body 分頁中選擇「GraphQL」,將剛剛在 Rize Playground 取得的 query 語法複製貼上。送出後會根據 Bearer Token 取得當前使用者的 Email。

至此,恭喜完成了人生第一次的 GraphQL 呼叫 🎉。

使用 GraphQL 指定返回的資料

前面跟 RESTful API 比較差異的段落中,有提到使用 GraphQL 可以指定返回的資料,這邊使用 Rize Playground 文件跟大家介紹怎麼找資料。

文件根目錄有兩個 Type:Query 和 Mutation,這就是前面提到的 GraphQL 的三種操作方式的其中二種 (還有一個是 Subscription)

▼ 選擇 query 看一下可以查詢哪些資料

▼ 紅框處是一個完整的 query,可以把 appsAndWebsites 想成是 RESTful API 的一個 endpoint,表示我現在要查詢 appsAndWebistes 的資料。括號裡面的 startTimeendTime 就是俗稱的 payload,也就是 query 的參數

▼ 此時的 query 可以這樣寫

query {
  appsAndWebsites(
    startTime: "2025-01-22T00:00:00+00:00",
    endTime: "2025-01-22T23:59:59+00:00"
  )
}

回到文件根目錄,看到「Root Types」下方的「All Schema Types」,Schema 是用來定義 API 整體結構的核心部分,我們可以在此查詢完整的資料結構與定義,如此就能知道要回傳哪些資料。

▼ 選擇跟 query「appsAndWebsites」同名的 schema 來查看資料結構

▼ 以下是 AppsAndWebsites 的資料結構,可以清楚地看到資料的值與型別

▼ 我希望 AppsAndWebsites 查詢只回傳 appNameid,我將前面寫好的 AppsAndWebsites 查詢加入指定回傳的資料

// 原本的 query 寫法
query {
  appsAndWebsites(
    startTime: "2025-01-22T00:00:00+00:00",
    endTime: "2025-01-22T23:59:59+00:00"
  )
}

// 加入回傳資料後
query {
  appsAndWebsites(
    startTime: "2025-01-22T00:00:00+00:00",
    endTime: "2025-01-22T23:59:59+00:00"
  ) {
    appName
    id
  }
}

▼ 貼到 postman 上,一樣使用 POST method,送出後會得到 1 月 22 日使用過的所有 apps 和 websites,而且只顯示 appName 和 id 兩個欄位

至此,恭喜完成了人生第二次的 GraphQL 呼叫,還能自己決定要取得哪些資料 🎉。

小結

感謝各位的收看,那麼我的 GraphQL 初體驗就到此先告一段落 XXD,之後會再研究怎麼跟 Tana 串接,當然有成功會再寫成文章分享出來。

關於前面提到 GraphQL 可以在單一請求中串接多個關聯數據,我目前還沒有嘗試,但翻了一下 Rize Playground 的文件,我覺得應該是在 Scheme 的 Implements 欄位內可以取得 API 之間的關聯。這部分未來有機會研究到,也會再跟大家分享 (又開始亂開支票了 😂

總之,這篇文章就獻給還沒使用過 GraphQL,但已經很熟悉 RESTful API,並想試水溫的朋友們。

最後,如果你對 Rize APP 這個時間追蹤軟體有興趣的朋友,歡迎使用我的 refer code 註冊,可以取得一個月的免費使用唷!