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
Adam Holt
February 20, 2014
Programming
0
95
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
Constant integer division faster than compiler-generated code
herumi
2
440
なぜ今、Terraformの本を書いたのか? - 著者陣に聞く!『Terraformではじめる実践IaC』登壇資料
fufuhu
4
420
0から始めるモジュラーモノリス-クリーンなモノリスを目指して
sushi0120
0
250
バイブコーディングの正体——AIエージェントはソフトウェア開発を変えるか?
stakaya
5
790
GitHub Copilotの全体像と活用のヒント AI駆動開発の最初の一歩
74th
7
2.1k
SwiftでMCPサーバーを作ろう!
giginet
PRO
2
230
Streamlitで実現できるようになったこと、実現してくれたこと
ayumu_yamaguchi
2
280
オホーツクでコミュニティを立ち上げた理由―地方出身プログラマの挑戦 / TechRAMEN 2025 Conference
lemonade_37
1
440
Google I/O Extended Incheon 2025 ~ What's new in Android development tools
pluu
1
230
AIコーディングエージェント全社導入とセキュリティ対策
hikaruegashira
16
9.5k
中級グラフィックス入門~効率的なメッシュレット描画~
projectasura
4
2.5k
DynamoDBは怖くない!〜テーブル設計の勘所とテスト戦略〜
hyamazaki
0
190
Featured
See All Featured
Art, The Web, and Tiny UX
lynnandtonic
301
21k
Why You Should Never Use an ORM
jnunemaker
PRO
58
9.5k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
110
19k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
131
19k
Imperfection Machines: The Place of Print at Facebook
scottboms
267
13k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
31
1.3k
What's in a price? How to price your products and services
michaelherold
246
12k
Building an army of robots
kneath
306
45k
For a Future-Friendly Web
brad_frost
179
9.9k
It's Worth the Effort
3n
185
28k
Faster Mobile Websites
deanohume
308
31k
BBQ
matthewcrist
89
9.8k
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?