Airtable API 開發指南

Airtable 是一個令人驚異的工具。

它結合了試算表和資料庫的功能。

作為一位開發者,你可以使用非常好用的介面創建一個資料庫,同時也可以享受到試算表的編輯和使用便利性,甚至可以從移動應用程式輕鬆更新你的記錄。

適合原型設計

Airtable 不僅僅是一個名不副實的試算表,對於想要原型設計或者建立最小可行性產品(MVP)的開發者來說,它是一個完美的工具。

MVP(Minimum Viable Product)是應用程式或產品的初始版本。

大多數產品的失敗並不是因為技術限制或者“堆棧無法擴展”,而是因為要麼沒有需求,要麼製作者並沒有明確的市場推廣策略。

創建一個MVP可以減小花費數月時間建立完美應用程式而發現沒有人需要的風險。

優秀的 API

Airtable 提供了一個非常優秀的 API,可以方便地與 Airtable 資料庫進行程式化的互動。

這正是它相對於一般試算表來說在數據處理和身份驗證方面的優勢。

該 API 每秒的請求限制為 5 個,這還是相當合理的。

優秀的 API 文檔

這是 Airtable API 的文檔頁面:https://airtable.com/api

作為開發者,我們花了很多時間閱讀文檔,並嘗試弄清楚事物的運作方式。

API 相對複雜,因為你需要與一個服務進行互動,並且希望了解服務提供哪些功能以及如何使用 API 完成你需要的功能。

Airtable API 文檔提供了直接使用你的表中的實際數據的示例。在下面的圖片中,請注意字段示例值是我在表中實際放置的值:

The Airtable API docs

該 API 文檔提供了使用 curl 的示例:

Examples using curl

以及官方 Node.js 客戶端的示例:

Examples using Node.js

官方 Node.js 客戶端

Airtable 維護了官方的 Airtable.js Node.js 客戶端庫,這是一個非常易於使用的方式來訪問 Airtable 的資料。

它很方便,因為它內建了處理請求速率限制的邏輯,並在超過限制時自動進行重試。

讓我們來看幾個常見的可以通過 API 執行的操作,但首先我們需要定義一些我們在程式碼中需要參考的值:

  • API_KEY:Airtable 的 API 金鑰
  • BASE_NAME:你將要使用的的底座(base)的名稱
  • TABLE_NAME:該底座中表(table)的名稱。
  • VIEW_NAME:表視圖(view)的名稱。

底座是資料庫的縮寫,它可以包含多個表。

表以不同方式組織相同的資料,稱為表視圖。至少會有一個視圖(查看更多有關表視圖的信息)。

身份驗證

你可以設置 AIRTABLE_API_KEY 環境變量,Airtable.js 將自動使用該金鑰,或者將它明確地添加到你的程式碼中:

const Airtable = require('airtable')

Airtable.configure({
  apiKey: API\_KEY
})

初始化底座

const base = require('airtable').base(BASE\_NAME)

或者,如果你已經初始化了 Airtable 變量,可以使用:

const base = Airtable.base(BASE\_NAME)

參考一個表

利用 base 物件,你可以引用表:

const table = base(TABLE\_NAME)

檢索表中的記錄

表中的每一行被稱為一個「記錄」。

Airtable 在每個結果頁面中返回最多 100 條記錄。如果你確定在表中不會超過 100 個項目,可以直接使用 firstPage 方法:

table.select({
  view: VIEW\_NAME
}).firstPage((err, records) => {
  if (err) {
    console.error(err)
    return
  }

  // 所有的記錄都在 `records` 陣列中,在此做一些處理
})

如果你有(或期望有)超過 100 個記錄,你需要分頁地取得它們,使用 eachPage 方法:

let records = []

// 每頁記錄呼叫該函數
const processPage = (partialRecords, fetchNextPage) => {
  records = [...records, ...partialRecords]
  fetchNextPage()
}

// 所有記錄檢索完成時呼叫該函數
const processRecords = (err) => {
  if (err) {
    console.error(err)
    return
  }

  // 對 `records` 陣列進行处理
}

table.select({
  view: VIEW\_NAME
}).eachPage(processPage, processRecords)

檢查記錄內容

任何一個記錄都有許多可以檢查的屬性。

首先,你可以獲取它的 ID:

record.id

//或者

record.getId()

接著,你可以獲取它的創建時間:

record.createdTime

你還可以獲取它的任何屬性,通過使用欄位名:

record.get('Title')
record.get('Description')
record.get('Date')

獲取特定記錄

你可以通過 ID 獲取特定記錄:

const record\_id = //...

table.find(record\_id, (err, record) => {
  if (err) {
    console.error(err)
    return
  }

  console.log(record)
})

或通過特定欄位值獲取:

const getData = url => {
  table.select({
    filterByFormula: `{url} = "${url}"`
  }).eachPage(function page(records) {
    records.forEach(function(record) {
      console.dir(record.get('json'))
    })
  })
}

如果你想從函數中返回數據,使用 .all() 和 async/await 是很方便的:

const getData = async url => {
  const records = await table.select({
    filterByFormula: `{url} = "${url}"`
  }).all()
  
  return records[0].get('json')
}

注意,all() 是同步地檢索所有結果頁面的記錄,僅在少量頁面的結果(或者在這種情況下只有 1 個結果)時使用。

創建新的記錄

你可以添加一個新的記錄:

table.create({
  "Title": "Tutorial: create a Spreadsheet using React",
  "Link": "https://flaviocopes.com/react-spreadsheet/",
}, (err, record) => {
  if (err) {
    console.error(err)
    return
  }

  console.log(record.getId())
})

更新記錄

你可以更新記錄的單個字段,而保留其他字段不變,使用 update

const record\_id = //...

table.update(record\_id, {
  "Title": "The modified title"
}, (err, record) => {
  if (err) {
    console.error(err)
    return
  }

  console.log(record.get('Title'))
})

或者,你可以更新記錄的某些字段,並清空你沒有修改的字段,使用 replace

const record\_id = //...

table.replace(record\_id, {
  "Title": "The modified title",
  "Description": "Another description"
}, (err, record) => {
  if (err) {
    console.error(err)
    return
  }

  console.log(record)
})

刪除記錄

可以使用以下代碼刪除一個記錄:

const record\_id = //...

table.destroy(record\_id, (err, deletedRecord) => {
  if (err) {
    console.error(err)
    return
  }

  console.log('Deleted record', deletedRecord.id)
})