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 a Swift Web API and Application Together
Search
Kyle Fuller
March 02, 2017
Technology
2
2.1k
Building a Swift Web API and Application Together
Kyle Fuller
March 02, 2017
Tweet
Share
More Decks by Kyle Fuller
See All by Kyle Fuller
Design APIs and deliver what you promised
kylef
0
140
Preparing for the future of API Description Languages
kylef
0
120
Resilient API Design
kylef
1
350
Testing without Xcode - CMD+U 2016
kylef
0
270
End-to-end: Building a Web Service in Swift (MCE 2016)
kylef
2
500
Designing APIs for Humans - Write the Docs 2016
kylef
0
350
Embracing Change - MBLTDev 2015
kylef
3
700
Practical Declarative Programming (360 iDev 2015)
kylef
3
530
Building Resilient API Clients (SLUG)
kylef
2
13k
Other Decks in Technology
See All in Technology
「Blue Team Labs Online」入門 - みんなで挑むログ解析バトル
v_avenger
0
170
わたしがセキュアにAWSを使えるわけないじゃん、ムリムリ!(※ムリじゃなかった!?)
cmusudakeisuke
1
730
元エンジニアPdM、IDEが恋しすぎてCursorに全業務を集約したら、スライド作成まで爆速になった話
doiko123
1
630
Dr. Werner Vogelsの14年のキーノートから紐解くエンジニアリング組織への処方箋@JAWS DAYS 2026
p0n
1
130
JAWS DAYS 2026 楽しく学ぼう!ストレージ 入門
yoshiki0705
2
180
身体を持ったパーソナルAIエージェントの 可能性を探る開発
yokomachi
1
120
CyberAgentの生成AI戦略 〜変わるものと変わらないもの〜
katayan
0
170
JAWSDAYS2026_A-6_現場SEが語る 回せるセキュリティ運用~設計で可視化、AIで加速する「楽に回る」運用設計のコツ~
shoki_hata
0
3k
Yahoo!ショッピングのレコメンデーション・システムにおけるML実践の一例
lycorptech_jp
PRO
1
210
Abuse report だけじゃない。AWS から緊急連絡が来る状況とは?昨今の攻撃や被害の事例の紹介と備えておきたい考え方について
kazzpapa3
1
670
JAWS FESTA 2025でリリースしたほぼリアルタイム文字起こし/翻訳機能の構成について
naoki8408
1
490
決済サービスを支えるElastic Cloud - Elastic Cloudの導入と推進、決済サービスのObservability
suzukij
2
630
Featured
See All Featured
Bash Introduction
62gerente
615
210k
Chasing Engaging Ingredients in Design
codingconduct
0
140
ReactJS: Keep Simple. Everything can be a component!
pedronauck
666
130k
Balancing Empowerment & Direction
lara
5
940
How Software Deployment tools have changed in the past 20 years
geshan
0
32k
Lightning Talk: Beautiful Slides for Beginners
inesmontani
PRO
1
480
Joys of Absence: A Defence of Solitary Play
codingconduct
1
310
My Coaching Mixtape
mlcsv
0
71
GitHub's CSS Performance
jonrohan
1032
470k
The State of eCommerce SEO: How to Win in Today's Products SERPs - #SEOweek
aleyda
2
9.9k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
35
2.4k
How Fast Is Fast Enough? [PerfNow 2025]
tammyeverts
3
480
Transcript
Building a Swift Web API and Application Together Kyle Fuller
Agenda —API Design —Building API in Swift —Deploying API in
Swift in production
API Design
What makes a good API?
What makes a good API? —Decoupled from implementation details —Able
to evolve without breaking existing clients
Example: Pagination
GET /posts
GET /posts{?page}
GET /posts?page=2
None
None
! How can we solve?
GET /posts{?before}
GET /posts?before=44
How do we introduce changes to our API?
Versioning APIs
/v1/posts{?page} /v2/posts{?before}
/posts{?page} /posts{?before}
API is coupled to implementation details
API is coupled to implementation details
What happens when you version an API?
What happens when you version an API?
How can we design the API without exposing implementation details?
REST Representational State Transfer
Anticipating change is one of the central themes of REST
Evolvability
Tight Coupling
"You can’t have evolvability if clients have their controls baked
into their design at deployment"
"Controls have to be learned on the fly. That’s what
hypermedia enables"
Hypermedia
Web Linking RFC 5988
GET /posts Link: </posts?before=30>; rel="next", </posts?before=120>; rel="last"
GET /posts?before=120 Link: </posts?before=90>; rel="prev", </posts>; rel="first"
WebLinking.swift https://github.com/kylef/WebLinking.swift
WebLinking: Checking for next link if let link = response.findLink(relation:
"next") { print("We have a next link with the URI: \(link.uri).") }
WebLinking: Introspecting Available Links for link in response.links { print("Relation:
\(link.relationType)") print("URI: \(link.uri)") }
application/hal+json
Blog Post { "title": "My First Blog Post", "body": "Lorem
Ipsum" }
Blog Post (Next Link) { "title": "My First Blog Post",
"body": "Lorem Ipsum", "_links": [ { "href": "/posts/2", "relation": "next" } ] }
Blog Post (Self) { "title": "My First Blog Post", "body":
"Lorem Ipsum", "_links": [ { "href": "/posts/1", "relation": "self" }, { "href": "/posts/2", "relation": "next" } ] }
Blog Post (Comments) { "title": "My First Blog Post", "body":
"Lorem Ipsum", "_links": [ { "href": "/posts/1", "relation": "self" }, { "href": "/posts/2", "relation": "next" }, { "href": "/posts/1/comments", "relation": "comments" }, ] }
Blog Post (Embedded Comments) { "_embed": { "comments": [ {
"author": "Kyle", "body": "That's a really interesting post!" "_links": [ { "href": "/posts/1/comments/1", "relation": "self" } ] } ] } }
application/ vnd.siren+json
Delete Post { "properties": { "title": "My First Blog Post",
"body": "Lorem Ipsum", }, "actions": [ { "name": "delete", "method": "DELETE", "href": "/posts/1" } ] }
Delete Post { "properties": { "title": "My First Blog Post",
"body": "Lorem Ipsum", }, "actions": [ { "name": "delete", "method": "DELETE", "href": "/posts/1" } ] }
Create Comment { "properties": { "title": "My First Blog Post",
"body": "Lorem Ipsum", }, "actions": [ { "name": "comment", "method": "POST", "href": "/posts/1/comments", "fields": [ { "name": "author", "type": "string" }, { "name": "message", "type": "string" } ] } ] }
Create Comment (Logged in) { "properties": { "title": "My First
Blog Post", "body": "Lorem Ipsum", }, "actions": [ { "name": "comment", "method": "POST", "href": "/posts/1/comments", "fields": [ { "name": "message", "type": "string" } ] } ] }
Hypermedia —Remove implementation details from interface —Keep business logic on
back-end, not front-end
Building an API in Swift
Web Frameworks
Web Frameworks —Frank —IBM Kitura —Vapor
Frank vs Kitura vs Vapor
Frank get("users", *) { (request, username: String) in return "Hello
\(username)" }
Server APIs Working Group
Server APIs Working Group
Useful Tools —Templating Languages —Stencil —Data Persistence —Redis (Redbird) —PostgreSQL
Testing
XCTest class PersonTests: XCTestCase { let person = Person(name: "Kyle")
func testPersonName() { XCTAssertEqual(person.name, "Kyle") } func testPersonDescription() { XCTAssertEqual(person.description, "Kyle") } }
extension PersonTests: XCTestCaseProvider { var allTests : [(String, () throws
-> Void)] { return [ ("testPersonName", testPersonName), ("testPersonDescription", testPersonDescription), ] } } XCTMain([ PersonTests(), ])
Dredd https://github.com/apiaryio/dredd
API Blueprint # GET /hello + Response 200 (application/json) {
"name": "Kyle" }
Dredd Testing $ dredd \ apidescription.apib \ https://localhost:8080 ✔ GET
/hello ✔ API Matches API Description
Deployment
https://github.com/kylef/heroku-buildpack-swift
$ cat Package.swift import PackageDescription let package = Package( name:
"Hello", dependencies: [ .Package(url: "https://github.com/nestproject/Frank.git", majorVersion: 0, minor: 3), ] )
$ cat Sources/main.swift import Frank get { _ in return
"Hello World" } get(*) { (_, username: String) in return "Hello \(username)" }
$ cat Sources/main.swift import Frank get { _ in return
"Hello World" } get(*) { (_, username: String) in return "Hello \(username)" }
$ cat .swift-version 3.0.2
$ cat .swift-version 3.0.2
$ swift build $ .build/debug/Hello [INFO] Listening at http://0.0.0.0:8000 (48827)
[INFO] Booting worker process with pid: 48828
$ cat Procfile web: Hello
$ heroku create --buildpack https://github.com/kylef/heroku-buildpack-swift.git $ git push heroku master
remote: -----> Swift app detected remote: -----> Installing 3.0.2 remote: -----> Installing clang-3.7.0 remote: -----> Building Package remote: -----> Copying binaries to 'bin'
None
None
None
Manual Deployment
Monitoring
Logging
print("ERROR: Connection to database failed \(error)")
Papertrail
None
None
Conclusion —API Design —Swift Web Services —Tools & Frameworks —Testing
—Deployment —Monitoring
Conclusion —API Design —Swift Web Services —Tools & Frameworks —Testing
—Deployment —Monitoring
kylefuller https://fuller.li/talks