Last active
November 26, 2023 20:36
-
-
Save martinklepsch/302121cdacd6771354c6 to your computer and use it in GitHub Desktop.
A minimal Clojure client for Airtable.com's HTTP API.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns oxygen.client | |
"A minimal Clojure client for Airtable.com's HTTP API. | |
Supports retrieval of whole tables as well as individual records. | |
Dependencies: [org.clojure/data.json \"0.2.6\"] [clj-http \"2.0.0\"]" | |
(:require [clojure.data.json :as json] | |
[clojure.string :as string] | |
[clojure.set :as set] | |
[clj-http.client :as client])) | |
(def api-base "https://api.airtable.com/v0") | |
(defn build-request-uri [base-id resource-path] | |
(string/join "/" (concat [api-base (name base-id)] (map name resource-path)))) | |
(defn get-in-base* | |
[{:keys [api-key base-id] :as base} resource-path] | |
(let [req-uri (build-request-uri base-id resource-path)] | |
(client/get req-uri {:headers {"Authorization" (str "Bearer " api-key)}}))) | |
(defn ^:private kwdize [m] | |
(set/rename-keys m {"id" :id "fields" :fields "createdTime" :created-time})) | |
(defn validate-base [{:keys [api-key base-id] :as base}] | |
(assert api-key ":api-key must present in passed credentials") | |
(assert base-id ":base-id must present in passed credentials")) | |
(defn validate-resource-path [resource-path] | |
(assert (sequential? resource-path) "resource-path must be a sequence") | |
(assert (<= (count resource-path) 2) "resource-path can't have more than two items")) | |
(defn get-in-base | |
"Retrieve tables and records from a table. | |
`base` needs to be a map containing `:api-key` and `:base-id`. | |
`resource-path` must be a sequence containing the table name | |
and an optional record id. | |
`:base-id` and elements in `resource-path` can be strings or keywords." | |
[base resource-path] | |
(validate-base base) | |
(validate-resource-path resource-path) | |
(let [data (-> (get-in-base* base resource-path) :body json/read-str)] | |
(if (= (count resource-path) 1) | |
(map kwdize (get data "records")) | |
(kwdize data)))) | |
(comment | |
(def my-base {:api-key "keyXXXXXXXXXXXXXX" | |
:base-id "appXXXXXXXXXXXXXX"}) | |
;; Retrieve a single record | |
(get-in-base my-base ["companies" "recXXXXXXXXXXXXXX"]) | |
;; Retrieve a full table | |
(get-in-base my-base ["products"])) |
It’s all yours :)
Thanks. I already forked the other repo and changed it a little. Also added to Clojure repo. https://github.com/altjsus/airtable-clj
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Don't you mind If i'd take this code, add other CRUD methods and post on clojars as package?