DroidKaigi2019に参加しました

DroidKaigi2019に参加することが出来たので、感想を書いておきます。

聴講したセッション

1日目

  • ウェルカムトーク
  • マルチモジュールなプロジェクトでテストはどう変わる?
  • マルチモジュールプロジェクトでのDagger2を用いたDependency Injection
  • Server-side Kotlin for Frontend: 複雑なAndroidアプリ開発に対するアプローチ
  • PWAでここまで出来る
  • Exploring the Android Transform API
  • Fireside chat && 懇親会

2日目

  • build.gradle.ktsに移行しよう
  • 夕飯

ウェルカムトーク

動画カッコ良かった。あとで納品されたのが当日9:30頃でめっちゃヒヤヒヤしたという話をtnjさんがしてて、ウケた。

それと、mhidakaさんのマイクがなんか変な音がしてて、聴きづらく、少し我慢してたのですが、誰も反応してないし、意を決してツイートしたら即対応してもらえた。(実際は自分のツイート起因なのかは不明だけど、嬉しかったので、そういうことにしておこうw)

マルチモジュールなプロジェクトでテストはどう変わる?

登壇者のテストが好きだというのがにじみ出ているようなトークでした。本当にテスト好きなんだなこの人!ってワクワクして聴かせてもらいました。 内容としては、DeNAさんのものなのかわからなかったですが、テストの方針やモジュールをどのようにテストするのか?とPITの紹介という感じでした。 わかりやすく噛み砕いてくれて、かなり参考になりました。スライドがシンプルで良かったです。

前半部分の方針の説明だったのですが、もう少し具体例が欲しかったかなと思いました。 方針の説明だから仕方ないのですが、それでもコードなどを示しつつ、方針と噛み合わせてくれたらさらに深く理解出来たと思います。 PITの説明に入ったら、具体的になって、その内容の面白さに会場がすごく盛り上がっていた印象を受けました。あれは本当に良かった。

マルチモジュールプロジェクトでのDagger2を用いたDependency Injection

去年に引き続き、kgmyshin さんのマルチモジュールのお話。 去年マルチモジュールの初歩的な話をしてもらい、今回具体的な実行編って感じの二部構成!って感じで勝手に感動してました。 スライドがすごく特徴的で、うまく手書きと図を使われており、流石だー!と感じました。

また、概要説明->実コード->概要説明->実コードと本当に素晴らしい流れで、めちゃめちゃわかりやすかったです。 いやーやっぱkgmyさんすごいなーと終わった時に改めて思いました。

Server-side Kotlin for Frontend: 複雑なAndroidアプリ開発に対するアプローチ

マイクロサービスを自社で導入しており、今後拡大した時にどうなるのか?BFFはどういう助けになるのか?が知りたくて聴講しました。 FiNCさんの過去の話からBFF採用するまでなどのお話でした。辛い辛い辛いーそうだよねそうだよね!という感じで結構感情移入しちゃって聴けました。 これは完全に自分の責任なのですが、遅れて入ってきたため、後ろの席で聴いたこと+登壇直前にツイートしてもらったスライド公開が残念ながら出来ていなかったこと+スライドの文字が多かったこと と不運が重なってしまい、スライドをめくった時にスライドを読むことに注力せざるを得ず、話を聞き逃すことが若干ありました。。。 なので、登壇後に直接いくつか質問させてもらいました。丁寧に回答頂き、なるほどーって結構な回数言わせてもらいました。(今スライド見返すと回答が書いてあったので完全にアホな質問ばかりだったかもしれません。。。)

FiNCさんはFin Techってネタは爆笑しました。(FiNCさんはヘルス事業の会社です。)

PWAでここまで出来る

自社が、PWAにベットしているので、あんまり説明も読まずにタイトルだけで聴講決めました。 今年のDroidKaigiで一番バズったのでは?と思う誤発注のDiverseさん所属の方の登壇でした。 DiverseさんがAndroidのFlutterエンジニア募集してると聴いておー!Flutterここまできたかーと驚きました。

PWAの基本的な紹介があり、その後TikTokさんに似たPWAサイトを作ると言う話でした。 PWAのGoogle Playでの公開方法の説明は実は初めて知って、おおおお!!!って驚きがありました。 作ってるものは本当に良かったし、話の内容もすんなり入ってきたし、面白いなーって聴けたのですが、一つだけ悲しいこと言っちゃうとコードの文字が小さくて全然読めなかった・・・。一つ前の時間で質問していて、席が後ろになったのが敗因でした。。。

ちなみに次の日に自分が同じ部屋で登壇するということもあり、参考にさせてもらいました。

実はこの登壇者の SAMUKEI さんとは2日目にホールで自分の登壇の質問待ちでボケーっと座っていたら、見つけてもらい、話しかけてもらえました。 最初赤髪の人と目が合ったー!こっち近づいてくるー!やばいー!!!とちょっとドキドキしたのですが、話してみるとすごく気さくな方で話やすく、楽しかったです。話終わった後に、あれ?そういえばあの人PWAの登壇者だったじゃん。って思い出して、あーPWAの話もっとすれば良かったと後悔しました。またどこかでお話しさせてください。

DroidKaigi2019ではDiverseさん面白い人多いと言う印象になりました。きっと来年はmini usb -> type cの誤発注してくれるでしょう!

Exploring the Android Transform API

これに関して言うと、自分にとって今年のDroidKaigiで一番楽しかったです。あまりに楽しすぎて、感想なんて要らない、みんなとにかくこのトークの動画を観るんだ!です。 簡単に説明するとAndroidでは使えないJava9のメソッド List.of をTransform APIで作り、Androidで動かしてしまおうと言うハッキーなお話です。まじで動くところまでライブコーディングしてます。動画が待ち遠しい。

Understanding Kotlin Coroutines: コルーチンで進化するアプリケーション開発

次に mhidaka さんの 「Understanding Kotlin Coroutines: コルーチンで進化するアプリケーション開発」を聴こうとしたのですが、早めに行ったと思ったのに、立ち見になっており、立ち見できる体力なかったので、泣く泣く諦めました。mhidakaさん人気すぎるんだよ。。。

Fireside chat && 懇親会

Fireside chatを聞こう早めに乗り込んだのですが、ちょっと遠く、声が聞こえませんでした。なので、会場入ってすぐに無理して聴くのを諦め、近くにいた方達と話していました。あの会場でのFireside chatは厳しいと思います。

懇親会はある程度知ってる方と話した後、新規の方との交流開拓のため、結構ぷらぷら歩いていました。

ただ、歩いてる時に話しかけられることはやっぱりない。
↓
テーブルに止まると話しかけてもらえる。
↓
でもテーブルに止まるには何か止まる理由が必要。
↓
テーブルに皿なら置ける
↓
食事・デザート・飲み物を持ちまくる。

ということでかなり食べてしまったような気がします。。。自分から話しかけるの無理なので、どうにか出来ないものか・・・。初めての人ともいっぱい話したいんだ。おかしな性格だ。

この懇親会でPixivの方にAndroidの勉強になるお話をしてくれたら、扇子くれるというイベント?やってました。こういうの話しかけるきっかけになるので良いですね!

inside.pixiv.blog

食事で並んでいたら見かけたので、「Find Pull Requestプラグインを作りました。」と言ったら、ポカーンとされて、完全に滑ってしまったわ。辛い。ってなったのだけど、別のPixivの方が「お世話になってます。」って言ってくれて扇子出してもらいました。めっちゃ嬉しかったです。

ステッカー以外のノベルティ特に反応しない息子くんもこれは気に入ったようで、返してくれません

f:id:shiraji:20190209121332j:plain
自分の登壇のMVP

Pixivの方に伺ったのですが、この扇子、Droidくんが入っているのですが、Googleさんに権利関係で連絡したとのことで、Pixivさんやっぱりサービス特性上、著作権周りもしっかりされているんだなーと感心しました。

build.gradle.ktsに移行しよう

二日目は登壇があり、自分のセッションより前のセッションは何も聴かず、自分の登壇後はすんごい倦怠感に襲われ、セッション聴くのを諦め控え室で引きこもってました。 体力が回復しつつあったので、去年に続き、tnj さんのgradleの話を聴きました。 build.gradle.ktsへの移行方法をプロジェクト作り、一つずつ手順を教えてくれました。 また、スライドには置換で活躍する正規表現も逐次記述しており、これがあれば簡単にbuild.gradle.ktsに移行できそうと言う印象を受けました。 こう言うビルドの話大好物なので、本当に楽しかったです。

2日目、控え室でtnjさんを見つけて、Android Studio 3.3.1当日リリースの被害を受けたということで記念に写真撮ってもらいました。

特に登壇の影響なくて良かった、いや良くなかった。バグが直ってないとtnjさんが混乱してる姿が面白すぎました。

夕飯

控え室でのんびりしてたら、gfxさんがご飯どうですか?って誘ってくれました。それなら!とこの会に興味ありそうな方にも声かけて、最終的に6人でご飯食べに行かせてもらいました。結構色々な話が出来て、本当に楽しかったです。

あの中で圧倒的に自分のスキルが一番低かっただろうなーって思い知ったので、もっと技術磨かなきゃって感じでした。


さて、ここからは話変わって、自分の登壇の話になります。

登壇

今回は2日目の14:00~でした。登壇の話を書く前にCfSの話から書こうと思います。

CfS

DroidKaigiのCfSがオープンになったということで、募集要項を確認しました。

droidkaigi.jp

なんか色々カテゴリがありますが、一番重要であろう点はここかな?と理解しました。

応募に当たって以下の3点を満たしていると採択されやすくなります。

Android specific: Android 固有であること
Expertise: よく知られている情報ではなく、専門性があること
Innovation: いままでに可能でなかったことを可能にしていること、革新性があること

この三つを満たしている物をCfSに書けば通るだろうと。

  • JetPackを本番で使ったことがなく、最新のAndroid開発周りでExpertiseとInnovationを満たすのは難しそう。
  • Kotlinはもう当たり前なのでチャンスあるとしたら、Coroutineだろうけど、自分より専門性高い人が多い分野だし、競合も多そう。
  • そうなるとAndroid Studioプラグイン開発かなー?と思ったけど、これは以前NGだったし、どこのカンファレンスでも需要がないのか今まで一度も通ったことがない。

今回やっぱり無理かなーと諦めていたら、同僚がJetBrainsのIDE使っていて、あれ?この設定使ってないの?ということが偶然あって、お?そういえば普段使われていないようなAndroid Studioの設定発掘したら面白いかも?とひらめきました。

そこからちょっとPreferencesを上から全部見ていって、設定を変えることにより、どうなるのか?を調べていきました。 そしたら、知っているもの含め、10個くらい面白そうな設定が出てきたので、一人で語りながら設定変えて実演してみたら、30分くらいに収まったので、うし、これでいくか!とCfS書きました。

CfSの書き方は特に奇抜なことはせずに全部書き出しました。

2014年末からAndroid Studio v1.0.0が出てから、ほとんどの方がAndroid Studioを使ってAndroidアプリの開発をしていると思います。
IntellijをベースにしたAndroid Studioでは非常に多くの機能が存在しています。しかしあまりにも多いため、埋もれてしまっている便利な機能があるのではないのでしょうか?
このセッションでは、Android Studioの隠れた便利な機能を紹介して、Android Studioを使った開発をより快適に出来るようにお手伝いしたいと思います。

以下の知識がある方を想定しています。
* Android StudioでAndroidアプリの開発をしたことがある
* Android Studioの設定をあまり変えたことがない
* 複数人での開発を主にしている
* セッション中にすごいと思ったら「おー!」って言ってくれる

このセッションでは以下の設定の話をする想定です。独断と偏見で大半の方が触らないであろうと思った設定を中心に説明します。
* 自分専用のアクションリストを作ってみる
* !=をカッコ良く
* 通知周り
* File Color
* Kotlinのファイルフォーマット忘れ防止
* 急に別の言語書きたくなった時のストレス発散方法
* JSON書きやすくする
* Run Configurationや.ideaの共有
* Layout Editor
* Pluginのインストールの強制

しっかり話す内容全部書き出したので、当日の齟齬は無かったはず。

これでCfS通らなかったら、Ubie, incに入社しました。 - shiraji’s diaryにも書いてあるとおり、Android開発から遠ざかっていますし、そろそろDroidKaigi卒業かなとも思ってました。その後、CfS通過連絡を受けて、まだまだDroidKaigiは自分を必要としてくれてたー!って結構喜びました。

登壇前

登壇前に、音声が出るのか不安だったため、運営の方たちに確認したところ、色々調整してもらい、ランチ時間にRoom1を使わせてもらえることになりました。 あの時間にRoom1にいた人たちは「なんだこいつ?」って感じだったと思います。申し訳なかったです。ランチ中にいきなり現れて、息子の動画とAndroid Studio喋らせてるヤツいたらそりゃそうなりますわ。。。

登壇時

twitter.com

意識していた「ライブ感」が本当にうまくできるのか?がすごく心配で、それが緊張を引き起こしてました。本当にみんな「おー!」って言ってくれるかな?って。音声チェックの時のように何こいつ?みたいな反応にならないかな?って。でも運営の人たちが緊張をほぐしてくれたので、だんだん調子が出てきました。

Macを見ずに俺を見ろ

この発言みんな笑ってくれたのが本当に助かりました。これで完璧に吹っ切れることが出来たと思います。きっと「おー!」の練習しっかりやってくれると。

ただMac見なくていいとは言いましたけど、まさかその時間でOS更新しようとするツワモノが現れるとは想像してませんでした。面白すぎる。DLは家でしてきたんですよね?

「おー!」の練習

そして、本番。すっごく盛り上がってくれました。やはりかわいいは正義だ。

その後、自己紹介中に「おー!」って言われたのは全く想定してなくて面白かったです。もうこの時には緊張なんて全くなく、全力で楽しんでいました。いい雰囲気でした。

Android Studioがしゃべった!

この辺、ライブ感満載で最高です。

Kotlinのスタイル設定

Kotlin Repositoryがこれを導入していたので、この設定は知っていたんです。でもこれが盛り上がるってことはみんなKotlinのコントリビュート環境整備してないってことなので実は寂しい!!!

コンディション設定してたのに間違って消しちゃうやつ!

この設定見つけた時すごく興奮した覚えがあります。というかこれ本当にデフォルトにしてほしい!

Inject Language

Inject Language自体が理解するの難しい機能で、それを説明して、その特定の不便さを説明して、それを解消する設定の説明っていう周りくどい感じだったんですよね。。。それを takahirom さん的確に説明してくれていて、さすがー!って思いました。

Prefer XML editor

推し

Notification出過ぎ

再起動中祈ったのに、結局いっぱい出てくれちゃって、あー!もー!!!って感じでした。練習ではもう一回再起動したりしてたのですが、なんか会場盛り上がっちゃったから、このままでいいかーって感じで流しちゃいましたwライブって感じ。

ツイートしてる暇がなかった

狙い通りです!

予約投稿

Twitterへの予約投稿は身内?であるたろうさんが反応してくれてました。本当にテレビの副音声みたいな機能に出来たらなーって思ってたので、嬉しい。

副音声ツイートは SocialDog さんを使わせてもらいました。TweetDeckで当初やる予定だったのですが、投稿予定だったツイートを確認する術がわからなかったため、選定出来ませんでした。

Room1がトレンド入り

登壇直後にハッシュタグ #Room1 がトレンド入りをしたと連絡もらいました。記念にスクショ撮っておきました。

f:id:shiraji:20190210042632p:plain

トレンドのロジックを全く理解していないのですが、Room1はそもそも各時間一番人が入るし、直前があのMotionLayoutのお話だし、いまいち何かを達成した感がないです。(そもそもTwitterじゃなくて俺を見てくれ!って話だったわけで・・・)

入れなかった方がいた・・・

開始直前まであのRoom1が満員になるなんて想像してなかったです。1部屋に入っていい人数って法律で決まっていると思うので、運営の方たちも自分もどうしようもできないので、ごめんなさい!としか言えないです。希望者全員に聴いて欲しかった。ライブ感をものすごく押し出していたので、furusinさんや他にもし会場入れなかった人がいらっしゃったなら、配慮が足りてなかったかもしれないです。本当に申し訳ないです。。。

登壇後

登壇後、良く見るすごい人たちが集まってきて「どうやって設定共有するの?」という質問を受けました。みんな同じ疑問を持っていたようです。

話を登壇中に戻すと、当初全ての説明が終わっても5分残っていたら、11個目の説明をしようと考えていました。10個目の説明の「Required Plugins」を話始めたタイミングで残り5分を切っており、さらにNotificationが出過ぎハプニングのため、会場が盛り上がってました。そんな良い感じの雰囲気のまま「Required Plugins」の説明は残り3分のところで終わりました。最後に感謝の言葉を言うのは30秒もあればできるので、強引に続けてもよかったのですが、練習不足であるのが明らかで、せっかく盛り上がったのに、話を延長して、残念な終わり方は嫌だなー。終わりよければ全て良しだよなーって逃げの気持ちが先行してしまい、そこで「ありがとうございました」と締めてしまいました。

が、やはりあの出来る人たちには見逃してもらえない感じでした。そこで、.ideaの設定共有の話をしたのですが、仕組み自体はただのファイルをgitで管理しているという簡単なものなので、1分もかからずみんな納得してくれて「あーこんな簡単ならやれば良かった・・・完全にチキンだったー」と自己嫌悪でした。

オフィスアワー

登壇後の質問で囲まれた時に運営の方に「やっぱりオフィスアワーやりますか?」と言われました。これは自分の聞き間違えだったかもしれないです。 そこで自分は(あ、自分はオフィスアワーなしだったんだ。)と勘違いしてしまい、質問対応後、そのまま控え室に戻りました。

そしたら、どなたかが、オフィスアワーで待ってくれてた様で、それを知った時には次のセッションが始まっていました。

そこで運営の方が色々動き回ってくれて、こんなツイートをしてくれました。

諸々対応して頂き、ありがとうございました!今後もいつでも回答しますし、DMも空いてますので、何か質問あれば今からでもしてください。

まとめ

とにかく楽しかったです。

自分は年2回くらいしかこういう大きなイベントには参加しないので、運営の人や他の参加者の方達よりゆるいスケジュールで当日過ごしました。 しかし、二日後のいまだに体が本調子に戻らなくて、ちょっとまずいなーって感じです。もうちょっと外に行こうか・・・?

Android開発者ではないので、次回のDroidKaigiでCfS突破できるようなネタが探せるのか?が課題ですが、来年も登壇出来たらなーって考えています。おもしろ登壇枠があればきっと大丈夫だと思うのですが・・・

運営の方たちの細かな気配りがいっぱいありました。色々対応して頂き、ありがとうございました。

そして、最後に、自分の登壇を聴いて下さった方たち、当日「おー!」と盛り上がってくれて本当に本当に本当に話しやすかったです。すっごく気持ち良かったし、楽しかったです。ありがとうございました!!!

Android Studio設定見直してみませんか? -詳細-

このブログはDroidKaigi 2019Android Studio設定見直してみませんか? の詳細です。 せっかく聴いてくれる方がメモを取ってて話を聴き逃してもらいたくないためのエントリーです。

登壇中何らかの問題が発生した時の対策でもあります。

前提

  • 設定の遷移の区分けはJetBrainsの公式と同じで「 | 」です。「Preferences | Keymap」という記述の場合、Preferencesの中にあるKeymapというメニューを表しています。
  • Macを使っている前提で話が書いてあります。
  • Android Studio 3.1から3.3.1での動作確認はしています。

Quick Lists

リファクタ、Surrend With、右クリックなどをすると出てくるポップアップがあると思います。

f:id:shiraji:20190202145813p:plain:w300 f:id:shiraji:20190202145726p:plain:w300
いろんなポップアップがあります

これ、実は自分専用のポップアップを作ることができます。

Preferences | Appearance & Behavior | Quick Lists

と遷移するとQuick Listsを作成する画面が出てきます。

f:id:shiraji:20190202150153p:plain
Quick Listsの設定画面

ここの「+」をクリックし、「Display name」にはわかりやすいものを設定し、ポップアップに表示したいアクションを追加します。

f:id:shiraji:20190202150414p:plain
shiraji quick listsというQuick Listsを作ってみました

「Find Actions」で「Display name」に入力した値を選択すると、自分でカスタマイズしたポップアップが表示されるようになります。

f:id:shiraji:20190202150617p:plain
Find Actionsに表示される

f:id:shiraji:20190202214450p:plain
自分専用のポップアップが!

このQuick ListsはKeymapを設定することも出来て、便利です。

f:id:shiraji:20190202150740p:plain
keymapも設定できる

Font ligatures

!=, ->, ==ってITエンジニアなら読むことは出来ると思うのですが、!=は≠と表示される方がカッコイイです!(主観です)Android Studioではこの表示をサポートしています。

Preferences | Editor | Font

Enable font ligaturesにチェックを入れ、Font ligaturesに対応しているフォントに変えます。

f:id:shiraji:20190202151148p:plain
Fontはデフォルトで入っていてFont ligaturesに対応しているFira Codeを選択

そうすると、コードがこんな感じに表示されるようになります。

f:id:shiraji:20190202151032p:plain:w300 f:id:shiraji:20190202151234p:plain:w300
左が変更前、右が変更後

Notification

右下や右上に出てくるポップアップです。

f:id:shiraji:20190202151703p:plain
Power Save ModeをONにすると出てくるポップアップ

このポップアップですが、すぐ消えちゃったり、何度も出てきてイライラさせたりしてくれます。 全てのポップアップにはIDが振られており、Notificationの設定で表示方法を変えることができます。これは3rdパーティのプラグインも含まれます。

f:id:shiraji:20190202151917p:plain
Gradle Syncが終わったらポップアップを表示させるようにしてみる

今回紹介したいのはこの設定ではなく、どのNotificationでも使われていない、「Read aloud」という設定です。

f:id:shiraji:20190202152300p:plain
どの設定もOFFになっている

Gradle Syncの設定の「Read aloud」を選択して、Gradle Syncをしたらどうなるでしょう? Notificationの内容をAndroid Studioが大きな声で何秒かかったのかを伝えてくれます!(この渾身のネタが文字でしか伝えられない悲しさ・・・)

ちなみに当日は、「おおおお!」とAndroid Studioさんに言ってもらうためのプラグインを使い、褒めてもらいました。

github.com

File Color

File Colorはデフォルトで利用されているので、結構みんな知らないうちに使っている機能だと思います。Project Viewにあるテストコードの背景が黄緑になっています。これがFile Colorです。

f:id:shiraji:20190202184757p:plain
背景が黄緑色になっている

f:id:shiraji:20190202184859p:plain
タブも色が変わる

File Colorは便利な利用方法があります。

Preferences | Appearance & Behavior | File Colors

f:id:shiraji:20190202210717p:plain

上の方のWindowにある、プラスボタンをクリックします。

「Scope」を「Production」として、「Color」を「Blue」としてみます。そうすると、「Run」ボタンを押して、アプリを起動する時に利用されるソースコードが青くハイライトされるようになります。

f:id:shiraji:20190202210853p:plain
青くハイライトされる

Build Variantを変えても即反映されます。

f:id:shiraji:20190202211137p:plain
Build VariantをpremiumReleaseにしたら、debugのソースのハイライトが消え、premiumのソースがハイライトされた

コードフォーマット

コードフォーマットにはいろんな方法が提供されています。

昔よく話に上がっていたのは、reformat code/organize importsなどを保存時に実行するマクロを組むとか、Eclipseのデフォルト機能から作られたであろう、Save Actions - Plugins | JetBrainsというプラグインを導入する、Commitダイアログにあるreformat code/organize importsなどにチェックして、Commitする。

f:id:shiraji:20190202212158p:plain
Commitダイアログのコードフォーマットの設定

ここで紹介するのは、コードを書いているときに、コードフォーマット漏れしているかを確認する方法です。

Preferences | Editor | Inspections | Kotlin | Style Issues

KotlinのInspectionの中に「File is not formatted according to project」という設定があります。これを有効にして、「Severity」を「Error」とします。

f:id:shiraji:20190202212545p:plain

これでプロジェクトのコードフォーマット設定に違反したコードを書くと文法エラーのような表示なります。

f:id:shiraji:20190202212658p:plain
コードフォーマットされていないとエラー表示になる

この赤線のところで、「Option(Alt) + Enter」をすると、「Reformat File」という選択肢が出るようになります。

f:id:shiraji:20190202212737p:plain
Reformat Fileという選択肢が出る

そこで「Reformat File」を選択すると、フォーマットされるようになります。

f:id:shiraji:20190202213134g:plain
簡単にコードフォーマットできる

これを利用すれば、コーディング中にフォーマットされているかどうかの確認が可能です。Android Studio上でエラー表示になっているだけで、ビルドは問題なく出来ます。

余談ですが、特定の箇所をCode Formatしたくない場合もあると思います。そう言う場合は

Preferences | Editor | Code Style

「Enable formatter markers in comments」を有効にし、「@formatter:off」と「@formatter:on」で括れば、フォーマットエラー表記もされないようになりますし、「Reformat File」しても無視されます。

f:id:shiraji:20190202214019p:plain
コードフォーマット対象にはならない

Breakpointsの削除

Breakpointsはデバッグ時に必須なものです。Breakpointsを特定の条件下のみ発動することも可能です。Breakpointを右クリックし、「Condition」を入力すればその「Condition」がtrueの時のみBreakpointで止まります。

f:id:shiraji:20190203013509p:plain
Breakpointに条件を追加する

で、このBreakpoint、作るときも削除するときも簡単で、クリックしたら出来ちゃいます。

f:id:shiraji:20190203013747g:plain
ワンクリックで簡単すぎる削除・・・

結構複雑な条件を設定したにも関わらず、誤ってワンクリックで消してしまい、またその条件を入力しなくてはならなくなった経験ありませんか?筆者は首がもげるくらいあります。

この問題への対処方法があります。

Preferences | Build, Execution, Deployment | Debugger

「Remove breakpoint」のところにある、「Confirm removal of conditional or logging breakpoints」を有効にしてみてください。

そうすると、条件付きのBreakpointをクリックすると、削除するか確認ダイアログが出現するようになります。

f:id:shiraji:20190203014225p:plain
削除するか確認ダイアログ

Inject Languages

Inject Languageと言う機能は生のStringに対して、JSONYAMLなどの言語に対するサポートができるようになる機能です。

対象のStringにカーソルを合わせ、「Option (Alt) + Enter」を押し、「Inject Language or reference」を選択します。その後、そのStringの言語を指定したら、その言語のサポートを受けられるようになります。

f:id:shiraji:20190203015402p:plain
同じ文字列なのに、コードハイライトが有効になっている

また、ここではJSONを利用しているため、「Edit JSON Fragment」と言う機能も利用でき、それを利用すると、別WindowでJSONを入力したら、エスケープなどを良しなにやってくれるようになります。

f:id:shiraji:20190203015606p:plain
下のWindowで編集したら上の文字列に反映される

この機能は非常に便利なのですが、チームで共有するためには、@language("JSON")//language=jsonなどを記述しなくてはなりません。この記述は「Inject Language or reference」を選択したタイミングですぐに再度「Option (Alt) + Enter」を押せば補完してもらえるのですが、忘れがちです。

f:id:shiraji:20190203020224p:plain
アノテーションをつけるかを聞かれる。別のアクションをしたら消えてしまう!

この問題を解消する機能があります。

Preferences | Editor | Language Injections | Advanced

この設定画面の一番下にある「Add @Launguage annotation or comment if needed」を有効にします。その後、もう一度「Inject Language or reference」を選択すると、@language("JSON")//language=jsonを最初から補完してくれるようになります。

Layout Editor

Android開発者なら誰もがお世話になるだろうLayout Editorの設定の紹介です。

f:id:shiraji:20190203135101p:plain

このLayout Editorは設定がいっぱいあって、なかなか面白い機能ではあるのですが、今回紹介するのはこの画面の設定ではなく、Preferecesの方の設定を変えてみます。

Preferences | Editor | Layout Editor

f:id:shiraji:20190203135321p:plain

この三つの設定のうち、一番上にある、「Prefer XML editor」という設定。有効にしてみて、もう一度Layout Editorを開いてみます。

f:id:shiraji:20190203135434p:plain
Prefer XML editorを有効にして、開き直しても特に見た目の違いが見えない。。。

よーく見てみます。

f:id:shiraji:20190203135607p:plain
本当に違いがあります

Textタブの位置が変わっています。

f:id:shiraji:20190203135655p:plain
Textタブの位置が左に!!!

デフォルトでは、Designが左で、Textが右。

f:id:shiraji:20190203135757p:plain
デフォルトはこれ

細部までこだわり抜いて作られている感じがします。

Preferenceのパスのコピー方法

これは設定というより機能のお話です。

登壇中もこのブログでも特定の設定画面への遷移を「Preferences | Keymap」のように記述していました。たぶんここを読んでいる方も社内や自分のドキュメントで設定への遷移を書いたことある人いるのではないでしょうか?

これをタイピングするのは、なかなか厳しいです。そこでこの機能を使うと便利です。

f:id:shiraji:20190203165414p:plain
Preferences | Build, Execution, Deployment | Gradle をタイピングするのは大変

左側にあるTree的なメニューにポインターを合わせ、右クリックしてみてください。「Copy Preferences Path」と出てきます。これをクリックすれば、そこまでのパスをコピーすることが出来ます。

f:id:shiraji:20190203165546p:plain
Copyメニューが出てくる

Pluginのインストールを強制する

特定の機能を使っている場合、チームで必須で使うプラグイン揃えたい時があると思います。例えばDatabindingを使っているプロジェクトでDatabinding Support - Plugins | JetBrainsを入れるとか。

登壇で使ったプロジェクトでは、自分がどんなタイピングをしたのか、どんなActionを実行したのかをあとでみやすくなるように、Presentation Assistant - Plugins | JetBrainsを強制していました。

Preferences | Build, Execution, Deployment | Required Plugins

プラグインの強制方法はこの設定画面で、現在使っているプラグインの中から強制するプラグインを選択します。

f:id:shiraji:20190203173216p:plain

これらのプラグインをインストールせずにプロジェクトを開くと、右下のところにエラーが表示されます。

f:id:shiraji:20190203173110p:plain
プラグインがインストールされていない場合、エラーが出る。

このエラーポップアップの「Install required plugin」というリンクをクリックすると、インストール予定のプラグインの詳細が表示されます。OKボタンを押すと、全てのプラグインをインストールしてくれます。

f:id:shiraji:20190203180205p:plain


当日の発表は多分ここまでです。これ以降は時間の都合上、発表することが出来なかったお話です。


設定の共有

ここまで色々設定変更を見てきましたが、これらの設定はチーム内で共有することが可能です。多くの設定はプロジェクトの.idea内に含まれています。

f:id:shiraji:20190203181739p:plain
.idea内に設定ファイルが格納されている

externalDependencies.xmlは必要なプラグインの設定、vcs.xmlはバージョンコントロールの設定だったりします。

ただし、例えば、workspace.xmlのようなその個人の設定ファイルも含まれてしまっていますので、必要に応じて、.gitignoreなどでコミットしないように注意が必要です。

github.com

GitHubのgitignoreにJetBrainsのものが公開されていますので、それを参考にすると良いと思います。

icon.png/icon_dark.pngというファイルがあると思います。これはそのプロジェクトiconとして認識されます。

f:id:shiraji:20190203182650p:plain
プロジェクトのアイコンが表示される

ちなみに、最近Android Studioの対応がされた、Toolboxでもアイコンが表示されます。

f:id:shiraji:20190203182808p:plain
Toolbox便利なのでぜひ使うといいと思います

Android StudioをNotepadにしてみよう!

最後に(最初から?)ちょっとAndroid Studioで遊んでみます。

Android Studioにはいろんなボタンや空白などがあります。これを全て消すとどうなるか!?を試してみます。

f:id:shiraji:20190203183042p:plain
初期表示

「Hide All Windows

f:id:shiraji:20190203183255p:plain
Tool Windowを隠す

「Tabs Placement」を「None」に

f:id:shiraji:20190203183407p:plain
タブが無くなった

「Show line numbers」を「OFF」に

f:id:shiraji:20190203183558p:plain
行番号が消えた

「Status bar」を「OFF」に

f:id:shiraji:20190203183647p:plain
最下部のStatus Barが非表示に

「Navigation Bar」を「OFF」に

f:id:shiraji:20190203183748p:plain
上部のNavigation Barを消した

「Show Gutter icons」を「OFF」に

f:id:shiraji:20190203183900p:plain
行番号の横にあったスペースがなくなった

「Tool Buttons」を「OFF」に

f:id:shiraji:20190203184030p:plain
外枠のボタンが全部なくなった

「Breadcrumbs」を「Don't Show」に

f:id:shiraji:20190203184125p:plain
下部のスペースがなくなった

ここまで来るともうNotepadとほぼ見分けが付きません!画面が有効活用出来そうです!

ちなみに、ここまでやってしまって、最初に戻す方法は用意されていません。Macの場合、~/Library/Preferences/AndroidStudio3.3/optionsフォルダを消せば元に戻せます。実行は自己責任でお願いします!

まとめ

以上、DroidKaigi2019の Android Studio設定見直してみませんか? の詳細でした。

これを聴いてくれた、または読んでくれた方が1人でも設定変えてみたり、他にも面白い設定/機能ないかなー?ってAndroid Studioの探訪をしてくれると嬉しいなーって思います!

宣伝

さて、Ubieでは、こんな感じで、便利なものを積極的に採用して開発を進めています。もし、Ubieに興味出てきたなーって方はぜひ、@shiraj_iにDM下さい!

サーバサイドエンジニア以外にもいろんな職種募集していますので、こちらもぜひ確認してみてください。

speakerdeck.com

GraphQL(Kotlin)とStackdriver Traceの美しさに惚れました。

GraphQL(Kotlin)とStackdriver Traceがすごくいい感じだったから見て欲しい。

実装

ここで公開したアプリに修正を加えてみました。

shiraji.hatenablog.com

github.com

ライブラリの追加

spring-cloud-gcp-starter-traceを使い、Stackdriver Trace*1利用するため、gradleに変更を加えます。

repositories {
    mavenCentral()
    jcenter()
+    maven(url = "http://repo.spring.io/libs-milestone")
}

dependencies {

+    val springCloudGcpVersion = "1.1.0.RC2"
+    compile("org.springframework.cloud:spring-cloud-gcp-starter-logging:$springCloudGcpVersion")
+    compile("org.springframework.cloud:spring-cloud-gcp-starter-trace:$springCloudGcpVersion") {
+        // remove this after 1.1.0.RELEASE
+        exclude(group = "io.grpc")
+    }
+    compile("app.ubie:brave-kt:1.0.0")

https://github.com/ubie-inc/kotlin-graphql-sample/commit/b0aee867adf13e3e2ef41e8c3e8a5979619995f3

exclude(group = "io.grpc")しているのは、1.0.0.RC1よりバージョンが上のspring-cloud-gcp-starter-traceを使うと、io.grpcが複数のバージョンに依存してしまう問題があるためです。以下で問題提起しています。1.1.0.RELEASEで修正が完了する模様です。

github.com

環境変数などを変更

次に、Stackdriver Traceを利用できるように環境変数などを変更しています。 GraphQLのクエリをログ出力するために、graphql.GraphQLのログレベルをDEBUGに変えています。

  cloud:
    gcp:
      trace:
-        enabled: false
+        enabled: true
      logging:
-        enabled: false
+        enabled: true
  sleuth:
    sampler:
      probability: 1.0
@@ -24,3 +24,4 @@ logging:
  level:
    root: INFO
    org.springframework.jdbc.core.JdbcTemplate: DEBUG
+   graphql.GraphQL: DEBUG

https://github.com/ubie-inc/kotlin-graphql-sample/commit/beb23dc3b858c1cd8cbead49d2f7c1a0abd59b21

Scope Spanを使い、さらに見やすく

最後に、brave-ktを利用して、各クエリがどれくらい時間がかかっているのかを確認するTraceを入れます。

-        if (icd.isBlank()) return emptyList()
-        return jdbcTemplate.query(
+        return Tracing.currentTracer().scopedSpan("findKinkiDrugsByIcd") {
+            if (icd.isBlank()) return emptyList()
+            jdbcTemplate.query(
                 //language=SQL
                 """
                 SELECT
                   yj_code,
                   icd
                 FROM
                   disease_kinki_drug
                 WHERE
                   icd = :icd
                 """.trimIndent(), mapOf("icd" to icd), rowMapper
-        )
+            )
+        }

https://github.com/ubie-inc/kotlin-graphql-sample/commit/25e8e477b365f037daa4948dc94b24ff5789709a

brave-ktに関しては以下の記事に書いてあります。

shiraji.hatenablog.com

結果

ライブラリ追加して、ちょこっと見やすい工夫を入れるだけなのですが、以下のような結果が表示されるようになります。

f:id:shiraji:20190116030939p:plain
Scope Spanを使い、各DBアクセスの時間を見えるように

f:id:shiraji:20190116031047p:plain
1クエリ内で発行されたログも表示できる

f:id:shiraji:20190116031125p:plain
リクエストクエリなども見える

特定のクエリに対して、どのSQLがどのタイミングで発行され、どれくらいの時間がかかっているのか?などが一目でわかるようになりました。

感想

めっちゃ便利。この結果が美しくて惚れました 😍

宣伝

さて、Ubieでは、こんな感じで、便利なものを積極的に採用して開発を進めています。もし、Ubieに興味出てきたなーって方はぜひ、@shiraj_iにDM下さい!

サーバサイドエンジニア以外にもいろんな職種募集していますので、こちらもぜひ確認してみてください。

speakerdeck.com

*1:Stackdriver Traceを利用するには https://cloud.google.com/trace/docs/quickstart?hl=ja を参照

Twitterエゴサーチで見る2018年まとめ

今年本当に自分のエンジニア生活が一変した年だったので、書き留めておく。(2年連続同じ文言)

shiraji.hatenablog.com

技術的な話は皆無です。ツイートと共に自分のための振り返りです。ので、自分のことを知りたい人以外が読んでもらっても多分「あ、そう。」という感想だけしか得られないはずので、戻るボタンクリックお願いします。

1月

2018年はこんなところからスタート

実はですが、初詣に行って、嫁ちゃんに今年で転職しそうだね。しっかりお祈りしときな。と言われて、(ははーん!この人何も俺のことわかってないね!結婚して何年経ったんだよ?)と思ったけど、今日の時点では(何で自分より自分のことを知ってる人がこの世に存在するんだ・・・?)と言う畏怖の念を抱いております。

2月

DroidKaigiがありました。How to Kontribute v4をやりました。このネタは結構な回数こなしてたんですが、あんまりうまくやれずに悔しい思いをしたのを覚えています。

きっと心の底から喜んでるでしょうね!

3月

r.kt #3でライブコントリビュートしました。ライブでコーディングしたの初めてだったので、かなり練習したのを覚えてます。

recruit-lifestyle.connpass.com

ライブストリーミングでshibuya.apkにも参加しました。子供がいるのでこう言うのがどんどん流行ってほしい!と思ってます。準備が大変ですけど・・・。

4月

4月になったので、キャリアについて真剣に考え始めたタイミングでした。早めのジョイン狙いだよなーってなってる時です。

年収ツイートするといいねいっぱい貰えると学んだツイート

フラグが立った日

そして、その日のうちに、スタートアップの早めのジョインなんて今の自分じゃ無理だと判断したツイート。

やっぱり4月は転職周りのツイート多いな。。。

5月

Google IOに行かせてもらいました。初めての参加でした。

Codelabで問題一切やらずに、ChromeBookの検証してた。

これ忘れられなくて、どうしてもやりたくて、現職でやらせてもらいました。もうすぐ詳細を弊社の誰かが書くはず!

6月

サーバサイドKotlinやりたくて仕方なくなってる頃です。

なるほど

GitHub Satellite Tokyoに参加して、色々話聞きました。で、この機能を知らなかったことに正直衝撃を受けてて、毎日GitHub触ってないことに対して危機感を覚えました。このままこのキャリアでもいいかな?と考えてもいたのですが、この危機感は今でも鮮明に覚えていて、この日を境にキャリアを変えると決断しました。で、6月終わりには現職に転職を決めました。

7月

コネヒトさんのイベントに参加して、Kotlin Festのネタ集めを始めました。本当にこのイベントのおかげで色々助かったので、コネヒトさんには感謝しかない!

にも関わらず恩を仇で返す

当然ごめん。

8月

そして最終出社日

最後の最後まで、店舗の方に顔だして仕事してたりしてました。自分がこの会社で長く働けなかったことは本当に悔しいし、またどこかの大企業に再挑戦できる機会がどこかであればいいなと思ってます。

そして、テンションおかしくなって、なぜかその日のうちにコミケに初参加を決めました。

参加者がみんな熱いな!ってちょっと感動してました。

Kotlin Festのスケジュールが公開されて、ふてくされました。

入社日前日に現職のBBQイベントがあったので、家族同伴で参加しました。

入社して一番やりたかったことを2日目にしてやらせてもらって、本当に嬉しかった。

その一週間後のKotlin Festで登壇。自分と同じ時間のLTの人たちがみんな時間通り進めたおかげで、最後の辺り全員が自分の登壇を観ると言う美味しい状況でした。

あと、ぼっち飯回避でTwitterで募集したら始めてお会いする人たちとご飯いけました。本当に楽しかった。

shiraji.hatenablog.com

この8月は今年の中で一番濃かったなー。

9月

現役引退予定でしたが、いまだにバリバリコーディングしてます。35歳定年なんてのはないですね。

10月

Pixelを合法的に日本で触れるなんて思ってもいなかったですね。これが4月までに発生してたら転職とかなかったかも?なので、何が起こるかわかりませんね。

GraphQL始めました。この辺りからツイートがGraphQL一色になってる。かなりお気に入りになった模様。

これ公開したら良くね?って気づいてすぐにOSSとしてコーディングスタイル公開しました。なかなか良い反応もらえて嬉しかった。

その勢いのままbrave-ktも公開しました。

shiraji.hatenablog.com

github.com

11月

2年連続でDroidKaigi登壇が決まりました。今回は日本語でやります。ライブコーディングの予定です。スライドあるとしても自己紹介だけになるので聴きに来てね!

キャリア変えたことを報告しました。Android開発者に罵られるかも?とビクビクしてました。でも当然そんなこと無く、本当に暖かい良い開発者コミュニティだなーと思います。DroidKaigiで少しでも恩を返せたらと!

shiraji.hatenablog.com

12月

今年はアドベントカレンダーに参加しない方針だったので、こっちの参加表明。

でもKotlin枠が空いてて、書くのを抑えられなかった人です。これ結構プロダクションに乗っかってるコードに近いので、興味ある人はぜひ触ってみてください!10月から月1ペースでOSS公開してます。そんな頻度とかは特に意識はしてないけど、出せるものは出して、サーバサイドKotlinやる人増えてくれたら嬉しいなー。

shiraji.hatenablog.com

github.com

2018年の目標達成度

2018年の目標

一回登壇を経験したので、流れも掴めたし、登壇の方の負荷も減ると思うので、コードのアウトプットと両立させたい。

負荷減ってない気が・・・。OSSのコードアウトプット量は前半かなり減っていたので、焦りが出た。それを機に転職して、2018年後半結構アウトプット出来たと思う。 ただ、まだまだやれると思うので、来年はもっと増やしていきたい。

2019年の目標

OSSもそうだけど、仕事でのアウトプットも増やしていきたい。まだまだ手探り感がある。 プライベートはようやく来年から落ち着きそうなので、家族みんな元気に過ごす!が目標。

最後に

8月に転職してまだ4ヶ月しか経ってないのかーと驚きです。今年は仕事もプライベートも色々あって、ドタバタだった感があります。

今年も初めましてな方といっぱい会うことが出来ました。来年もきっと楽しいことが起こるだろうなとワクワクしています。

今年一年、ありがとうございました。来年もよろしくお願いいたします。

Kotlin大好きな人向けなCollectionのstdlibメソッドを掘り出してみた

これはQiita Kotlin Advent Calendar 10日目の記事です。

qiita.com

これマニアックなんじゃね?Kotlin大好きな人向けなんじゃね?ってstdlibにあるIterable/Collection/List/Set/Mapのメソッドを独断と偏見で挙げてみようと思います!

Collection - Kotlin Programming Language

想定読者

  • KotlinのCollectionのstdlibメソッドもっと知りたい人
  • 一旦はさすがです!って褒めてくれる人

環境

Kotlin 1.3.11で使えるメソッドにしています。全メソッドPlaygroundで動作確認済みです。

distinct

説明: 重複削除したListを作る

distinct - Kotlin Programming Language

サンプルコード:

https://pl.kotl.in/HJnYskugV

fun main() {
    val list = listOf(1,1,1,3,5)
    println("List: $list") // List: [1, 1, 1, 3, 5]
    println("Result: ${list.distinct()}") // Result: [1, 3, 5]
}

感想: かー毎回Setに詰め込んでたね。それでListが欲しい場合は、toListしてたね。さらに順番が必要なら色々頑張ってたね。便利😊

intersect

説明: 両方のCollectionに入っている要素をSetにして返す

intersect - Kotlin Programming Language

サンプルコード:

https://pl.kotl.in/SkQkak_eE

fun main() {
    val list1 = listOf(1,1,1,3,5)
    val list2 = listOf(3,4,1)
    println(list1.intersect(list2)) // [1, 3]
}

感想: 知らなかったら、filterとかcontainsメソッドなどで泣きながら書いてたと思う。

union

説明: Collectionをがっちゃんこする。戻り値はSet

union - Kotlin Programming Language

サンプルコード:

https://pl.kotl.in/rykBje_lV

fun main() {
    val list1 = listOf(1,1,1,3,5)
    val list2 = listOf(3,4,1)
    println(list1.union(list2)) // [1, 3, 5, 4]
}

感想: intersectと同じ感想

onEach

説明: 渡した引数のactionを全ての要素に実行し、レシーバーを返す

onEach - Kotlin Programming Language

サンプルコード:

https://pl.kotl.in/HyrGyxugE

fun main() {
    val list = listOf(1,1,1,3,5)
    list.onEach {
        println("Log: $it")
    }.filter {
        it > 3
    }.forEach {
        println("Result: $it")
    }
}

結果

Log: 1
Log: 1
Log: 1
Log: 3
Log: 5
Result: 5

感想: forEachして、そのまま何かしたい!って時にまたレシーバーを書いてたけど、これ使えば全部繋げられるじゃん。便利じゃん。onEachWithIndexとか欲しくなりそう。

partition

説明: Collectionの要素が引数の条件にマッチした要素をPairのfirstのListに。マッチしない要素をsecondのListに分割する

partition - Kotlin Programming Language

サンプルコード:

https://pl.kotl.in/HJgvexugN

fun main() {
    val list = listOf(1,1,1,3,5)
    println(list.partition { it >= 3 }) // ([3, 5], [1, 1, 1])
}

感想: 分割が必要な時、頑張らなくてもいいね!

requireNoNulls

説明: 要素にnullがないことを担保する。もし、nullがあればIllegalArgumentException

requireNoNulls - Kotlin Programming Language

サンプルコード:

https://pl.kotl.in/SJ3VMlul4

fun main() {
    val list: List<Int?> = listOf(1,2,4)
    val listNoNulls: List<Int> = list.requireNoNulls()
}

感想: requireNotNullのCollection版って感じ。nullがないことが前提条件のメソッドとかで利用できそう。(特に気にもせずに無心でfilterNotNullするかもだが。。。)

unzip

説明: PairのArrayに対し、firstの値だけのListとsecondの値だけのListをPairとして返す。

https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/unzip.html

サンプルコード:

https://pl.kotl.in/ryYFNedx4

fun main() {
    val array = arrayOf(1 to "foo", 2 to "bar", 3 to 5)
    println(array.unzip()) ([1, 2, 3], [foo, bar, 5])
}

感想: ちょっと限定的すぎる?🤔いや、こういうのいいですよねきっと!

windowed

説明: Collectionをsizeの要素数のListを作る。次のListはstep分ずれたものからスタートする。

ごめんなさい。どう英訳すれば一番わかりやすいのかすらわからない。以下が原文。

Returns a list of snapshots of the window of the given size sliding along this collection with the given step, where each snapshot is a list.

windowed - Kotlin Programming Language

サンプルコード:

https://pl.kotl.in/r13a_gdxN

fun main() {
    val list = listOf(0,1,2,3,4,5,6,7,8,9)
    println(list.windowed(size = 5, step = 3)) // [[0, 1, 2, 3, 4], [3, 4, 5, 6, 7]]
    println(list.windowed(size = 5, step = 3, partialWindows = true)) // [[0, 1, 2, 3, 4], [3, 4, 5, 6, 7], [6, 7, 8, 9], [9]]
}

partialWindowsがtrueだった場合、sizeに足りてないものも含む。

感想: ちょっと置いていかれたメソッド。これが便利なんだ!というくらいKotlinを使いこなしたい・・・

zipWithNext

説明: Listの隣り合った要素をListのPairとして返す

zipWithNext - Kotlin Programming Language

サンプルコード:

https://pl.kotl.in/r1cjdxOlE

fun main() {
    val list = listOf(0,1,2,3,4,5,6,7,8,9)
    println(list.zipWithNext()) // [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7), (7, 8), (8, 9)]
    println(list.zipWithNext { a, b -> a + b }) // [1, 3, 5, 7, 9, 11, 13, 15, 17]
}

感想: transformを渡せば、数列とかで便利かも?あとは次の値を見て何かするような処理とかでもいいかも。

サーバサイドKotlin+GraphQLのアプリケーションをOSS化しました

これはQiita Kotlin Advent Calendar 2018 1日目の記事です。

qiita.com

ツイートしたら良い反応もらえたので、サーバサイドKotlinのアプリを以下で公開する事に決めました。

github.com

cloneして、docker-compose upしたら、GraphiQLが http://localhost:8090/graphiql 立ち上がって、サーバの動作確認が出来る。簡単!!!

f:id:shiraji:20181214165629p:plain
GraphiQL画面

Ubie内で絶賛開発中のシステムに少し手を加えていますが、基本的に実際に開発している環境と同じになっています。

公開目的

公開に至った理由はいくつかあります。

サーバサイドKotlinやりたいって人のハードルを下げたかった

やりたい!という声はいろんなところで聞くけど、「環境ないし・・・。」「経験無いし・・・。」という方も多いと思ってます。実際Ubie入社前の自分がそうでした。

このプロジェクトは、clone後すぐにローカルで動かす事が可能です。

そのため、このお手軽さを見てもらい、もっと多くの方にサーバサイドKotlinやってもらいたいなーと思いました。

Kotlin+SpringBoot+GraphQLの開発者にコードレビューしてもらいたかった。または仲良くなりたかった

今回、色々な事情があり、KotlinでGraphQLの採用をしています。自分にKotlin+GraphQLの実績がないため、コードを公開することにより、いろんな人に見てもらい、より良いものになったら良いなと思いました。さらに同じような環境の方ともっと仲良くなりたいです!

特に後述しますが、多対多のGraphQLResolverの処理が本当にこんな感じのコードで良いのかが不明です。Spring+GraphQLの情報が少なすぎる。。。もっと効率良く出来そうなんですが・・・

同じ構成のものをOSS化することにより、Ubieの入社即パフォーマンス発揮!をしてもらいたかった

今のところ、Ubieのサーバサイドに関わる人には入社前に1日インターンをしてもらい、チームに溶け込めるか?を見てもらう時間を取っています。しかし、時間が1日しかなく、環境構築に時間を取られてしまうのはもったいないです。そのため、同じ環境をOSS化することにより、先に環境構築出来る状況にしたいと考えました。

さらに将来的には1日インターン宗教上無理!って方にこのOSSプロダクト開発に携わってもらい、雰囲気をそこで味わってもらうのもいいかなと考えています。

技術スタック

このプロジェクトでは以下の技術スタックを利用しています。

今後テスト書くので、以下が追加予定

  • JUnit5
  • Mockk
  • WebTestClient

パッケージ構成

app.ubie.kotlingraphqlsample
├── domain
├── infrastructure
│   └── jdbc
├── presentation
│   ├── queryresolver
│   └── resolver
└── service

(Query)Resolver → Service → JDBCという呼び出し階層になってます。

DB

f:id:shiraji:20181214205606p:plain
E-R図

薬と傷病の関係性のサンプルテーブルになっています。医療業界で利用されているデータに合わせ、IDがなかったり、外部キーがUniqueじゃなかったり、全て多対多の仕様になっています。

DBアクセスはspringがデフォルトで提供しているJDBCを使い、SQLをコードに書いてDBアクセスしています。これは賛否両論あると思いますが、以下の理由から採用しています。

  • SQLのチューニングがしやすい
  • ラーニングコストが低い
  • 一目でどこでどのSQLを発行しているのかがわかる

Flywayを利用して自動マイグレーションが走る状態にしてあります。

GraphQL

GraphQLのスキーマ定義ファイルには薬情報と病気情報が定義されています。

type Query {
    # 薬を取得します
    drugs(yjCode: String!) : [Drug!]
    # 病気を取得します
    diseases(icd: String!) : [Disease!]
}

# 薬情報
type Drug {
    # 薬品名
    name: String!
    # YJ Code。だいたい薬を表すために使われるCode。一意ではないので注意
    yjCode: String!
    # 併用禁忌薬
    kinkiDrugs: [Drug!]
    # 処方してはいけない特定の病気
    kinkiDiseases: [Disease!]
} 

# 病気
type Disease {
    # 傷病に対してつくコード。一意ではないので注意
    icd: String!
    # 病名
    name: String!
    # 処方されてはいけない薬
    kinkiDrugs: [Drug!]
}

Queryブロックには公開APIが定義されています。graphql-javaではこの定義をGraphQLQueryResolverを実装したクラスで記述する必要があります。このプロジェクトではqueryresolverパッケージ内で定義されています。

@Component
class DiseaseQueryResolver(private val service: DiseaseService) : GraphQLQueryResolver {
    fun diseases(icd: String): List<Disease> = service.getDiseases(icd)
}
@Component
class DrugQueryResolver(val drugService: DrugService) : GraphQLQueryResolver {
    fun drugs(yjCode: String): List<Drug> = drugService.getDrugs(yjCode)
}

Drug/Diseaseブロック内にあるkinkiDrugsなどの外部キーを使った結合はgraphql-javaではGraphQLResolver<T>を実装する必要があります。resolverパッケージ内で定義されています。typeがDrugkinkiDrugsの取得時にはfun getKinkiDrugs(drug: Drug): List<Drug>が呼び出される。

@Component
class DiseaseResolver(private val service: DiseaseKinkiDrugService, private val drugService: DrugService) : GraphQLResolver<Disease> {

    fun getKinkiDrugs(disease: Disease): List<Drug> {
        val kinkiDrugs = service.findKinkiDrugsByIcd(disease.icd)
        return drugService.getDrugs(kinkiDrugs.map { it.yjCode })
    }
}
@Component
class DrugResolver(
    private val kinkiDrugService: KinkiDrugService,
    private val diseseKinkiDrugService: DiseaseKinkiDrugService,
    private val drugService: DrugService,
    private val diseaseService: DiseaseService
) : GraphQLResolver<Drug> {

    fun getKinkiDrugs(drug: Drug): List<Drug> {
        val kinkiDrugs = kinkiDrugService.findKinkiDrugsByYjCode(drug.yjCode)
        return drugService.getDrugs(kinkiDrugs.map { it.kinkiYjCode })
    }

    fun getKinkiDiseases(drug: Drug): List<Disease> {
        val kinkiDrugs = diseseKinkiDrugService.findKinkiDrugsByYjCode(drug.yjCode)
        return diseaseService.getDiseases(kinkiDrugs.map { it.icd })
    }
}

多対多な関係が多く、SQLの発行回数が若干多いなーという印象があります。この辺りどうしたらいいのか誰かと語りたい!!!

終わりに

このコード読んで、UbieでサーバサイドKotlinやってみたいと思った方は @shiraj_i に直接DMか以下のWantedlyさんのサイトから話を聞きにきて下さい!

www.wantedly.com

もっと気軽にUbieに遊びに来たい!という方は以下のBosyuさんからメッセージを送って下さい!

bosyu.me

Ubie, incに入社しました。

2018/08/20からUbieに入社しています。3ヶ月の試用期間も無事明けたので、色々書いておこうと思います。

キャリアを変えようとした動機

ちょくちょく話題になる35歳に今年なりました。

2018年4月の時点で自分の今後のキャリアについて悩んでいました。主な悩みはこのままAndroidアプリ開発者を続けるか?です。 Twitterさんや日経さんなど今や多くのWebサイトがブラウザ上での体験を圧倒的に良くするPWAを採用し始めています。PWAと比較してネイティブアプリを作る優位性が、低いレイヤーの処理を必要とするゲームくらいしかないのでは?という不安に陥っていました。このままこのキャリアを続けて5年後、Androidアプリ開発者の需要が万が一無くなってしまった場合、40代で(ゲームではない)Androidアプリ開発が得意です!としか言えなかったら、エンジニアとしてのニーズが無くなりそうだと。Androidアプリ開発者の需要がある今のうちに、新しいモノを試して、駄目だったり、さらにAndroid開発者の需要が増えたら、またカムバックすることが最善策ではないかと考えるようになりました。

Ubieを知る

さぁ次のキャリアどうするかー?といろんな会社にお話させてもらおうと考えていた時にたろうさんの転職のエントリーが出ました。

taro.hatenablog.jp

このエントリーで初めてUbieという会社があるんだなと知りました。当時このブログエントリーの感想は面白そうなことやってる会社だなー。RailsをKotlinに置き換えるとかスタートアップがそんな余裕なの!?でした。

Ubieと話す

たろうさんの記事の後1ヶ月くらい経ってから、Ubieがサーバサイドエンジニアを募集しているということを知りました。せっかくなのでとお話を聞かせてもらいました。

共同代表の久保と話すことが出来て、ざっくりまとめると

  • RailsからKotlinに切り替えるのはガチ
  • 論文を読み込んで、真剣に機械学習に取り組んでいる
  • 精度に関しては圧倒的な自信あり。他社はまず追いつけない
  • 創業して1年目(当時)だけど、日本だけではなく、世界をもう視野に入れてる

のような話をしてもらいました。思った以上にすごすぎて、ちょっとポカーンとしちゃいました。

Ubieに入る

その後、冷静に自分がUbieで働く場合を整理してみると

  • サーバサイドKotlinをやるチャンスがある
  • あのたろうさんと一緒に働ける
  • 機械学習を真剣に取り組んでおり、そこのサポート役の経験を積めそう
  • 組織がまだこれから整備される状況であり、自分の知見が活かせる余地がありそう
  • 事業的には伸び代かなりありそう
  • 創業1年目のベンチャーで、面白そうなフェーズ

自分の次のキャリアとしてこれ以上ないなと思い、入社をさせてもらうことにしました。今では本当にタイミングと運が良かったなと思っています。

入社の儀 f:id:shiraji:20181122235605p:plain

撮影してもらいました f:id:shiraji:20181107121402j:plain

Ubieの業務

入社前からサーバサイドKotlinをしたいと言い続けていたので、希望通り、主なタスクはサーバサイドKotlinをやらせてもらっています。Kotlin化の初期だったということもあり、たろうさんと1on1での開発をさせてもらいました。そのおかげもあり、サーバサイド開発のキャッチアップは結構すんなりいけました。

ライフサイクルが非常にシンプルということもあり、Kotlinのコーディングに集中出来、コード書く楽しさを実感してます。 テストもしっかり書く文化になっているのもお気に入りです。

Kotlinのタスク以外にもGitLabからGitHubへの移行、CircleCIの導入、OSSとしてライブラリの公開などなど色々やらせてもらっています。 毎日のようにテレレ テッテッテーとBGMが頭の中で流れています。

今後はこれらに加えGraphQL+Kotlinや機械学習との連携、SRE業務やPythonでの開発など様々なことに手を出していきます。

リモートRepository移行させたということもあり、正確なPR/issueの数とかわからない+自分の働き方上、多くのRepositoryに顔出しているので、分散しちゃっているのですが、一番コミット数が多いRepositoryはこんな感じでした。

f:id:shiraji:20181121012248p:plain

Ubieの制度 - リモートワークと有給休暇

Ubieは「週2のリモートワークが可能」です。オフィスの環境が良いこともあり、多くの人がオフィスに出社しています。今の事業フェーズではあまりうまく事が進むように整備し切れていないため、フルリモートは出来ないようになっています。今後可能になるように絶賛整備中です。

自分は奥さんと子供がいます。台風が来た週、子供が熱を出してしまったため、台風で一日、子供の看病で一日リモートしました。さらに子供の熱が下がらない可能性があり、有給休暇を取るかリモートするか悩んだため、Slackで投げかけてみました。

f:id:shiraji:20181121005053p:plain

リアクション見てもらえばわかる通り、看病であれば、週3日のリモートもOKでした。

ただ、さらに良くないことが続きました。自分の奥さんが入院することになってしまいました。自分たち家族は親族が新幹線乗らないと来れない距離にいるため、今までであれば、この状況に陥った場合は有給を使い看病することになります。入退院を繰り返すことになってしまったので、合計すると3ヶ月のうち、約1ヶ月はリモートしていました。最大2週間連続でした。でも同僚は自分がうまく働けるように工夫してくれました。

この件からUbieのリモートワークのルールは「週2のリモートワークが可能。ただし何かしら理由があり、恒久的でなければフルリモート可」が実態です。

ということで、この3ヶ月会社にいないことも多かったのですが、最終的に有給休暇の消化0です。子供が産まれてから子供の看病のため有給休暇を取得し、毎年有給消化率80%は越えていました。あんまり自分のための有給を取った覚えがなく、どういうタイミングで取ればいいのか悩んでいます。ちなみに有給は休みます!と宣言したら取れますし、週5のフルタイムであれば入社日に14日付与となります。

Ubieの制度 - 勤務時間

Ubieは裁量労働制です。

日本で初めて入った会社が裁量労働制で、朝9:30出社(1分でも遅刻NG)で帰りは残業などして夜10:00がザラでした(見込み残業が30時間だったので40-50時間くらいサービス残業してました)。そのため、裁量労働制に対して非常に嫌なイメージを持っていて、それ以降裁量労働制の会社を避けていました。

Ubieも裁量労働制だと聞いたので、若干の残業は覚悟の上で、プライベートは絶対死守しようと考えていました。しかし、実態はUbieはしっかり裁量労働をさせてくれています。遅刻という概念がほぼなく、業務中にお昼寝や映画を観にいく人もいます。自分は現在奥さんが病気になってしまったこともあり、朝息子を保育園に送り、夜迎えに行くことが必須となっています。そのため、出社が10:00頃になり、退社は17:30です。30分業務時間が足りてません!しかし自分の労働時間ではなくアウトプットを見てくれてますし、足りていない分、家で仕事して補填しています。トータルでは残業はほぼなしです。

自分があまりの早さで帰るため、Ubieの他の社員さんたちがどれだけ残業しているのかあまり把握していないですが、自分より早く来て早く帰る人もいますし、自分も今後も残業0時間を目安に働いていこうと考えています!

Ubieの制度 - KPT

Ubieでは週次でチーム内KPTをしています。リモートワークを始めたタイミングではたろうさんや自分が今何をやっているのか把握できない事態に陥ってしまったため、この課題がKPTのPとして挙がりました。解決策としては「Slackで始業時に今日のTODO共有する」としたところ、お互い何をやっているのかが把握でき、リモートでも非常にスムーズにタスクが進められるようになりました。

こんな感じで毎朝やってます。この日はリモートで9時から開始

f:id:shiraji:20181122215342p:plain

残業ほぼなし、リモートもしていて、パフォーマンスが下がらないか不安だったのですが、問題があれば、都度全員で解決策を考え、改善していく文化があり、色々手助けをしてもらい、特にパフォーマンスを落とさずにタスクがこなせています。

他にも良いと思ったものを取り入れたり、逆にこれは減らして良いだろうと判断したものは削減したりと試行錯誤していて、ガンガン変わっていく姿が見れて楽しいなーと感じています。

Ubieの社員構成

Ubieの中でかなり気に入っているのがこの社員構成です。

f:id:shiraji:20181121013528p:plain

特徴的なのがSaaSのスタートアップにデザイナーが2人揃っていること。しかも強い。この2人がUXのためなら公民館だろうが診察室だろうがガンガン入っていってより観察しまくります。動き方はUIデザイナーではなく、サービスのデザイナーです。医師が2人いるのも特徴的です。Ubieに入って初めて医師って全員が全員病院に勤務するわけでもないのだなという気づきがありました。弊社の医師だけなのかもしれませんが。全体を観て、バランスが非常に取れている組織だなーという印象を受けています。(業務委託の人がカウントされていないので、その人たちを含めるともう少しエンジニアの数が増えます。)

ちなみにこの社員構成ですが来月には数字がいくつか増えます。どんどん大きくなっていっていて、ワクワクします。

終わりに

ということで、3ヶ月しか働いていないこともあり、良いことにしか目がいっていない恋は盲目状態のブログエントリーでした。

半年くらい働けば、きっと悪いところももっと見えてくるはずなので、来年落ち着いたらまた続編を書いていきたいと思います。

これを見て、興味あるなーという方は @shiraj_i にDMしてもらうか、以下で応募して下さい。

www.careers.dr-ubie.com

一覧にはないのですが、SREやデータサイエンティストも募集してますのでぜひ!

直近ではこんなイベントもあるよ!

bosyu.me

bosyu.me