Airtable API for Developers

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 文檔提供了直接使用你的表中的實際數據的示例。在下面的圖片中,請注意字段示例值是我在表中實際放置的值: 該 API 文檔提供了使用 curl 的示例: 以及官方 Node.js 客戶端的示例: 官方 Node.js 客戶端 Airtable 維護了官方的 Airtable.js Node.js 客戶端庫,這是一個非常易於使用的方式來訪問 Airtable 的資料。 它很方便,因為它內建了處理請求速率限制的邏輯,並在超過限制時自動進行重試。 讓我們來看幾個常見的可以通過 API 執行的操作,但首先我們需要定義一些我們在程式碼中需要參考的值: API_KEY:Airtable 的 API 金鑰 BASE_NAME:你將要使用的的底座(base)的名稱 TABLE_NAME:該底座中表(table)的名稱。 VIEW_NAME:表視圖(view)的名稱。 底座是資料庫的縮寫,它可以包含多個表。...

GraphQL API vs REST API

主要介紹了REST與GraphQL之間的差異以及在什麼情況下使用其中之一。 由於REST是建立API的一種常用方法,比GraphQL更為廣泛使用,所以可以假設你對其相當熟悉,現在讓我們看看GraphQL和REST之間的差異。 REST是一種概念 REST是一種事實上的架構標準,但沒有具體的規範,有許多非官方定義。而GraphQL有一個規範草案,它是一個查詢語言,而不是一種架構,其周圍建立了一套明確的工具集(和一個蓬勃發展的生態系統)。 REST是建立在現有架構之上的,最常見的情況是使用HTTP。而GraphQL則正在構建自己的一套約定,這既可以是優點,也可能不是優點。因為REST可以通過HTTP層的緩存功能免費獲益。 單一端點 GraphQL只有一個端點,您將所有的查詢都發送到該端點。而REST則使用多個端點,並使用HTTP 動詞來區分讀取操作(GET)和寫入操作(POST,PUT,DELETE)。GraphQL不使用HTTP動詞來確定請求類型。 根據需求量身定制 在REST中,您通常無法選擇服務器返回的數據,除非服務器實現了使用稀疏字段集進行部分響應的功能,並且客戶端使用該功能。API維護者無法強制執行此類過濾。 除非您也控制API服務器並為每個不同的請求定制響應,否則API通常會返回比您所需的更多信息。 在GraphQL中,您明確要求您所需的信息,您不會“選擇退出”完整的默認響應,而需要選擇您想要的字段。 這有助於節省服務器的資源,因為您可能需要更少的處理,同時也節省了網絡流量,因為要傳輸的有效載荷更小。 一個很好的例子來形象地展示這一點是一個Pizza端點的示例(我是義大利人,一個披薩的例子很完美)。 如果你調用GET /pizza/margherita,你會得到一個馬若里披薩。 如果你調用GET /pizza/napoli,你會得到一個拿坡里披薩。 如果你有30個不同的口味,你將有30個端點(除非你把披薩名稱作為參數傳遞給GET /pizza,例如)。 但也許你想要一種特定的披薩,但卻不要一種你不喜歡的成分。向服務生提出這個要求很容易,但對於REST端點來說有點困難。 一個GraphQL端點將讓你調用/pizza,然後你可以要求特定的成分,來打造你想要的完美披薩。 GraphQL使得監測字段使用變得容易 在REST中通常無法確定客戶端是否需要某個字段,因此在進行重構或淘汰時,無法確定實際使用情況。 GraphQL使得追踪客戶端使用的字段成為可能。 訪問嵌套數據資源 GraphQL允許進行更少的網絡調用。 來看一個例子:您需要訪問一個人的朋友的名字。如果您的REST API公開了一個/person端點,該端點返回一個包含朋友ID列表的人物對象,通常可以先通過GET /person/1獲取人物信息,其中包含朋友的ID列表。 除非該人的朋友列表已經包含有朋友的名字,否則對於有100個朋友的情況,您需要對/person端點發起101個HTTP請求,這是一個巨大的時間成本,也是一個資源密集型操作。 而GraphQL只需要一個請求,該請求要求查詢該人物的朋友的名字。 類型 REST API基於無法提供類型控制的JSON。GraphQL具有一個類型系統。 哪一個更好? 全球各地的組織都在質疑他們的API技術選擇,他們正試圖找出從REST遷移到GraphQL是否適合他們的需求。 當您需要公開複雜的數據表示且客戶端可能只需要數據的子集,或者他們定期執行嵌套查詢以獲取所需的數據時,GraphQL非常適合。 和編程語言一樣,沒有絕對的贏家,一切都取決於您的需求。 同時,我還想說一點:您可以同時使用兩種方法。 您可以根據您的需求混合使用REST和GraphQL,有時這是最好的方法。

Node事件模組

Node.js的events模組提供了EventEmitter類別 events模組為我們提供了EventEmitter類別,這是在Node中處理事件的關鍵。 我在這篇完整的文章中發布了更多詳細內容,所以在這裡我僅描述API而不提供進一步的用例。 const EventEmitter = require('events') const door = new EventEmitter() 事件監聽器也使用這些事件: newListener 當監聽器被添加時 removeListener 當監聽器被移除時 以下是最常用方法的詳細說明: emitter.addListener() emitter.emit() emitter.eventNames() emitter.getMaxListeners() emitter.listenerCount() emitter.listeners() emitter.off() emitter.on() emitter.once() emitter.prependListener() emitter.prependOnceListener() emitter.removeAllListeners() emitter.removeListener() emitter.setMaxListeners() emitter.addListener() emitter.on()的別名。 emitter.emit() 觸發一個事件。按照它們註冊的順序同步調用每個事件監聽器。 emitter.eventNames() 返回一個字串陣列,表示當前EventListener上註冊的事件: door.eventNames() emitter.getMaxListeners() 獲取可以添加到EventListener對象的最大監聽器數量,默認為10,但可以通過使用setMaxListeners()增加或減少。 door.getMaxListeners() emitter.listenerCount() 獲取傳遞的事件的監聽器的數量: door.listenerCount('open') emitter.listeners() 獲取傳遞的事件的監聽器數組: door.listeners('open') emitter.off() emitter.removeListener()在Node 10中新增的別名。 emitter.on() 添加在事件觸發時調用的回調函數。 用法: door.on('open', () => { console.log('門被打開了') }) emitter.once() 添加在註冊後僅在首次觸發事件時調用的回調函數。這個回調函數只會被調用一次,後續不再調用。 const EventEmitter = require('events') const ee = new EventEmitter() ee....

Phaser: 處理畫布

本篇文章是 Phaser 系列的一部分。點擊這裡 查看系列的第一篇文章。 Phaser 遊戲是在 HTML 的 <canvas> 元素中渲染的。 如果你對 Canvas 還不熟悉,我在 Canvas API 教程 中詳細介紹了它。 我們創建一個帶有特定寬度和高度的畫布,並在其中繪製內容。 我們無法使用 CSS 來對元素進行排版,而是需要使用更底層且較困難的 API。 幸運的是,Phaser(以及其他使用底層 Canvas 的庫)抽象了所有細節,所以我們可以專注於應用程式代碼。 我們可以通過在 Phaser 物件上調用 Game 靜態方法來初始化一個 Phaser 遊戲: new Phaser.Game() 我們必須將一個對象字面量傳遞給此函數,其中包含一組配置選項: new Phaser.Game({}) 在這個配置對象中,我們可以設置多個屬性。 首先,我們可以設置畫布的寬度和高度: new Phaser.Game({ width: 450, height: 600 }) 另一個我們可以傳遞的屬性是 backgroundColor,它接受一個十六進制值,例如 0x000000 表示黑色。 顏色類似於 CSS 顏色,但你需要在前面加上 0x 以便 JavaScript 知道這是一個十六進制數字。

Web Storage API: 本地儲存和會話儲存

Web Storage API 提供了一種在瀏覽器中儲存數據的方式。它定義了兩種非常重要的儲存機制:會話儲存和本地儲存,它們是 Web 平台上提供的一套儲存選項的一部分。 介紹 如何訪問儲存 方法 setItem(key, value) getItem(key) removeItem(key) key(n) clear() 儲存大小限制 桌面 移動設備 超過配額 開發者工具 Chrome Firefox Safari 介紹 Web Storage API 定義了兩種非常重要的儲存機制:會話儲存和本地儲存。 它們是 Web 平台上提供的一套儲存選項的一部分,包括: Cookies IndexedDB 緩存 API Application Cache 已被棄用,Web SQL 在 Firefox、Edge 和 IE 中沒有實現。 會話儲存和本地儲存提供了一個私有區域來存儲數據。您存儲的任何數據都無法被其他網站訪問。 會話儲存在頁面會話的期間保持存儲的數據。如果多個窗口或選項卡訪問同一個網站,它們會有兩個不同的會話儲存實例。 當一個選項卡/窗口關閉時,該選項卡/窗口的會話儲存將被清除。 會話儲存旨在允許在同一個網站上獨立處理不同的進程,這在 cookie 中是不可能的,因為它們在所有會話中共享。 相反,本地儲存會保存數據直到它被明確刪除,無論是您還是用戶刪除。它不會自動清理,並且在所有訪問網站的會話中共享。 本地儲存和會話儲存都是協議特定的:在使用 http 訪問頁面時存儲的數據在使用 https 服務頁面時不能訪問,反之亦然。 網絡儲存只能在瀏覽器中訪問,不像 cookie 那樣發送到服務器。 如何訪問儲存 本地和會話儲存都可以在 window 對象上使用 sessionStorage 和 localStorage 進行訪問。 它們的屬性和方法集完全相同,因為它們返回的是同一個對象,即 Storage 對象。...

什麼是 JAMstack?

了解 JAMstack 的意義以及這組技術的優勢 你在過去幾年中一定聽過 JAMstack 這個詞語。 JAMstack 是一組技術,結合使用以實現目標,如果你熟悉 LAMP 和 MEAN 的話,你可能已經知道了。 JAMstack 是什麼意思? JAM 表示 JavaScript、API 和 Markup。 它描述了在創建網絡應用程式和網站時具有以下特點的趨勢: 有一個“愚蠢”的網絡伺服器(或者CDN),傳送運行應用所需的 HTML,通常是使用靜態站點產生器生成的。HTML 不是在伺服器上生成。 應用程式可以載入一些 JavaScript,從 API 中接收數據。頁面互動,如導航,可以導致從 API 獲取更多數據。認證也是通過 API 完成的。 這種新的方法是一種新的方式,與傳統的方式不同: 傳統網站提供應用程序中已有的內容(如靜態站點)。 基於 CMS 的網站從後端的數據庫中加載信息。 使用任何種類的後端語言進行服務器渲染的應用程式。 它也不同於具有服務器渲染部分的客戶端渲染網站(例如使用 React 構建)。JAMstack 完全不涉及服務器渲染。 使用 JAMstack 的優勢是什麼? 它快速。HTML 已經生成並且網絡伺服器只需提供它,而無需進行從數據庫查找數據或為每個請求生成頁面 HTML 等任何後端操作。它可以通過 CDN(內容傳遞網絡)輕鬆提供。 它高效。由於沒有後端,所以沒有瓶頸(例如沒有數據庫)。 它更便宜,因為通過 CDN 提供資源比通過後端伺服器提供資源要便宜得多。 它更安全,因為後端僅通過 API 公開。 傳統的動態服務器渲染網站應用程序的方式(如 WordPress、Laravel 和 Rails)在許多情況下正被一種較輕的方式所取代。 一個典型的 WordPress 網站在每次頁面加載時可能對數據庫進行30-100次請求,這取決於安裝的插件數量。除非頁面被大量緩存,否則當一個 WordPress 網站在 Hacker News、Reddit 或任何其他大型網站上變得流行時,你會看到一個空白頁面-這意味著伺服器上發生了故障,因為該網站無法應對所有的流量。這往往是一個失去的機會,因為當網站以其最高的流行度時它無法運作。 相比於這些情況,提供一個靜態 HTML 頁面要有效得多,並且在 HTML 載入後可以根據需要仍然獲取動態數據,使用獨立的 API 呼叫。...

介紹 JSON Web Token (JWT)

學習 JWT 基礎知識及如何使用它 JSON Web Token 是一種用於創建應用程式的訪問令牌的標準。 它的運作方式是,伺服器生成一個令牌,用於驗證使用者身份,並將其發送給客戶端。 客戶端將在每個後續請求中將令牌發送回伺服器,因此伺服器知道該請求來自特定身份。 這種架構在現代 Web 應用程序中非常有效,在使用者驗證之後,我們會對 REST 或 GraphQL API 執行API請求。 誰在使用 JWT 呢?以 Google 為例,如果你使用 Google APIs,你會使用 JWT。 JWT 是被加密簽名的(但不會被加密,因此在將用戶數據存儲在 JWT 中時,使用 HTTPS 是必須的),所以當我們收到它時,我們可以確信它的可信度,沒有中間人可以截取並修改它,或者無效化它所保存的數據。 儘管如此,JWT 經常因過度使用而受到批評,尤其是在可以使用更少問題的解決方案時使用它們。 你需要對該主題形成自己的觀點。我並不主張某種技術優於其他,只是展示你在手邊擁有的所有機會和工具。 它們有什麼用途?主要用於 API 認證和服務器到服務器的授權。 JWT 令牌如何生成? 使用 Node.js 你可以通過以下代碼生成令牌的第一部分: const header = { "alg": "HS256", "typ": "JWT" } const encodedHeader = Buffer.from(JSON.stringify(header)).toString('base64') 我們設定 HMAC SHA256 作為簽名算法(JWT 支持多種算法),然後我們從這個 JSON 編碼對象創建一個緩存,並且使用 base64 編碼它。 部分的結果是 eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9。 接下來我們添加 payload,我們可以使用任意類型的數據自定義它。有一些預留的鍵,包括 iss 和 exp,它們標識令牌的發行者和過期時間。...

在不同的JavaScript庫中進行相同的POST API調用

我使用了一個很酷的應用程序Insomnia來測試API,它允許您對REST API或GraphQL API服務進行HTTP請求。 該應用程序具有一個很好的按鈕,可以生成代碼以從應用程序複製API請求,您可以在其中以可視化方式設計所有請求數據。 在內部,他們使用了httpsnippet,這是一個使用JavaScript編寫的多語言和庫的HTTP請求片段生成器。這是一個非常酷的項目。 無論如何,導出的代碼片段有幾個,我想展示不同庫中相同的API調用。 首先,這是API調用的描述。我向 api.randomservice.com 網站發送一個POST請求(這是我隨便想出的一個隨機URL)到 /dog 端點。 我向該端點發送一個帶有2個屬性的對象: { name: 'Roger', age: 8 } 作為JSON編碼。 我還傳遞了一個 content-type 以將內容設置為 application/json,並且還傳遞了一個 authorization 標頭,以使用通過API儀表板分配給我的Bearer令牌對請求進行身份驗證。 XHR 第一個代碼示例是使用XHR(可在瀏覽器中原生支持)和在Node.js中使用xmlhttprequest庫: const data = JSON.stringify({ name: 'Roger', age: 8 }); const xhr = new XMLHttpRequest(); xhr.withCredentials = true; xhr.addEventListener('readystatechange', function() { if (this.readyState === this.DONE) { console.log(this.responseText); } }); xhr.open('POST', 'https://api.randomservice.com/dog'); xhr.setRequestHeader('content-type', 'application/json'); xhr.setRequestHeader('authorization', 'Bearer 123abc456def'); xhr.send(data); Fetch API 然後,我們使用Fetch API進行相同的代碼片段,這也是另一個在瀏覽器中原生可用且可以在Node.js中使用node-fetch的API: fetch('https://api.randomservice.com/dog', { method: 'POST', headers: { 'content-type': 'application/json', authorization: 'Bearer 123abc456def' }, body: JSON....

在調用 `res.redirect()` 後產生 Next.js 空白頁面

我在使用一個 API 路由並在回應表單提交後調用了以下程式: res.redirect('/') 在本地開發時運作得很好,但是當我將它部署到 Vercel 時,重定向結果卻呈現了一個空白頁面。URL 是正確的,但需要刷新頁面才能顯示內容。 我不確定為什麼會這樣,但我通過使用 res.writeHead() 來解決這個問題: res.writeHead(302, { Location: '/' }).end() 302 Found HTTP 狀態碼是執行 URL 重定向的常見方式。

如何使用 Drag and Drop API

了解如何使用 Drag and Drop API 為您的使用者創建交互式體驗 使用 Drag and Drop API,您可以定義頁面中的哪些元素是可拖動的,並在用戶拖動元素時攔截它。 它在現代瀏覽器中得到了很好的支持: 在我們開始研究這個 API 之前,我們必須知道如何定義頁面中的可拖動元素。我們可以通過在頁面的 HTML 中添加 draggable 屬性並將其設置為 true 來實現: <div draggable="true"> ... </div> 這就足以使元素成為可拖動的。 提示:圖片、文字選擇和鏈接默認情況下是可拖動的,除非您在它們上面設置了 draggable 為 false。 我們還可以從用戶計算機中將文件拖動到瀏覽器中。在這種情況下,我們傳輸的是文件。 我們還需要澄清的另一點是元素可以拖放到哪裡。就像我們不能隨意拖動任何元素一樣,我們也不能隨意拖放到任何元素中。元素必須是有效的放置目標。 要使元素成為放置目標,您需要侦聽其 dragover 事件,並根據需要從該事件返回 false 或調用 preventDefault(): const element = document.querySelector('#my-drop-target') element.addEventListener('dragover', event => { event.preventDefault() }) 一旦完成了上述步驟,我們就擁有了一個可拖動元素和一个放置目標,就可以開始進一步操作了。我們可以與可拖動元素交互的事件有: dragstart drag dragend 放置目標上可以交互的事件有: dragenter dragover dragleave drop 拖放操作概述及觸發的事件 當用戶開始拖動一個可拖動元素時,可以進行鼠標點擊並移動鼠標,或者也可以單擊並保持選擇,然後移動選擇區,此時會在元素上觸發 dragstart 事件: element.addEventListener('dragstart', event => { //... }) 傳遞給事件處理函數的 event 對象是一個 DragEvent 對象。它是從更一般的事件對象中擴展出來的,與所有其他事件(鼠標,鍵盤,滾動等)共享。...