$30 off During Our Annual Pro Sale. View Details »
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Building API clients with Cistern
Search
Adam Holt
February 20, 2014
Programming
0
97
Building API clients with Cistern
@nwrug - github.com/lanej/cistern
Adam Holt
February 20, 2014
Tweet
Share
More Decks by Adam Holt
See All by Adam Holt
NWRUG - Celluloid
omgitsads
3
240
Other Decks in Programming
See All in Programming
ハイパーメディア駆動アプリケーションとIslandアーキテクチャ: htmxによるWebアプリケーション開発と動的UIの局所的適用
nowaki28
0
420
Cap'n Webについて
yusukebe
0
130
안드로이드 9년차 개발자, 프론트엔드 주니어로 커리어 리셋하기
maryang
1
110
新卒エンジニアのプルリクエスト with AI駆動
fukunaga2025
0
210
ID管理機能開発の裏側 高速にSaaS連携を実現したチームのAI活用編
atzzcokek
0
220
これだけで丸わかり!LangChain v1.0 アップデートまとめ
os1ma
6
1.8k
TypeScriptで設計する 堅牢さとUXを両立した非同期ワークフローの実現
moeka__c
6
3k
実はマルチモーダルだった。ブラウザの組み込みAI🧠でWebの未来を感じてみよう #jsfes #gemini
n0bisuke2
0
430
Microservices rules: What good looks like
cer
PRO
0
1.3k
まだ間に合う!Claude Code元年をふりかえる
nogu66
5
800
リリース時」テストから「デイリー実行」へ!開発マネージャが取り組んだ、レガシー自動テストのモダン化戦略
goataka
0
130
Full-Cycle Reactivity in Angular: SignalStore mit Signal Forms und Resources
manfredsteyer
PRO
0
130
Featured
See All Featured
Bash Introduction
62gerente
615
210k
Stop Working from a Prison Cell
hatefulcrawdad
273
21k
Become a Pro
speakerdeck
PRO
31
5.7k
Producing Creativity
orderedlist
PRO
348
40k
Testing 201, or: Great Expectations
jmmastey
46
7.8k
The Illustrated Children's Guide to Kubernetes
chrisshort
51
51k
[SF Ruby Conf 2025] Rails X
palkan
0
510
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
[RailsConf 2023] Rails as a piece of cake
palkan
58
6.2k
Building Flexible Design Systems
yeseniaperezcruz
330
39k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
359
30k
Measuring & Analyzing Core Web Vitals
bluesmoon
9
710
Transcript
BUILDING API CLIENTS WITH CISTERN
@adamholt
@lanejoshlane
WHAT IS CISTERN?
“Cistern helps you consistently build your API clients and facilitates
building mock support.”
None
SERVICE
class Twitter::Client < Cistern::Service ! model_path "twitter/models" request_path "twitter/requests" !
model :tweet collection :tweets request :create_tweet ! class Real def initialize(options={}) # Setup end end ! class Mock def self.data; @data ||= {}; end ! def initialize(options={}) # Setup Mock Data end end end
class Twitter::Client < Cistern::Service model_path "twitter/models" request_path "twitter/requests" ! ...
end
class Twitter::Client < Cistern::Service ... ! model :tweet collection :tweets
request :create_tweet ! ... end
class Twitter::Client < Cistern::Service ... ! class Real def initialize(options={})
# Setup end end ! class Mock def self.data; @data ||= {}; end ! def initialize(options={}) # Setup Mock Data end end end
MODELS
class Twitter::Client::Tweet < Cistern::Model identity :id ! attribute :user, type:
:hash attribute :tweet, type: :array ! def retweet requires :id ! new_attributes = connection.retweet_tweet(id: id).body merge_attributes(new_attributes) end end !
COLLECTIONS
class Twitter::Client::Tweets < Cistern::Collection ! model Twitter::Client::Tweet ! def timeline(params
= {}) response = connection.get_tweets(params) ! data = self.clone.load(response.body) ! collection.attributes.clear collection.merge_attributes(data) end ! def retweets(params={}) response = connection.get_retweets(params) ... end ! def get(id) new(connection.get_tweet("id" => id).body) end end
REQUESTS
module Twitter class Client class Real def create_tweet(options={}) request( :body
=> {status: options[:body]}, :method => :post, :path => '/statuses/update' ) end end # Real ! ... end # Client end # Twitter
module Twitter class Client ... ! class Mock def create_tweet(options={})
id = Foo.random_hex(6) ! tweet = { "id" => id, "text" => "Hello from @NWRUG", "user" => {"name": "omgitsads"}, }.merge(options) ! self.data[:tweets][id]= tweet ! response( :body => tweet, :status => 200, :path => '/statuses/user_timeline.json', ) end end # Mock end # Client end # Twitter
DRAWBACKS
QUESTIONS?