Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Reacting to Change - API Days 2014
Search
Kyle Fuller
December 02, 2014
Technology
220
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Reacting to Change - API Days 2014
Kyle Fuller
December 02, 2014
More Decks by Kyle Fuller
See All by Kyle Fuller
Design APIs and deliver what you promised
kylef
0
150
Preparing for the future of API Description Languages
kylef
0
130
Resilient API Design
kylef
1
370
Building a Swift Web API and Application Together
kylef
2
2.2k
Testing without Xcode - CMD+U 2016
kylef
0
300
End-to-end: Building a Web Service in Swift (MCE 2016)
kylef
2
510
Designing APIs for Humans - Write the Docs 2016
kylef
0
370
Embracing Change - MBLTDev 2015
kylef
3
720
Practical Declarative Programming (360 iDev 2015)
kylef
3
570
Other Decks in Technology
See All in Technology
目の前の楽しいが人生を変える - コミュニティの螺旋の歩き方と楽しむコツ / change your life
soudai
PRO
5
650
AI coding 整合正規方法
philipz
0
410
研究開発部の紹介 / Sansan R&D Profile
sansan33
PRO
5
25k
株式会社シーエーシー エンジニア向け会社紹介資料
cac
0
57k
積み重なった技術負債への挑戦 〜初手としての全社ゴト化〜
techtekt
PRO
0
1.4k
え、こんなに早く改修できるの?──新人エンジニアとスクラムマスターの2人が語る、AI×アジャイル開発の現場
ysasago
2
580
Railsのように考える: See through the Master
snoozer05
PRO
4
1.2k
俺の仕事は AIに奪われないし、たぶんその BIも要らない
hikaruri
0
530
ソフトウェアDNAとクラウドエージェントのススメ
cloudace
0
120
「どのログを見ればいい?」 から始めた サーバーレス障害解析
y_waka1
1
110
CLIライブラリ開発を支える技術
htnabe
0
140
aws-iot-platform-architecture-use-cases.pdf
ma2shita
0
420
Featured
See All Featured
Building Applications with DynamoDB
mza
96
7.2k
Efficient Content Optimization with Google Search Console & Apps Script
katarinadahlin
PRO
1
870
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
32
4.9k
What does AI have to do with Human Rights?
axbom
PRO
1
2.4k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
508
140k
Max Prin - Stacking Signals: How International SEO Comes Together (And Falls Apart)
techseoconnect
PRO
0
470
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
31
10k
Exploring anti-patterns in Rails
aemeredith
4
510
Agile Actions for Facilitating Distributed Teams - ADO2019
mkilby
0
280
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
31
3.4k
Connecting the Dots Between Site Speed, User Experience & Your Business [WebExpo 2025]
tammyeverts
11
1k
Keith and Marios Guide to Fast Websites
keithpitt
413
23k
Transcript
REACTING TO CHANGE ! KYLE FULLER
BUILDING better API CLIENTS
None
None
DOZENS of APPS
HTTP / APIS
THERE’S AN API
COMPONENTS OF AN API CLIENT
perform(.RetrieveArticles) { result in switch result { case .Success(let representor):
/* We've got some articles */ case .Error(let error): /* We hit an error */ } }
FOUNDATION
NSURLSession OR NSURLConnection
NSURLRequest
NSURLHTTPResponse
SIMPLE...
HTTP SEMANTICS
SERIALISATION (JSON)
CONVERT to VALUE-MODELS
struct Article { let title:String let body:String let author:Author let
image:[NSURL] } struct Author { let name:String let twitter:String }
articles[0]["author"]["name"]
"/articles"
"name"
"nme"
- age + birthday
None
None
MAPPING
HTTP JSON MODEL MAPPING TESTS (STUBS & FIXTURES) DOMAIN LOGIC?
$ cloc **Model**.{h,m} **API**.{h,m} 95 text files. 83 unique files.
0 files ignored. ------------------------------------------------------------------------------- Language files blank comment code ------------------------------------------------------------------------------- Objective C 51 1420 499 5598 C/C++ Header 32 258 480 479 ------------------------------------------------------------------------------- SUM: 83 1678 979 6077 -------------------------------------------------------------------------------
6077 LINES OF CODE
ANDROID
15,000 LINES OF CODE
WINDOWS PHONE
20,000 LINES OF CODE
...
30,000 LINES OF CODE
BUILDING an API CLIENT
DOMAIN-SPECIFIC
INTEGRATED
MIXING PROTOCOL SEMANTICS
WHAT DOES THE API LOOK LIKE?
None
None
None
GETTING STARTED
TESTS
MOCK
[OHHTTPStubs stubRequestsPassingTest:^BOOL(NSURLRequest *request) { return ([request.URL.host isEqualToString:@"trunk.cocoapods.org"] && [request.URL.path isEqualToString:@"/api/v1/sessions"]);
} withStubResponse:^ OHHTTPStubsResponse *(NSURLRequest *request) { NSString *fixture = OHPathForFileInBundle(@"sessions.json", nil); NSDictionary *headers = @{ @"Content-Type": @"application/json" }; return [OHHTTPStubsResponse responseWithFileAtPath:fixture statusCode:200 headers:headers]; }];
{ "created_at": "2014-04-21 23:08:00 +0200", "email": "
[email protected]
", "name": "Kyle Fuller",
"sessions": [ { "created_at": "2014-05-04 15:20:19 +0200", "valid_until": "2014-09-09 15:20:19 +0200", "verified": false }, { "created_at": "2014-05-04 15:20:20 +0200", "valid_until": "2014-09-09 15:20:20 +0200", "verified": true } ] }
AND REPEAT
None
CAN’T WE USE THIS?
UNDERSTANDABLE by machines
POWERING YOUR TESTS with API BLUEPRINT
pod `CCLRequestReplay`
[OHHTTPStubs stubRequestsPassingTest:^BOOL(NSURLRequest *request) { return ([request.URL.host isEqualToString:@"trunk.cocoapods.org"] && [request.URL.path isEqualToString:@"/api/v1/sessions"]);
} withStubResponse:^ OHHTTPStubsResponse *(NSURLRequest *request) { NSString *fixture = OHPathForFileInBundle(@"sessions.json", nil); NSDictionary *headers = @{ @"Content-Type": @"application/json" }; return [OHHTTPStubsResponse responseWithFileAtPath:fixture statusCode:200 headers:headers]; }]; [OHHTTPStubs stubRequestsPassingTest:^BOOL(NSURLRequest *request) { return ([request.URL.host isEqualToString:@"trunk.cocoapods.org"] && [request.URL.path isEqualToString:@"/api/v1/pods"]); } withStubResponse:^ OHHTTPStubsResponse *(NSURLRequest *request) { NSString *fixture = OHPathForFileInBundle(@"pods.json", nil); NSDictionary *headers = @{ @"Content-Type": @"application/json" }; return [OHHTTPStubsResponse responseWithFileAtPath:fixture statusCode:200 headers:headers]; }]; [OHHTTPStubs stubRequestsPassingTest:^BOOL(NSURLRequest *request) { return ([request.URL.host isEqualToString:@"trunk.cocoapods.org"] && [request.URL.path isEqualToString:@"/api/v1/pod/../owners"]); } withStubResponse:^ OHHTTPStubsResponse *(NSURLRequest *request) { NSString *fixture = OHPathForFileInBundle(@"pod-querykit-owners.json", nil); NSDictionary *headers = @{ @"Content-Type": @"application/json" }; return [OHHTTPStubsResponse responseWithFileAtPath:fixture statusCode:200 headers:headers]; }]; ...
{ "created_at": "2014-04-21 23:08:00 +0200", "email": "
[email protected]
", "name": "Kyle Fuller",
"sessions": [ { "created_at": "2014-05-04 15:20:19 +0200", "valid_until": "2014-09-09 15:20:19 +0200", "verified": false }, { "created_at": "2014-05-04 15:20:20 +0200", "valid_until": "2014-09-09 15:20:20 +0200", "verified": true } ] } { "name": "QueryKit", "version": "0.8.3", "authors": { "Kyle Fuller": "
[email protected]
" }, "social_media_url": "http://twitter.com/kylefuller", "source": { "git": "https://github.com/QueryKit/QueryKit.git", "tag": "0.8.3" }, "source_files": [ "QueryKit/*.{h}", "QueryKit/ObjectiveC/*.{h,m}" ], "requires_arc": true } ...
let URL = NSBundle.mainBundle().URIForResource("palaver", withExtension:"apib.json") requestReplayManager.addRecordings(fromBlueprintURL:URL, error:nil)
GET /sessions
None
EMBRACE CHANGE
None
WE MADE A MISTAKE.
WE WANT TO CHANGE... ENDPOINT URI.
NEGOTIATE AT RUN-TIME
WE WANT TO CHANGE... PAGINATION LOGIC.
FOLLOWING LINKS
TRANSITION BETWEEN STATES
"Paging is achieved with the published_before parameter."
published_before
[ { "published_date": "2013-04-30T16:05:45+00:00", ... } ]
GET /articles?published_before=2013-04-30T16:05:45+00:00
SERVER LOGIC
Next Page = <some URI>
Prevent BREAKING CHANGES
BUILDING BETTER CLIENTS from THE API
FLEXIBILITY
CASCADED REQUESTS
GET /categories GET /authors GET /articles
BANDWIDTH
LARGE DATA
$ curl -I http://api.something.com/articles HTTP/1.1 200 OK Content-Type: application/json Content-Length:
12524998
BREAK IT UP
PAGINATION
/list VS /list/detail
USE Last-Modified
USE Cache-Control
USE STANDARDS
LET’S BUILD BETTER APIS TOGETHER
KYLE FULLER