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
1.9k
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
69
Preparing for the future of API Description Languages
kylef
0
85
Resilient API Design
kylef
1
290
Testing without Xcode - CMD+U 2016
kylef
0
220
End-to-end: Building a Web Service in Swift (MCE 2016)
kylef
2
450
Designing APIs for Humans - Write the Docs 2016
kylef
0
280
Embracing Change - MBLTDev 2015
kylef
3
640
Practical Declarative Programming (360 iDev 2015)
kylef
3
460
Building Resilient API Clients (SLUG)
kylef
2
13k
Other Decks in Technology
See All in Technology
KnowledgeBaseDocuments APIでベクトルインデックス管理を自動化する
iidaxs
1
270
コンテナセキュリティのためのLandlock入門
nullpo_head
2
320
ゼロから創る横断SREチーム 挑戦と進化の軌跡
rvirus0817
2
270
podman_update_2024-12
orimanabu
1
280
私なりのAIのご紹介 [2024年版]
qt_luigi
1
120
バクラクのドキュメント解析技術と実データにおける課題 / layerx-ccc-winter-2024
shimacos
2
1.1k
PHP ユーザのための OpenTelemetry 入門 / phpcon2024-opentelemetry
shin1x1
1
560
DevOps視点でAWS re:invent2024の新サービス・アプデを振り返ってみた
oshanqq
0
180
終了の危機にあった15年続くWebサービスを全力で存続させる - phpcon2024
yositosi
19
18k
2024年にチャレンジしたことを振り返るぞ
mitchan
0
140
事業貢献を考えるための技術改善の目標設計と改善実績 / Targeted design of technical improvements to consider business contribution and improvement performance
oomatomo
0
100
LINEヤフーのフロントエンド組織・体制の紹介【24年12月】
lycorp_recruit_jp
0
530
Featured
See All Featured
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
95
17k
Designing for humans not robots
tammielis
250
25k
Fashionably flexible responsive web design (full day workshop)
malarkey
405
66k
Bootstrapping a Software Product
garrettdimon
PRO
305
110k
Being A Developer After 40
akosma
87
590k
Site-Speed That Sticks
csswizardry
2
190
Reflections from 52 weeks, 52 projects
jeffersonlam
347
20k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
251
21k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
330
21k
How to Ace a Technical Interview
jacobian
276
23k
No one is an island. Learnings from fostering a developers community.
thoeni
19
3k
The Power of CSS Pseudo Elements
geoffreycrofte
73
5.4k
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