Meetupは、マッチングサービスを運営する企業が主催する開発者向けの勉強会です。過去の回でも弊社の社員が発表をしています。diverse-tech.hateblo.jpnote.mu4回目となる今回のテーマはズバリ「エンジニアリング全般」。私は10分LTにて、入社時から2年半程携わっているPoiboyでのプロジェクトマネジメントにまつわるお話をさせていただきました。speakerdeck.com内容は、Poiboyで実際に取り組んできた新旧のプロジェクトマネジメント手法を比較しつつ「エンジニアリングとは何か」を改めて考えるといったものになっています。この話をしたのは、普段Poiboyで仕事をする中で「そもそもエンジニアリングとは何だったっけ??」という疑問を抱いていたことがきっかけでした。プログラミングを仕事にしていると、普段「エンジニアリング=プログラミング」という認識でいることもあるかと思います。そんな折、発表中にも引用した「エンジニアリング組織論への招待」という本を読んだのですが、その中に「エンジニアリングとは『曖昧さを減らす行為』」であると書かれていました。人は見えないものや知り得ないものに対しては対処ができないため、そうした曖昧な要因を減らすことで生産的にプロジェクトを進めることができるというのです。詳細は同書を読んでいただきたいのですが、プログラミングも曖昧さを減らす行為の1つではあるものの、それ以外でも曖昧さを減らすことは可能ということになります。今日開発手法の主流となっているスクラム開発で行うプランニングやKPTといった手法も、この「曖昧さを減らす」ことが一つの目的となっているわけです。1スプリント内にこなせる・こなした具体的なタスク量が見えるように可視化することや、タスクの優先度の決定基準を特定の人の中ではなく全員が認識できる外に置くことなどです。そのためエンジニアリングは「エンジニアだけが行うこと」ではなく「誰でもできること」という認識を持つべきではないかと思いました。最終的な目的が曖昧さの削減であれば、それを達成するために行動することこそが真のエンジニアリングであるということをお話させていただきました。参加者の方からも多くのフィードバックをいただきました。2019他には、実際に取り組んでいる開発プロセスの改善活動やフレームワークなどの紹介、大規模なチーム構成におけるマネジメント・情報共有手法などについての発表がありました。弊社でやったことがない手法も多く取り上げられていたので、今後のプロダクト開発に取り入れていきたいものがたくさんありました。株式会社イグニスさんのイベント会場なお会場のイグニスさんですが、イベントスペースが大変きれいで司会進行もスムーズにされていたのが印象的でした。7月16日に神田明神ホールにて行われたPLAZMAに私と熊埜御堂の2名が登壇したので今回はそのご報告になります。plazma.redPLAZMAはTreasureDataが主催するユーザー向けイベントで、Diverseでも以前より社内DBとしてTreasureDataを使用していました。今回のイベントはDiverseが昨年から導入しているBIツールであるLookerがスポンサーをしていたことから、合同セッションでの登壇機会をいただくこととなりました。Lookerの概要や導入経緯についてはwantedlyでも紹介していますので併せてご覧ください。www.wantedly.comセッションでははじめにLookerからの概要説明や導入実績等が紹介されました。現在は日本でも20社以上が導入していて、その中でもDiverseは最初期の段階で導入しているという点もお話させていただきました。その後Diverse側にバトンタッチし、Lookerの導入背景や抱えていた課題、導入の効果や利用時のノウハウなどを紹介しました。(残念ながら当日のスライドについては現時点では非公開です)Lookerを導入する以前は、ビジネスで必要なデータがある場合、都度エンジニアにSQL発行を依頼していたため、クエリーの属人化が進んでいました。可視化のためスプレッドシートで管理されているデータも多く、集計時のバグ修正や計算ロジックの管理ができないといった課題を抱えていました。ビジネス側の要件で算出条件を変更する場合には、複雑なクエリを修正する手間がありました。UI上で入力することでLookMLにより自動的にSQLが発行されるため、クエリの属人性を下げることができます。Spreadsheetに頼っていた可視化も、ダッシュボード機能を使うことで常に最新のデータを必要な形で見れるほか、普段見たい情報が集約されるため必要なシートを探す手間がなくなりました。UI上での設定変更で実現するためSQLの修正が不要となり、エンジニア以外のメンバーでもほしいデータを容易に取得することができるようになりました。このようにデータの活用が難しかったDiverseが、Lookerによりデータドリブンな企業に近づいていることをお伝えしました。当日はエンジニア以外にマーケティングや分析の担当者をはじめ様々な方が参加されており、登壇後の懇親会でも導入を検討してる企業の方から質問を受けるなど好評をいただくことができました。DiverseでもまだLookerで見れないデータや扱える人が限定されているといった問題がありますが、こうした課題も今後徐々に解消していくため日々努力を続けています。したデータドリブンなサービス作りに興味がある方は、ぜひDiverseの社員までお声がけください。kikuchyが登壇いたしました。stamp.connpass.comPORTは主にFirebase関連の勉強会を企画されているイベントプロジェクトで、過去にも様々な企業やテクノロジとのコラボ回を実施されています。今回はFirebaseとFlutterの組み合わせ、というテーマでした。Crashlytics』というタイトルで、FlutterアプリケーションにクラッシュレポートサービスのCrashlyticisを導入して運用した際に判明した問題とTipsを紹介させていただきました。導入対象のアプリは、先日このブログでもお伝えした、婚活サービスのyoubrideです。developer.diverse-inc.com実務で使用する際の運用方法についてお話できたので、Flutter開発のお役にたてば、と思います。次の登壇者のパネルディスカッションでは、アプリのアーキテクチャ、youbirdeアプリでのテスト構成、CIの構成、クロスプラットフォーム採用の是非などについてもお話させていただきました。FlutterはFirebaseなどを使ったプロトタイピングと相性が良いので、ビジネスロジックの状態をStatefulWidgetに押し込めたりしがちです。BLoCパターンやScopedModelパターンなどでWidget外にビジネスロジックの状態を切り出し、StatefulWidgetには表示ロジックの状態管理に徹してもらうようにすると、状態の抽象化や結合度の低下に貢献できるでしょう。youbrideではBitriseをCIに使用していて、PR作成時にテストの実行、PRのマージ時にビルドとデプロイを自動で行うようにしています。ビジネスロジックの単体テストを自動で行っており、実行も2〜3分程度で終わるようになっています。プロジェクトの開始時に、まずは「ビルドが通るか」だけを確認するタスクのみでもCIを導入して、使えるようにしておくと良いでしょう。後からCI環境を整備すると面倒になりがちであったり、リポジトリに動作しない状態のコードを混ぜる危険性を少なくできるためです。FlutterはワンソースでiOS/Android両方に対応できることがウリの一つですが、結局プラットフォーム依存の機能を使用する場合やビルド周りなどでそれぞれの知識が必要になります。そのため、慣れていないのであれば、iOS/Androidのどちらか一方に注力する選択肢を取ったほうが無難でしょう。(youbrideチームは、クライアント開発できるエンジニアが全員iOS/Android両方ともできたのでうまく行っています)fultterから開発すべきか?swiftUIとかもあるけど?スピード重視かつチームにもよる。日本ならユーザーの多いiOS、グローバル(中国、インド)はAndroidが良いのでは。fultterを無理に採用する必要はない。クロスプラットフォーム専用の知識も必要になりコストも2倍になるため。懇親会ではクライアントでのgRPC採用の話題で大いに盛り上がりました。2019年6月26日(懇親会の様子)gRPCは共通の定義ファイルから、サーバー/クライアントのRPCに関わるコードを自動生成してくれるため、APIの定義から実装をとても楽に行なえます。やり取りするデータはProtocolBuffersでシリアライズされているため、JSONと比べると軽量で、通信時間の短縮も見込めます。Webではまだ双方向のリアルタイムストリーミングができていない、などの制限があるというお話を聞くことができて大変助かりました。11:20Tweet2019-07-04歴史ある婚活サービスyoubrideがFlutterを採用しましたFlutter最近はすっかりFlutterエンジニアになってます。Diverseが提供するサービスの一つに、youbrideという婚活サービスがあります。youbride.jpこの6月に、youbrideはAndroidアプリのデザインリニューアルを行いました。youbrideアプリのデザインが大きく変わりました!変わったのは見た目だけではありません。新アプリには、マルチプラットフォームフレームワークのFlutterを採用しています。flutter.dev近々、iOSアプリもFlutterで開発したバージョンに置き換える計画が進行中です。Railsを使ったものに置き換えています。rubyonrails.orgサーバーとクライアント間の接続にはgRPCを使用しています。gRPCを採用することになったのか?それは、youbrideに発生していた種々の問題を解決するためでした。仕様の複雑化とコードの複雑化youbrideは今年で運営19年目を迎える、長寿サービスの一つです。私達、今のチームが運営を手がけるより前にも、複数の会社を渡り歩き、複数のチームが開発・運営に携わっていました。歴史あるサービス故に、サービス方針などで迷走した時期もあったのでしょう。複雑な仕様や把握が難しい仕様が存在し、それを表現するコードも複雑になっていました。複雑故に依存関係も読みきれず、不要かどうかわからないコードが放置されデッドコードになっている箇所もあります。現在、youbride担当チームは以下のメンバーで構成されています。膨大な仕様とコードに対して、対応できる人員が少なすぎます。そんな状況だったので、一つの機能改修をするための影響範囲の調査だけで半日〜数日かかることもあり得る状況でした。求人youbrideのサーバーアプリケーションのコードはPerlで書かれていました。Perlでの開発・運用をしたいエンジニアさんの数は少なく、採用の現場ではPerlエンジニアの募集がとても難しい、という声も上がっていました。少人数での開発を可能にするには、保守する対象のコードを削減する必要があります。クライアントアプリケーションについては、マルチプラットフォーム開発ができる仕組みを使うことで、UIに関するコードやビジネスロジックをiOS/Androidの間で一本化できます。ツールによる補助などを使用して、省力化できる部分は省力化したいところです。利用者の皆様に御迷惑をかけてしまうため、サービス仕様については急に大きな変更をすることはできません。プログラム的な内部仕様は単純化したいものです。クライアント間の通信仕様の管理を簡単にできるものを探すことになりました。求人の対象は主に日本国内で、特にサーバーサイドで人気が高く、応募者が集まりやすい言語を選定することになりました。上記の要件に合致するものとして、最終的に以下のものを選択しました。クライアントFlutterを採用しました。決定当時に普及の兆しが見え始めていたこと、ロジックだけでなくUIも共通のコードで記述できること、エコシステムが強力だったこと、いざとなればプラットフォームの機能を簡単に使用できることなどが主要因です。APIを使用できないことから、不採用となりました。Railsを採用しました。開発メンバーが慣れていることなどが主要因です。JVM言語(KotlinやJavaなど)の使用も検討されていましたが、メンバーのJVMサーバーのチューニングなどの運用経験が皆無であることなどから見送りとなりました。クライアント間のインターフェイスにはgRPCを使用することになりました。通信部分の実装をほとんど自動生成できることが主な要因です。(OpenAPI)も俎上に上がりましたが、通信速度などの点でgRPCに軍配が上がりました。実際に採用してみてクライアント途中経過の話は、以前にQiitaに投稿したことがありますので、合わせてご覧ください。Experienceの良いフレームワークだと感じています。Reloadがとにかく高速で、これを経験してしまうと、通常のAndroidアプリのビルド時間にも耐えられなくなってしまうほどです。(React風の)宣言的UI構築はとても直感的で、Viewの現在の状態を考える必要がなく、楽にコードを書くことができました。高速な動作、使い勝手Androidのアプリケーションとしてリリースを行いました。Designであるということもあり、通常のAndroidアプリケーションと使い勝手は何ら遜色ありません。ビルド後のサイズも、今まで公開していたAndroidクライアントと全く変わらないサイズ(約15MB)になっています。FlutterアプリケーションはDartのエンジンなどを積んでいるため、サイズは大きくなることを覚悟していましたが、軽く済んだのはとても嬉しい誤算でした。Controllerな設計になっており、適切なレイヤー化ができていませんでした。今回、サーバーのコードもリライトする際にレイヤーを見直すことで疎結合な実装を実現でき、テスト駆動開発ができるようになりました。同時に、Perlでは多用されていたメタプログラミングを廃し、IDEによる補助を強力に受けられるようになりました。cコマンドによる対話的環境で、簡単な動作確認が手元で行えるようになりました。テストを書くほどではなく、少し値の形式を確認したいだけ...など、といったときに、心理的なハードルを低くして動作させることができるようになっています。これまではサーバーを立ち上げて、試したいコードパスを通るリクエストを投げなければいけませんでした。Callの仕組みです。共通のインターフェース記述言語(IDL)を用意し、そこからサーバー、クライアント用の実装を自動生成します。クライアント間ではREST(っぽい)APIを定義し、HTTP/1を介してJSONフォーマットでデータをやり取りしていました。Perlの値を安直にJSONへシリアライズすると、真偽値が"1"/"0"と、数値も文字列型として出力されてしまいます。以前のメンテナがいなくなってしまった今は、果たしてこの値が真偽値として扱うことを期待されているのか、そうでないのか、判別できません。gRPCには共通のIDLに型宣言でき、Enumも定義できることから、値域について混乱することがなくなりました。実装の簡略化gRPCはIDLからサーバー/クライアント向けのコードを生成できるため、具体的な通信にかかるコードを記述する手間をほとんど無くすことができました。IDLの.protoファイルは専用のリポジトリで管理しています。Requestを生成するようにしました。protoファイルの変更から自動生成されたPRドキュメントもGithubリポジトリのWikiに自動でPushされるようにしています。ファイルの変更後、自動的に更新されるRPCのWikiファイルの生成について特別気にすることがないため、とても開発が楽になりました。抱えていた問題のだいたいを解決することができましたが、新しい要素の採用故に生じた問題もあります。Reloadなどの仕組みもDart言語を前提に作られています。Flutterが出た当初はDartに対する不満も多く見られましたが、バージョン2.3になってだいぶ改善してきたように思います。現状ではまだ大規模開発を行う上で不満は残ります。現在のDartはnull安全ではなく、予期しない入力によってnullを期待しないメソッド引数にnullが入ってしまった場合などに簡単に例外が生じます。人間はミスをしがちな生き物であり、人間の注意だけでこうしたミスを防ぐのは困難なので、できれば型システムでnullが入る可能性があるのか否かを明示してほしいと切に感じます。null安全性については今後のDart言語のバージョンアップでの採用が決まっているため、プロダクションで採用するならば、個人的にはnull安全が導入された後のタイミングをおすすめします。悪い言語だということではありません。If/Forなどコードを書きやすい機能も揃っています。Crashlyticsにクラッシュレポートの蓄積を行っています。CrashlyticsはFlutterを公式にはサポートしていません)レポートの送信はfirebase_crashlyticsプラグインを用いて行っていますが、例外によってはDartのスタックトレースが送信されていないケースがままあります。SDKのクラス名が並ぶばかりで、ユーザーコードのどこで例外が起きたのかわからないこともあります。そのため、現在は例外の原因究明に大きなコストがかかっています。CrashlyticsがFlutterに正式に対応してくれるのを待っています。gaurunとfirebase_messagingの相性youbrideはgaurunを用いてPushサーバーを運用しています。Messagingを使う必要があり、firebase_messagingプラグインはFlutterでのPush受信のデファクトスタンダードになっています。ところが、firebase_messagingはFirebaseのコンソールなどから送信された形式のペイロードを想定した作りになっているため、gaurunが送信するペイロードとは形式が合わず、gaurunからPush通知を送ってもクライアント側で表示されません。(gaurun側の修正予定もない、とのこと)結局、プラグインに頼らずに、Push通知の受信を実装することになりました。弊社内でgRPCを使用したプロダクトはyoubrideが初めてです。そのため、大規模サービスでのgRPCの運用経験がありません。インフラ構成なども手探りで進めているので、今後なにかトラブルがあったら怖いのは間違いないです。大事故に至らないように調査はしていますし、今後知見をためていくことができれば不安は小さくなるでしょう。gemにはCPUを使い切ってくれない問題があるようです。今のところはまだこれが問題にはなっていませんが、そのうちに問題になる時が来るかもしれません。youbrideチームは、iOSアプリもFlutterで作ったものに置き換えるべく作業を続けています。これだけ歴史の長い大きなサービスでFlutterを採用しているケースは、国内初なのではないかと思います。LT登壇させていただきましたので、今回はそのご報告になります。potatotips.connpass.compotatotipsは、iOSとAndroidの両プラットフォームの開発者が集い、アプリやモバイルの周辺技術にまつわるTIPSを共有するという勉強会です。2019の後ということもあり、両プラットフォームとも新しく発表された機能に関する発表が多く見受けられました。Configの運用で得たノウハウについての発表をさせていただきました。Firebaseは両プラットフォームで使うことのある技術のため、potatotipsでのトピックにも最適と思いお話させていただきました。当日の資料はこちらに公開させていただいております。Configは、アプリ内にあるロジックを遠隔で操作可能にするソリューションです。一部のユーザーに対して通常と異なる画面を表示したり、限定的に新機能を利用可能にしたりする、いわゆるA/Bテストに必要な機能を実現できます。アプリ側での実装は、Firebaseからパラメーターを読み込む処理を数行書くだけで良いため、既存のプロダクトに簡単に導入できるというメリットがあります。専用の管理画面が用意されており値を入力して保存するだけで反映されるため、運用・管理のコストが低いのも特徴です。Configを利用したA/Bテストによる施策の効果検証を10件以上行ってきました。その中で現在に至るまで、チーム内で実装・運用とも試行錯誤を重ねてきました。詳細は資料に載せたのでそちらをご覧いただきたいのですが、今回は主に増加するパラメータの管理方法として現時点でのベストプラクティスと、エンジニア以外のメンバーにとっても運用がしやすくなるようなノウハウをお伝えしました。Configの概要を知っているかどうかを参加者に質問したところ、7割以上の方が「知っている」と回答されていました。Configは注目されているのだなと感じました。一方で「実際に利用している」と答えた方は全体の半数程度でした。Configを使わない理由について聞いたところ「A/Bテストのための仕組みを自前で実装している」と話す方が複数名いらっしゃいました。大きな会社だと基盤や数値分析を専門とするチームがあり、A/Bテストの実装についてはモバイルエンジニアは担当しないというケースが多い様子でした。別の理由として「A/Bの振り分けに詳細なユーザー属性を指定したいから」という声も聞かれました。(ターゲットユーザーグループ)を対象に含めることで、属性に基づくターゲットに絞っての検証が可能です。高精度な属性情報が必要な場合は追加のプロパティをFirebaseに送ることもできますので、自前実装を考えている方はFirebaseの利用を検討してみても良いでしょう。これまで自分は「A/BテストならとりあえずFirebaseを使えば大丈夫」という考え方だったので、自前実装との比較ができとても参考になりました。A/Bテストの進め方や組織体制などについても参加者と意見を交わすことができ、大変有意義なTIPS共有会となりました。今回はお話できなかったログ送信や数値測定周りのお話も、今後機会があればしたいなと思っています。Diverseでは、こうした施策の効果測定を始めとした数値分析にも力を入れています。最近ではLookerというBIツールも導入し、FirebaseでのA/Bテストの結果検証にも利用しています。Looker導入の経緯についてはこちらの記事もぜひご覧ください。6で買い込んだ積読本にようやく目を通しています。#10に登壇して参りました。Nightは今回が記念すべき第10回で、今回も主にiOSでのテスト手法やCI関連の発表がされていました。登壇したこともあります。developer.diverse-inc.comそんな中今回、自分は初登壇のLT枠で「iOSアプリのテストを書きたいのに書けないあなたへ」という発表をさせていただきました。speakerdeck.com自分が入社以来携わり続けているPoiboyでは、恥ずかしながらつい最近までテストコードがほぼが存在しませんでした。テストのメリットを感じつつも長い間導入できなかった要因はいくつかありますが、その一つに「iOSアプリのテストの書き方が分からない」というものがありました。大学の授業や入社後の研修でテストの書き方自体は習っていましたが、それは題材のコードが明示的な入出力関係を持っていたためでした。スライド内でも紹介している通り、iOSアプリのコードは必ずしも入出力が明確なものばかりではなく、テストを書こうと思ってもうまく書けず失敗を重ねていたのでした。その後、明示的な入出力があって小さなコードを選んでテストを書き始めたところ、徐々にテストを書くことができるようになりました。実際のプロダクトで起こったことを例に、テストが書きにくそうなコードも書きやすいコードに変えていくための手法として、依存注入と抽象化、また設計を行う前段としてのモジュール分割も紹介させていただきました。今回は自分と同じようにテストをうまく書けないという方に向けて発表をいたしましたが、既にテストに慣れている方や他の登壇者からも、発表に対してのポジティブな感想をいただくことができました。