Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
KtorでおうちAPIをリプレースした話
Search
yagi2
December 18, 2017
Programming
1.2k
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
KtorでおうちAPIをリプレースした話
2017/12/18 CA.kt #5 @大阪 LT
yagi2
December 18, 2017
More Decks by yagi2
See All by yagi2
モバイルアプリエンジニアの生存戦略
yagi2
0
400
Kotlin DSLを理解してみる / Understanding Kotlin DSL
yagi2
4
2.7k
おうちにAPIを生やすお話.pdf
yagi2
0
530
略解 The Navigation Architecture Component
yagi2
1
280
10分で完全に(雰囲気を)理解するマテリアルデザイン
yagi2
1
490
Other Decks in Programming
See All in Programming
S3 TablesのIcebergデータに、AIエージェントからアクセスしてみた / 20261016developersio2026joetsu-accessing-iceberg-in-s3tables-via-agent
kasacchiful
PRO
0
230
Domain-Driven Transformation
hschwentner
2
2.4k
golang-bob.pdf
iwatsukayura
0
150
Event is what happens
moro
2
1.9k
Vue.jsで作る空間解析アプリとCapacitorプラグインのData Bridge
hal_spidernight
1
130
Performance Optimization With LLMs
xleitix
0
220
AI Augmentation Techniques with Liberty
ivargrimstad
0
140
Jetpack Compose Mechanisms
skydoves
3
900
Next.js: The final boss of Web Performance
guaca
0
360
クラウドエージェントは、 何がそんなに便利なのか / what makes cloud agents so useful
rkaga
3
620
全ての永続トークンを、生まれる前に消し去りたい!
sylph01
2
1.5k
sbt 2.0: takeoff
eed3si9n
0
180
Featured
See All Featured
Lightning Talk: Beautiful Slides for Beginners
inesmontani
PRO
2
750
Making Projects Easy
brettharned
120
6.8k
BBQ
matthewcrist
90
10k
Ecommerce SEO: The Keys for Success Now & Beyond - #SERPConf2024
aleyda
1
2.2k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
27k
sira's awesome portfolio website redesign presentation
elsirapls
0
480
KATA
mclloyd
PRO
35
16k
Gemini Prompt Engineering: Practical Techniques for Tangible AI Outcomes
mfonobong
2
600
Navigating Algorithm Shifts & AI Overviews - #SMXNext
aleyda
1
1.7k
The Hidden Cost of Media on the Web [PixelPalooza 2025]
tammyeverts
2
540
Facilitating Awesome Meetings
lara
57
7.2k
[RailsConf 2023] Rails as a piece of cake
palkan
59
7.1k
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!