Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Building API clients with Cistern
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
Adam Holt
February 20, 2014
Programming
100
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Building API clients with Cistern
@nwrug - github.com/lanej/cistern
Adam Holt
February 20, 2014
More Decks by Adam Holt
See All by Adam Holt
NWRUG - Celluloid
omgitsads
3
240
Other Decks in Programming
See All in Programming
AI駆動開発勉強会 広島支部 第一回勉強会 AI駆動開発概要とワークショップ
hayatoshimiu
0
450
LLM Plugin for Node-REDの利用方法と開発について
404background
0
160
TAKTでAI駆動開発の品質を設計する
j5ik2o
6
1k
正しくソフトウェアを作る、前提を疑うための認知の視点 / doubt-premise
minodriven
17
6.1k
Semantic Version 単位で戦略を柔軟に変えて、パッケージアップデートを自動化する
daitasu
0
170
AIエージェントの隔離技術の徹底比較
kawayu
0
470
ローカルLLMを使ってB2Bサービスを作っていての学び
yaotti
0
150
Modding RubyKaigi for Myself
yui_knk
0
900
Javaの型とAI時代に型が大事な理由 / java types and type in AI era
kishida
2
110
IBM Bobを活用したレガシーアプリの最新化
oniak3ibm
PRO
1
170
TSKaigi Night Talks 2026_TypeScriptでサプライチェーンの整合性を型に閉じ込める
geekplus_tech
0
320
コンテキストの使い捨てをやめる — ビジネスルール駆動開発と miko —
ioki
0
150
Featured
See All Featured
WENDY [Excerpt]
tessaabrams
11
38k
The Curse of the Amulet
leimatthew05
1
13k
Product Roadmaps are Hard
iamctodd
PRO
55
12k
Leveraging LLMs for student feedback in introductory data science courses - posit::conf(2025)
minecr
1
280
How to Align SEO within the Product Triangle To Get Buy-In & Support - #RIMC
aleyda
2
1.5k
What the history of the web can teach us about the future of AI
inesmontani
PRO
1
600
Ethics towards AI in product and experience design
skipperchong
2
300
Ruling the World: When Life Gets Gamed
codingconduct
0
250
The Hidden Cost of Media on the Web [PixelPalooza 2025]
tammyeverts
2
330
Designing for humans not robots
tammielis
254
26k
Why Mistakes Are the Best Teachers: Turning Failure into a Pathway for Growth
auna
0
150
The Curious Case for Waylosing
cassininazir
1
380
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?