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
はじめてのSwift Server API / Beginning Swift Server API
Search
Shun Takebayashi
September 15, 2017
Programming
1
580
はじめてのSwift Server API / Beginning Swift Server API
Shun Takebayashi
September 15, 2017
Tweet
Share
More Decks by Shun Takebayashi
See All by Shun Takebayashi
Introduction of Swift HTTP APIs
takebayashi
0
310
The Ecosystem of Web Development with Swift
takebayashi
4
1.3k
Other Decks in Programming
See All in Programming
地方に住むエンジニアの残酷な現実とキャリア論
ichimichi
5
1.5k
#kanrk08 / 公開版 PicoRubyとマイコンでの自作トレーニング計測装置を用いたワークアウトの理想と現実
bash0c7
1
660
Is Xcode slowly dying out in 2025?
uetyo
1
240
設計やレビューに悩んでいるPHPerに贈る、クリーンなオブジェクト設計の指針たち
panda_program
6
1.8k
AWS CDKの推しポイント 〜CloudFormationと比較してみた〜
akihisaikeda
3
320
データの民主化を支える、透明性のあるデータ利活用への挑戦 2025-06-25 Database Engineering Meetup#7
y_ken
0
340
deno-redisの紹介とJSRパッケージの運用について (toranoana.deno #21)
uki00a
0
170
生成AIコーディングとの向き合い方、AIと共創するという考え方 / How to deal with generative AI coding and the concept of co-creating with AI
seike460
PRO
1
350
童醫院敏捷轉型的實踐經驗
cclai999
0
210
たった 1 枚の PHP ファイルで実装する MCP サーバ / MCP Server with Vanilla PHP
okashoi
1
220
datadog dash 2025 LLM observability for reliability and stability
ivry_presentationmaterials
0
400
PHPでWebSocketサーバーを実装しよう2025
kubotak
0
240
Featured
See All Featured
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
138
34k
How to Ace a Technical Interview
jacobian
277
23k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
29
1.8k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
29
2.7k
Being A Developer After 40
akosma
90
590k
Unsuck your backbone
ammeep
671
58k
A Modern Web Designer's Workflow
chriscoyier
694
190k
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
7
720
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
657
60k
Optimizing for Happiness
mojombo
379
70k
RailsConf 2023
tenderlove
30
1.1k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
32
2.4k
Transcript
͡ΊͯͷSwift Server API Shun Takebayashi
ΞδΣϯμ • Swift Server APIͱ • HTTP APIͱ • αϯϓϧʹֶͿHTTP
API • HTTP APIͷݱঢ় • ·ͱΊ
Swift Server APIͱ
Swift Server APIͱ αʔόʔαΠυͰඞཁͱͳΔίϯϙʔωϯτΛඪ४Խͨ͠APIͷ૯শ
Swift Server APIͱ త • ૬ޓӡ༻ੑͷ֬อ • ϚϧνϓϥοτϑΥʔϜͷରԠ
Swift Server APIͱ Χόʔ͢ΔྖҬ • ωοτϫʔΫ • ηΩϡϦςΟ • HTTP
Swift Server APIͱ Χόʔ͢ΔྖҬ • ωοτϫʔΫ • ηΩϡϦςΟ • HTTP
HTTP APIͱ
HTTP APIͱ αʔόʔαΠυͰಈ͘HTTPΞϓϦέʔγϣϯͷͨΊͷجຊతͳίϯϙʔωϯτ • ܕΠϯλʔϑΣʔε • σϑΥϧτͷ࣮ ΣϒΞϓϦέʔγϣϯϑϨʔϜϫʔΫͰͳ͍
HTTP APIͱ ΞϓϦέʔγϣϯ ϦΫΤετ Ϩεϙϯε αʔό ϦΫΤετ Ϩεϙϯε ΫϥΠΞϯτ
HTTP APIͱ ΞϓϦέʔγϣϯ ϦΫΤετ Ϩεϙϯε αʔό ϦΫΤετ Ϩεϙϯε ΫϥΠΞϯτ
HTTP APIͱ HTTPRequestHandler HTTPRequest HTTPResponseStatus, … HTTPServing ϦΫΤετ Ϩεϙϯε ΫϥΠΞϯτ
HTTP APIͱ public typealias HTTPRequestHandler = (HTTPRequest, HTTPResponseWriter) -> HTTPBodyProcessing
public protocol HTTPServing : class { func start(port: Int, handler: @escaping HTTPRequestHandler) throws // ... }
αϯϓϧʹֶͿHTTP API
let app: HTTPRequestHandler = { (request, responseWriter) in let headers:
HTTPHeaders = ["Content-Type": "text/plain"] responseWriter.writeHeader(status: .ok, headers: headers) responseWriter.writeBody("Hello, world!") return .discardBody }
let app: HTTPRequestHandler = { (request, responseWriter) in let headers:
HTTPHeaders = ["Content-Type": "text/plain"] responseWriter.writeHeader(status: .ok, headers: headers) responseWriter.writeBody("Hello, world!") return .discardBody }
let app: HTTPRequestHandler = { (request, responseWriter) in let headers:
HTTPHeaders = ["Content-Type": "text/plain"] responseWriter.writeHeader(status: .ok, headers: headers) responseWriter.writeBody("Hello, world!") return .discardBody }
let app: HTTPRequestHandler = { (request, responseWriter) in let headers:
HTTPHeaders = ["Content-Type": "text/plain"] responseWriter.writeHeader(status: .ok, headers: headers) responseWriter.writeBody("Hello, world!") return .discardBody }
try! HTTPServer().start(port: 8080, handler: app)
let app: HTTPRequestHandler = { (request, responseWriter) in responseWriter.writeHeader(status: .ok)
return .processBody { (chunk, stop) in switch chunk { case .chunk(let data, let finishedProcessing): responseWriter.writeBody(data) { _ in finishedProcessing() } case .end: responseWriter.done() default: stop = true responseWriter.abort() } } }
let app: HTTPRequestHandler = { (request, responseWriter) in responseWriter.writeHeader(status: .ok)
return .processBody { (chunk, stop) in switch chunk { case .chunk(let data, let finishedProcessing): responseWriter.writeBody(data) { _ in finishedProcessing() } case .end: responseWriter.done() default: stop = true responseWriter.abort() } } }
let app: HTTPRequestHandler = { (request, responseWriter) in responseWriter.writeHeader(status: .ok)
return .processBody { (chunk, stop) in switch chunk { case .chunk(let data, let finishedProcessing): responseWriter.writeBody(data) { _ in finishedProcessing() } case .end: responseWriter.done() default: stop = true responseWriter.abort() } } }
let app: HTTPRequestHandler = { (request, responseWriter) in responseWriter.writeHeader(status: .ok)
return .processBody { (chunk, stop) in switch chunk { case .chunk(let data, let finishedProcessing): responseWriter.writeBody(data) { _ in finishedProcessing() } case .end: responseWriter.done() default: stop = true responseWriter.abort() } } }
let app: HTTPRequestHandler = { (request, responseWriter) in responseWriter.writeHeader(status: .ok)
return .processBody { (chunk, stop) in switch chunk { case .chunk(let data, let finishedProcessing): responseWriter.writeBody(data) { _ in finishedProcessing() } case .end: responseWriter.done() default: stop = true responseWriter.abort() } } }
let app: HTTPRequestHandler = { (request, responseWriter) in responseWriter.writeHeader(status: .ok)
return .processBody { (chunk, stop) in switch chunk { case .chunk(let data, let finishedProcessing): responseWriter.writeBody(data) { _ in finishedProcessing() } case .end: responseWriter.done() default: stop = true responseWriter.abort() } } }
let app: HTTPRequestHandler = { (request, responseWriter) in responseWriter.writeHeader(status: .ok)
return .processBody { (chunk, stop) in switch chunk { case .chunk(let data, let finishedProcessing): responseWriter.writeBody(data) { _ in finishedProcessing() } case .end: responseWriter.done() default: stop = true responseWriter.abort() } } }
try! HTTPServer().start(port: 8080, handler: app)
public typealias HTTPBodyHandler = (HTTPBodyChunk, inout Bool) -> Void public
enum HTTPBodyProcessing { case discardBody case processBody(handler: HTTPBodyHandler) } public enum HTTPBodyChunk { case chunk(data: DispatchData, finishedProcessing: ()-> Void) case end // ... }
αϯϓϧʹֶͿHTTP API جຊతͳྲྀΕ • HTTPRequestHandlerΛ࣮͢Δ • HTTPRequestΛड͚औΓɺHTTPResponseWriterʹॻ͖ࠐΉ • ϦΫΤετϘσΟΛॲཧ͢Δ߹HTTPBodyHandlerΛ࣮͢Δ •
ෳճ࣮ߦ͞ΕΔՄೳੑ͕͋Δ (Chunked Transfer)
HTTP APIͷݱঢ়
HTTP APIͷݱঢ় ਖ਼ࣜϦϦʔεલ ·ͩਖ਼ࣜϦϦʔε͞Ε͓ͯΒͣɺʑվળ͞Ε͍ͯΔ • https://github.com/swift-server/http •
[email protected]
ഁյతͳมߋ͕ߦΘΕΔՄೳੑ͋Δ
HTTP APIͷݱঢ় HTTP APIʹґଘͨ͠ΞϓϦέʔγϣϯͷϏϧυํ๏ λά͕ৼΒΕ͍ͯͳ͍ͨΊɺSwift 4ͷPackage Manager͕ඞཁ let package =
Package( name: "swift-http-example", dependencies: [ .package(url: "https://github.com/swift-server/http.git", .branch("develop")), ], targets: [ .target(name: "swift-http-example", dependencies: ["SwiftServerHTTP"]), ] )
·ͱΊ
·ͱΊ • Swift Server APIϙʔλϒϧͳαʔόʔαΠυSwiftΛ࣮ݱ͢ΔͨΊͷAPI • HTTP APIHTTPΞϓϦέʔγϣϯͷͨΊͷڞ௨ΠϯλʔϑΣʔε • ΞϓϦέʔγϣϯHTTPRequestHandlerΛ࣮
• αʔόʔHTTPServingΛ࣮ • ҙͷαʔόʔͱΞϓϦέʔγϣϯΛΈ߹Θ࣮ͤͯߦՄೳ • ·ͩਖ਼ࣜϦϦʔεલͷ༷Ͱ͋ΓɺMLͰٞͷࢀՃ͕Մೳ