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
450
Other Decks in Programming
See All in Programming
3年ぶりにコードを書いた元CTOが Claude Codeと30分でMVPを作った話
maikokojima
0
650
オープンソースソフトウェアへの解像度🔬
utam0k
17
3.2k
CSC305 Lecture 09
javiergs
PRO
0
320
O Que É e Como Funciona o PHP-FPM?
marcelgsantos
0
210
What Spring Developers Should Know About Jakarta EE
ivargrimstad
0
530
AI駆動で0→1をやって見えた光と伸びしろ
passion0102
1
870
三者三様 宣言的UI
kkagurazaka
0
280
テーブル定義書の構造化抽出して、生成AIでDWH分析を試してみた / devio2025tokyo
kasacchiful
0
320
React Nativeならぬ"Vue Native"が実現するかも?_新世代マルチプラットフォーム開発フレームワークのLynxとLynxのVue.js対応を追ってみよう_Vue Lynx
yut0naga1_fa
2
1.8k
One Enishi After Another
snoozer05
PRO
0
170
チームの境界をブチ抜いていけ
tokai235
0
230
Claude Agent SDK を使ってみよう
hyshu
0
1.4k
Featured
See All Featured
Learning to Love Humans: Emotional Interface Design
aarron
274
41k
Faster Mobile Websites
deanohume
310
31k
Optimizing for Happiness
mojombo
379
70k
Designing for humans not robots
tammielis
254
26k
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
9
930
Product Roadmaps are Hard
iamctodd
PRO
55
11k
Embracing the Ebb and Flow
colly
88
4.9k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
32
1.7k
Code Review Best Practice
trishagee
72
19k
Stop Working from a Prison Cell
hatefulcrawdad
272
21k
Automating Front-end Workflow
addyosmani
1371
200k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
31
2.6k
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!