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
KtorでおうちAPIをリプレースした話
Search
yagi2
December 18, 2017
Programming
1
1.1k
KtorでおうちAPIをリプレースした話
2017/12/18 CA.kt #5 @大阪 LT
yagi2
December 18, 2017
Tweet
Share
More Decks by yagi2
See All by yagi2
Kotlin DSLを理解してみる / Understanding Kotlin DSL
yagi2
4
2.5k
おうちにAPIを生やすお話.pdf
yagi2
0
490
略解 The Navigation Architecture Component
yagi2
1
230
10分で完全に(雰囲気を)理解するマテリアルデザイン
yagi2
1
440
Other Decks in Programming
See All in Programming
uniqueパッケージの内部実装を支えるweak pointerの話
magavel
0
940
Domain-centric? Why Hexagonal, Onion, and Clean Architecture Are Answers to the Wrong Question
olivergierke
2
630
iOSエンジニア向けの英語学習アプリを作る!
yukawashouhei
0
180
After go func(): Goroutines Through a Beginner’s Eye
97vaibhav
0
240
CSC305 Lecture 06
javiergs
PRO
0
210
デミカツ切り抜きで面倒くさいことはPythonにやらせよう
aokswork3
0
210
あなたの知らない「動画広告」の世界 - iOSDC Japan 2025
ukitaka
0
430
ネイティブ製ガントチャートUIを作って学ぶUICollectionViewLayoutの威力
jrsaruo
0
140
Go言語の特性を活かした公式MCP SDKの設計
hond0413
1
200
iOS 17で追加されたSubscriptionStoreView を利用して5分でサブスク実装チャレンジ
natmark
0
650
私はどうやって技術力を上げたのか
yusukebe
43
18k
AI Coding Meetup #3 - 導入セッション / ai-coding-meetup-3
izumin5210
0
630
Featured
See All Featured
Visualization
eitanlees
148
16k
[RailsConf 2023] Rails as a piece of cake
palkan
57
5.9k
Code Review Best Practice
trishagee
72
19k
GraphQLとの向き合い方2022年版
quramy
49
14k
The Pragmatic Product Professional
lauravandoore
36
6.9k
Designing for humans not robots
tammielis
254
26k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
29
2.6k
Done Done
chrislema
185
16k
Scaling GitHub
holman
463
140k
Music & Morning Musume
bryan
46
6.8k
Producing Creativity
orderedlist
PRO
347
40k
Fashionably flexible responsive web design (full day workshop)
malarkey
407
66k
Transcript
torͰ͓͏ͪAPI ɹΛϦϓϨʔεͨ͠ 2017/12/18 CA.kt #5 @େࡕ Itsuki AOYAGI
͍͋ͭ͝͞ - ࣗݾհ - • ໊લ : ੨༄ थ Itsuki
AOYAGIʢ23ʣ a.k.a ͗ʹ͍ • AndroidΞϓϦΤϯδχΞ • Kotlinྺ : • Twitter : @yaginier • GitHub etc… : @yagi2 / @yagi21 • ͓͏͍͖ͪͩ͢
͍͋ͭ͝͞ - ࣗݾհ - • ໊લ : ੨༄ थ Itsuki
AOYAGIʢ23ʣ a.k.a ͗ʹ͍ • AndroidΞϓϦΤϯδχΞ • Kotlinྺ : • Twitter : @yaginier • GitHub etc… : @yagi2 / @yagi21 • ͓͏͍͖ͪͩ͢
͓͏ͪϋοΫͯ͠·͔͢ʁ
͓͏ͪϋοΫ ͓͏ͪΛΑΓշదͳͷʹ͢ΔͨΊʹ ΨδΣοταʔϏεΛΈ߹Θͤͯ ϋοϐʔʹ͢ΔͨΊͷ͋Ε͜Ε ɻ ࠷ۙͩͱεϚʔτεϐʔΧʔ͕͍ͬͺ͍͋ΔͷͰ ͦΕΒܦ༝ͰՈిͱ͔Λૢ࡞Ͱ͖Δɻ
͓͏ͪϋοΫ - զ͕Ո - ɾRaspberry Piʢॳʣ ɹˠ ͓͏ͪAPI͕͍͑ͯΔʢPHPʣ ɹɹˠ ϒϥβ͔ΒHTTPSܦ༝ͯ͠ϖʔδ͔Βୟ͘
ɹɹˠ ࣗ࡞ͷAndroidΞϓϦ͔ΒϦΫΤετ Ұྫ ɾࣗͷσεΫτοϓPCͷిݯΛ֎͔ΒೖΕΔ ɾΤΞίϯɺςϨϏͷ֎ઢͰૢ࡞͢ΔՈిͷૢ࡞ ɾϥδΦʢRasPiΛrtmpετϦʔϛϯάͬͯϥδΦʹ͍ͯͨ͠ʣ
͓͏ͪϋοΫ - զ͕Ո - ɾRaspberry Piʢॳʣ ɹˠ ͓͏ͪAPI͕͍͑ͯΔʢPHPʣ ɹɹˠ ϒϥβ͔ΒHTTPSܦ༝ͯ͠ϖʔδ͔Βୟ͘
ɹɹˠ ࣗ࡞ͷAndroidΞϓϦ͔ΒϦΫΤετ Ұྫ ɾࣗͷσεΫτοϓPCͷిݯΛ֎͔ΒೖΕΔ ɾΤΞίϯɺςϨϏͷ֎ઢͰૢ࡞͢ΔՈిͷૢ࡞ ɾϥδΦʢRasPiΛrtmpετϦʔϛϯάͬͯϥδΦʹ͍ͯͨ͠ʣ
͓͏ͪϋοΫ - զ͕Ո - ɾRaspberry Piʢॳʣ ɹˠ ͓͏ͪAPI͕͍͑ͯΔʢPHPʣ ɹɹˠ ϒϥβ͔ΒHTTPSܦ༝ͯ͠ϖʔδ͔Βୟ͘
ɹɹˠ ࣗ࡞ͷAndroidΞϓϦ͔ΒϦΫΤετ Ұྫ ɾࣗͷσεΫτοϓPCͷిݯΛ֎͔ΒೖΕΔ ɾΤΞίϯɺςϨϏͷ֎ઢͰૢ࡞͢ΔՈిͷૢ࡞ ɾϥδΦʢRasPiΛrtmpετϦʔϛϯάͬͯϥδΦʹ͍ͯͨ͠ʣ ͍ͭ͜ΛKotlinʹॻ͖͑Δ
αʔόʔαΠυ Kotlin
αʔόʔαΠυKotlin ɾSpring Boot ɹҎલKotlin + Spring BootͰJSONΛు͘APIΛ࡞ͬͨ͜ͱ͕͋Δ ɹ ͦͷ࣌ͷϒϩά →
KotlinͱSpring BootΛͬͯαΫοͱୟ͚ΔAPIΛ࡞Δ ɾKotr ɹΊͬͪΌബ͍ ɹ ɹKtor is a framework for quickly creating web applications in Kotlin with minimal effort.
Ktor fun main(args: Array<String>) { embeddedServer(Netty, 8080) { routing {
get("/") { call.respondText("Hello, world!", ContentType.Text.Html) } } }.start(wait = true) } ɾബ͗ͯ͢README͕͍ ɹɹɹɹউखͳΠϝʔδ ɹɹɹɹɹɹɹSpringBoot → Ruby on Rails ɹɹɹɹɹɹɹKtor → Sinatra
Ktor - WoL API - KtorΛͬͯɺࣗPCͷిݯΛ֎͔ΒೖΕΔAPIΛॻ͖͢ ݱࡏͷ༷ ɾΫϥΠΞϯτPOSTͰରͷMacΞυϨεΛ͛Δ ɾαʔόʔड͚औͬͨΒͦͷMacΞυϨεʹରͯ͠WoL͢Δ ɹʢexecͰwakeonlanίϚϯυΛୟ͍͍ͯΔʣ
Ktor - WoL API - KtorΛͬͯɺࣗPCͷిݯΛ֎͔ΒೖΕΔAPIΛॻ͖͢ ৽͍༷͠ ɾΫϥΠΞϯτPOSTͰରͷϗετ໊Λ͛Δ ɹˠ ϗετ໊ͦΕʹ४ͣΔͷʢཧ༝ޙड़ʣΛ͛Δ
ɹˠ DBαʔόʔଆͰϗετ໊ͱMacΞυϨεΛ͓͍࣋ͬͯͯࢀর ɾαʔόʔड͚औͬͨΒରʹରͯ͠WoL͢Δ ɹ͔ͤͬ͘ͳͷͰϚδοΫύέοτૹ৴Λ࣮͢Δ
Ktor - WoL API - install(Routing) { post("/wol") { val
name = call.receiveParameters()[“name”] val host = ϗετΛDB͔Βݕࡧ(name) if (host == null) { call.respond("ݟ͔ͭΒͳ͔ͬͨ") } else { try { WakeOnLan(host.macAddr).sendMagicPacket() call.respond("ૹͬͨ") } catch (e: IOException) { call.respond("ૹΔͷʹࣦഊͨ͠") } } } ɾPOSTͰड͚औͬͯϚδοΫύέοτΛૹΔ ɹˠ Ͳͷϗετʹରͯ͠ϚδοΫύέοτΛૹΔͷ͔ύϥϝʔλͰ ɹˠ DBʹExposed + MySQLΛ༻
Ktor - WoL API - install(Routing) { post("/wol") { val
name = call.receiveParameters()[“name”] val host = ϗετΛDB͔Βݕࡧ(name) if (host == null) { call.respond("ݟ͔ͭΒͳ͔ͬͨ") } else { try { WakeOnLan(host.macAddr).sendMagicPacket() call.respond("ૹͬͨ") } catch (e: IOException) { call.respond("ૹΔͷʹࣦഊͨ͠") } } } ɾPOSTͰड͚औͬͯϚδοΫύέοτΛૹΔ ɹˠ Ͳͷϗετʹରͯ͠ϚδοΫύέοτΛૹΔͷ͔ύϥϝʔλͰ ɹˠ DBʹExposed + MySQLΛ༻
Ktor - WoL API - install(Routing) { post("/wol") { val
name = call.receiveParameters()[“name”] val host = ϗετΛDB͔Βݕࡧ(name) if (host == null) { call.respond("ݟ͔ͭΒͳ͔ͬͨ") } else { try { WakeOnLan(host.macAddr).sendMagicPacket() call.respond("ૹͬͨ") } catch (e: IOException) { call.respond("ૹΔͷʹࣦഊͨ͠") } } } ɾPOSTͰड͚औͬͯϚδοΫύέοτΛૹΔ ɹˠ Ͳͷϗετʹରͯ͠ϚδοΫύέοτΛૹΔͷ͔ύϥϝʔλͰ ɹˠ DBʹExposed + MySQLΛ༻ object Computers : IntIdTable() { val hostName = varchar("hostname", 50).index() val macAddr = varchar("mac_addr", 50) } class Computer(id: EntityID<Int>) : IntEntity(id) { companion object : IntEntityClass<Computer>(Computers) var hostname by Computers.hostName var macAddr by Computers.macAddr } fun findByHostName(hostName: String?): Computer? { return transaction { Computer.find { Computers.hostName eq hostName }.firstOrNull() } }
Ktor - WoL API - install(Routing) { post("/wol") { val
name = call.receiveParameters()[“name”] val host = ϗετΛDB͔Βݕࡧ(name) if (host == null) { call.respond("ݟ͔ͭΒͳ͔ͬͨ") } else { try { WakeOnLan(host.macAddr).sendMagicPacket() call.respond("ૹͬͨ") } catch (e: IOException) { call.respond("ૹΔͷʹࣦഊͨ͠") } } } ɾPOSTͰड͚औͬͯϚδοΫύέοτΛૹΔ ɹˠ Ͳͷϗετʹରͯ͠ϚδοΫύέοτΛૹΔͷ͔ύϥϝʔλͰ ɹˠ DBʹExposed + MySQLΛ༻
Ktor - WoL API - class WakeOnLan(private val macAddress: String)
{ @Throws(IOException::class) fun sendMagicPacket() { val iNetAddress = InetAddress.getByName("255.255.255.255") val magicPacket = getMagicPacket(macAddress) DatagramSocket().send(DatagramPacket(magicPacket, magicPacket.size, iNetAddress, 8080)) } private fun getMagicPacket(macAddress: String): ByteArray { val packet = ByteArray(102) var index = 0 repeat(6) { packet[index++] = 0xFF.toByte() } val macAddressByte = getMacAddressByte(macAddress) repeat(16) { repeat(6) { packet[index++] = macAddressByte[it] } } return packet } private fun getMacAddressByte(macAddress: String): ByteArray = macAddress.split(":").map { Integer.parseInt(it, 16).toByte() }.toByteArray() }
ʂ ͨ͠ͷͰɺGoogleHome͔Β͑ΔΑ͏ʹ͢Δ
Google Home + IFTTT Google HomeͷԻίϚϯυͰIFTTTͷτϦΨʔΛୟ͍ͯ IFTTTWebHookͰ͓ՈAPIʹPOST͢Δ
Google Home + IFTTT ී௨ʹϓϩάϥϜ͔ΒPOST͢Δͱ͖ $ curl --data-urlencode "name=hoge"
http://api.example.com/wol Google Homeͩͱ”name=hoge”͕ͭΒ͍ ɹˠ ຊޠͰͷΤΠϦΞεΛ͚ͯDBͷΧϥϜʹೖΕ͓ͯ͘ ྫʣʮͶ͐ɺGoogle ͏ͪͷ͜ͱΓΛىͯ͜͠ʯ ɹɹˠ name=͜ͱΓ ɹɹˠ DB͔Βʮ͜ͱΓʯͰҰக͢ΔͷΛݕࡧͯ͠Δ
Google Home + IFTTT object Computers : IntIdTable() { val
hostName = varchar("hostname", 50).index() val macAddr = varchar("mac_addr", 50) } class Computer(id: EntityID<Int>) : IntEntity(id) { companion object : IntEntityClass<Computer>(Computers) var hostname by Computers.hostName var macAddr by Computers.macAddr } fun findByHostName(hostName: String?): Computer? { return transaction { Computer.find { Computers.hostName eq hostName }.firstOrNull() } } object Computers : IntIdTable() { val hostName = varchar("hostname", 50).index() val name = varchar("name", 50) val macAddr = varchar("mac_addr", 50) } class Computer(id: EntityID<Int>) : IntEntity(id) { companion object : IntEntityClass<Computer>(Computers) var hostname by Computers.hostName var name by Computers.name var macAddr by Computers.macAddr } fun findByHostName(hostName: String?): Computer? { return transaction { Computer.find { Computers.hostName eq hostName }.firstOrNull() } } fun findByName(name: String?): Computer? { return transaction { Computer.find { Computers.name eq name }.firstOrNull() } }
Google Home + IFTTT transaction { Computer.new { hostname =
"kotori" name = "͜ͱΓ" macAddr = “FF:FF:FF:FF:FF:FF” } } ͓Ոʹ͋ΔϚγϯΛDBʹೖΕͯ͋͛Δɻ $ curl --data-urlencode "name=kotori" http://api.example.com:/wol ʮͶ͐ɺGoogle ͓͏ͪͷ͜ͱΓΛىͯ͜͠ʯ ✨྆ํڞOK✨
Google Home + IFTTT ҙ ʮͶ͐ɺGoogle ͏ͪͷ͜ͻͳͨΛىͯ͜͠ʯ → ͬͯ͘Δ໊લ͕ʮ͜ ͻͳ
ͨʯ ʮͶ͐ɺGoogle ͏ͪͷͪΌͪΌΛىͯ͜͠ʯ → ͬͯ͘Δ໊લ͕ʮʑʯ ղܾࡦ → 1ճࢼͯ͠Կ͕ͬͯ͘Δͷ͔ΛݟΔ
ຊͷ͓͠ͳ͕͖ ɾAPI ɹˠ https://github.com/yagi2/Kaya ɾKtor ɹˠ https://github.com/ktorio/ktor ɾExposed ɹˠ https://github.com/JetBrains/Exposed
Have a Nice Kotlin!