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.2k
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Building a Swift Web API and Application Together
Kyle Fuller
March 02, 2017
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
360
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
360
Embracing Change - MBLTDev 2015
kylef
3
710
Practical Declarative Programming (360 iDev 2015)
kylef
3
560
Building Resilient API Clients (SLUG)
kylef
2
13k
Other Decks in Technology
See All in Technology
大量データに対しても、生成AIを用いてリーズナブルにデータ加工をしたい!Databricksのai_queryについて調べてみた
kamoshika
1
130
インフラと開発の垣根を超えていき!〜元AWSインフラエンジニアがAWS開発で奮闘している話〜
hatahata021
2
180
SRE依存からの脱却 運用を開 発チームへ移す、 フルサイ クル開 発体制の実践
joooee0000
0
2.7k
ボーイスカウトルールでメモリやスキルを改善しよう
azukiazusa1
2
1k
「最後に責任を取るのはチーム」— 人間のPRレビューを最小化してアップデートしたメンタルモデル
jnishime_dresscode
0
610
[2026-07-15] AI Ready なはずだったアーキテクチャと、見えてきた課題・次に目指す状態
wxyzzz
6
3.1k
最適な自走を最小限の支援で — M&Aで拡大する組織で少人数SREが挑んだ1年 / SRE NEXT 2026
genda
0
1.1k
証券システムを10年Scalaで作り続けるということ - 関数型まつり2026
krrrr38
3
840
個人開発で育てる「大規模設計の苗床」 - AI時代の1人開発から始める業務への知識接続 / The Seedbed for Large-Scale Design - From AI-Era Solo Projects to Professional Knowledge
bitkey
PRO
0
180
型は壁、Rustでもバグを直すな、表現できなくせよ
nwiizo
13
2k
タスクの複雑さでモデルを選ぶ ── Thompson Samplingで動かす“トークン/コスト最適化
satohy0323
0
370
SRE Next 2026 何でも屋からの脱却
bto
0
680
Featured
See All Featured
Leading Effective Engineering Teams in the AI Era
addyosmani
9
2.1k
Winning Ecommerce Organic Search in an AI Era - #searchnstuff2025
aleyda
1
2.1k
Building AI with AI
inesmontani
PRO
1
1.1k
Scaling GitHub
holman
464
140k
How to Build an AI Search Optimization Roadmap - Criteria and Steps to Take #SEOIRL
aleyda
1
2.1k
Lightning Talk: Beautiful Slides for Beginners
inesmontani
PRO
2
600
WENDY [Excerpt]
tessaabrams
11
38k
Noah Learner - AI + Me: how we built a GSC Bulk Export data pipeline
techseoconnect
PRO
0
220
16th Malabo Montpellier Forum Presentation
akademiya2063
PRO
0
200
Future Trends and Review - Lecture 12 - Web Technologies (1019888BNR)
signer
PRO
0
3.6k
Unlocking the hidden potential of vector embeddings in international SEO
frankvandijk
0
870
The agentic SEO stack - context over prompts
schlessera
0
840
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