リモートモブワークをやってみてます

プロダクト開発チームの富田です!

現在、15時頃から「モブワーク」時間を2時間、毎日確保しています。

元々、この時間はフロントエンドの引き継ぎをすることになり、学習のために始めました。

このモブプロの体験がとても良く、TDDもこの時間に経験することができました。 TDDに関しては、同じチームの御園さんが「TDDをやってみた感想」という記事でまとめてくれています。

この後、他の作業もモブプロ(モブワーク)でやり始めました。

いつもはリモートでやっていて、月1回の飲み会の日はオフラインで開催しています。

オフライン開催時のモブプロの風景

使っているツール

エディタ

Visual Studio CodeLiveShare機能を使っています。 各個人環境で動かす事ができるのと、Driverがどのコードを見ているのかすぐに分かるのが良いです!

また、ターミナルを共有出来るのも地味に重要です。 CLIの各種ツールは開発に必須なので、同じ環境で作業で出来ることは心強いです。

タイマー

タイマーは↓のような機能が欲しい感じです。

  • slackで知らせて欲しい
  • Driverが変わる時に通知して欲しい。変わる前に予告の通知も欲しい。
  • 時間や参加者を柔軟に変えることができる

結局、良いツールが見つからず自家製を使っています。雑な作りですが、必要十分です。

どんな作業をやっているか?

例えば、↓のようなものです。

  • 属人化しがちな作業
    • インフラ(AWS)の設定・構築
    • フロントエンド
  • 複雑な処理のレビュー
  • DBからのデータ出力対応

特にフロントエンドを変更する場合は、モブでやることが多いです。 現在のメンバーは全員フロントに強くないので…

全部モブ?一部だけ?

モブで行う作業は、一部だけです。 毎週月曜のスプリントプランニング時に、どのタスクをモブワークでやるか相談します。 モブ向きの作業が無い場合は、無理して開催していません。

調査作業等、一人で対応した方が効率が良さそうなことは、モブではやっていません。 フルでモブプロやっている会社もあると聞きますが、どんな風にやっているでしょうか、、、気になります。

やってみた感想

属人化しがちだったタスクをシェアすることで、暗黙知を潰せていることが出来ているかなと思います。

また、各メンバーの技術の底上げや、コーディングスタイルを共有することで良い刺激になっていると思います。「そんな書き方があったのか!」と驚くこともシバシバです。

今後も、このモブの時間を継続していくことが出来れば、と思います!

TDDをやってみた感想を物語風に書いてみた

こんにちは、Baseconnectエンジニアの御園です。 最強寒波の時「気温がunsigned intになってくれない」とか「冷たいからrangeでチンする」とか色々と思いついたのですが、どこに吐き出すでもなく一人ほくそ笑んでいたおもしろ系エンジニアです。 別にそんな事はどうでもよく、そもそもTDDとは何か?について、そしてやってみた感想を記事にしてみたいと思います。

introduction

例えば貴方が学校に通っているとして、今にも遅刻しそうだとします。 すると当然のことながら大半の人は走って間に合おうとするでしょう。(少数の人は諦めて開き直り、歩くかもしれません。そのような人々はExceptionです。)

その時、食パンを加えた美少女が角から飛び出してきたら貴方はなすすべもなく衝突してしまうでしょう。 そして美少女に文句をつけられ、結局遅刻し、散々な目に合うかもしれません。

その後、学級ではどこからともなくリークされた転校生の話題でfullですが、貴方は脳RAMをそんなものに割く余裕もなく、今朝の事でムカついてしまい、うまくGCする余裕もありません。

やがて訪れた朝の学級会で、担任の先生が転校生を紹介した時、その転校生は今朝貴方とシノニムを起こしたばかりの美少女で、お互いに指を指し合って「あの時の!!!」となり、そこから青春のストーリーがプロセススタート……

おっと、ブラウザバックするのはまだ早いです。 OK、ゆっくり、まずはコーヒーでも一杯飲みながら、続きを読んでみて見ください。 読者の”あなた”が読んでいるのは、「TDDをやってみた感想」という題名のブログ記事で間違いありません。

このイントロダクションのような出会いを、実際に目にしたこと、あるいは経験したことがあるでしょうか? もしそのような事がexistsな方々は、幸運としか言いようがありません。

残念ながら私はありません。というか普通の人はないと信じたいです。たいてい、ドラマか、アニメの中の話でしょう(最も、最近はそんな王道展開の物語も少ないかもしれませんが)。

筆者、御園とTDDとの出会いは、まさに上記のような感じでした。TDDという言葉はやんわりと聞いたことがあったのです。日本語訳が「テスト駆動開発」というのもなんとなく知っていた程度ですが、本当にその程度の知識です。

しかし実際にTDDに触れ、TDDを知り、そして実践していく中で、その出会いは確実にまさに衝撃と呼べるものでした。少し誇張していて興奮気味ですし、読者の中には「おいおいそれは言いすぎだぜ」と思う人もいるかも知れません。

これからの文章は、あくまで筆者の感想として捉えていただき、しかしながら生暖かい目で見守っていただき、それでいてTDDへの理解が少しでも深まれば幸いと思って書くことにしますので、アイスブレイク的にゆっくりと楽しんでいただければと思います。

TDDの導入

冒頭のストーリーを思い出しましょう。 今度は貴方はそのストーリーの主人公ではなく、ストーリーの実装者です。 簡単な、ゲームのようなものを作ると考えてみてください。 ストーリーを完成させるには、まず主人公は学校に遅刻しており、そして間に合わせるために走らなければなりません。 擬似コードを書いてみます。

main_character.set_state('遅刻')
main_character.run

なんとなくRubyチックに書いてみましたが、あくまで擬似コードなのでそこまで気にしなくて良いです。 さて、ここでストーリーを完成させるための冒頭を開始したわけですが、実際には上記のコードが上手く動いているかを確かめる必要があります。 つまり”テスト”を書くということです。 簡単に書くならばこんな感じでしょうか。

expect(main_character.get_state()).to eq('遅刻')
expect(main_character).to receive(:run)

主人公の状態が遅刻になっているかと、”走る”が呼び出されているかを確認しました。

さて、通常の開発フローであれば何も違和感がないように思えます。 ですが、今回の主題はTDDでした。

Test-Driven Development

つまり、テスト駆動開発は、その名の通りテストを主軸に置いた開発を行います。 TDDにおいて、開発の一番最初に行うのは、テストを書くことであり、もっと言えばそのテストが落ちることを確認します。 先程の例を基にしてみましょう。

expect(main_character.get_state()).to eq('遅刻')
expect(main_character).to receive(:run)

TDDにおいては、一番最初に書くべきコードはこれであり、そしてこのテストが落ちることを確認します。 実装が何もなければこのテストが落ちることは自明です。 テストが落ちることを確認したなら、次にやるべきことは「このテストを通すこと」です。 ここで面白いことが起きます。このあと、同じように

main_character.set_state('遅刻')
main_character.run

と実装を進めていくわけですが、その目的が「テストを通すこと」にTDDでは成り代わっていることに気づいたでしょうか?

もちろん「遅刻していて、走り出す」という実装をすることには間違いないのですが、TDDではない最初のやり方だと、

・「遅刻している」「走る」を実装する

・それらの実装があっているかを確認する

の順序になっていたのに対し、

TDDでは

・「遅刻している」状態をテストする。落ちることを確認する。

・「走る」が呼ばれているかテストする。落ちることを確認する。

・テストが通るようにする。(「遅刻している状態にする」を実装する、「走る」を実装する)

と、最終的な実装は「テストが通るようにする」ところからスタートするのです。 ここにTDDの妙が詰まっています。

保証されたリファクタリング

TDDでは、「まずテストを通すこと」を一番大事にします。そのため、”綺麗にコードを書く”事は一旦意識しなくて良いのです。 例を見てみましょう。例えば、先程のテストを持ってきてみます。主人公が遅刻しているということを確認するテストです。

main_character = MainCharacter.new
expect(main_character.get_state()).to eq('遅刻')

このテストを通すために、最低限どのようなことをすればよいでしょうか?

シンプルに考えることが大事です。 それはつまり、

・MainCharacterクラスに遅刻を返す get_state メソッドがあれば良い

という事に他ならず

class MainCharacter
    def get_state
        return '遅刻'
    end
end

という実装をすればよいのです。ちょっと待って……。貴方が言いたいことはわかります。 普通の精神をしてたらこんなコードは書かないです。

でも、TDDではある意味”これが正解”なのです。 なぜなら、「テストが通るようにする」という目的はこの実装で達成されるのですから。

では、何が気に入らないのでしょう?

・get_stateで遅刻しか返らない。本来なら他のいろいろな状態を保持するようにしたいはず。

当然の疑問です。それは正解です。ではそのように少しコードを変えてみましょう。

class MainCharacter
    def initialize
        @state = '普通'
    end
    def set_state(state)
        return @state = state
    end
    def get_state
        return @state
    end
end

MainCharacterクラスがインスタンス変数 @state を持ち、これによって様々な状態を保持するようになりました。セットするための set_state 関数も実装されています。

さて、先程のテストは通るでしょうか?

main_character = MainCharacter.new
expect(main_character.get_state()).to eq('遅刻')

当然、落ちます。 なぜなら主人公を遅刻させるための set_state が呼ばれていません。 このテストに set_stateを使う必要があるようです。

main_character = MainCharacter.new
main_character.set_state('遅刻')
expect(main_character.get_state()).to eq('遅刻')

テストが再び通るようになりました。

ここで示したのは極端な例ですが、TDDを行う時は「まずテストを通るようにする」という事が大事です。 そしてその先にリファクタリングがあるのです。

そしてそのリファクタリングも、最終的には「テストを通すようにする」に帰結しています。 テストが通ることは、コードの変更前と変更後で、期待する結果が得られていることの保証になり、心理的に開発者を安心させることになるのです。

  1. テストを書く
  2. テストが落ちることを確認する
  3. ”取り敢えず”テストを通るようにする
  4. 3.で生まれたリファクタリングポイントを解消していく
  5. テストがすべて通るようにしておく

これが私が実際に体験したTDDのポイントです。リファクタリングはあとなので、例えばテストのファイル単一に全ての実装コードを書くこともあります。 本来なら実装段階でいくつかのファイルに分けて綺麗に書きたいところですが、TDDでは単一のファイルに書いてから、後で外側のファイルに吐き出す。という事をしました。

動作はテストが保証してくれます。 リファクタリングしたいな、と思うメモの項目一つ一つを解決していく際に、テストが通るという保証が付き添ってくれるので、安心しながらリファクタリングをすすめることが出来るのです。

そして、実装を変更したいときも、テストがついていれば「テストを通るように」すればよく、常に私達は目的を見失う事なくコーディングが出来るというわけです。

放課後(ただの感想)

TDDを体験した時、私が一番の衝撃を受けたのが、”リファクタリングが後”という事でした。 (殆どの人がそうだと私は信じていますが)私はコードを書く時に「いかに綺麗に、保守しやすく、他の人が読みやすいコード」を意識しています。

だからクラスは別ファイルに階層を意識して書くし、テストも通常別ファイルです。 ですが、私のチームで実践したTDDでは、テストのファイルに実装も一気に書いてしまい、テストが完全に通るようになってから、ちゃんとしたファイルに書き出す(私にTDDを教えてくれたメンバーはこれを"extract"と表現していました)事をしています。

なんて原始的で、でも着実なんだろう。と思いました。

プログラミングを学びたての頃は、単一のファイルに数百行以上のコードを書くなんてことはありましたが、クラスやモジュール、名前空間などのファイル毎に分けるようなテクニックを学んでからは、ほとんど単一のファイルに大量のコードを書くことなんてありませんでした。

ですが、TDDではそれがありえてしまうのです。

一旦全て実装を書ききってしまい、テストが動くという保証を基に、適切な位置にコードを配置していく。 バグはテストが動かないということそのもので見つかる、なんて素敵なんでしょう。

ここまで感想を述べると、まるで私がTDDの事を完璧に思ってるように見えます。 ですが、不満もあります。いくつか見ていきましょう。

  • 開発時間は多くなる

先程示したとおり、非常に小さなステップもテストとともに進んでいくので、開発時間はどんどん多くなっていきます。

完璧なプログラマなら最初からリファクタリング済みの完璧なコードをかけるような時間に対して、TDDは”着実に”進んでいくので、どうしてもコードを書く時間は伸びるのです。

  • 正しいテストかどうか、テストを書く人(見る人)に委ねられる

それが求めている仕様を表すのに本当に正しいテストかどうかは、よく吟味しなければなりません。 やもすれば、全然意図しない間違ったテストを基に実装してしまうことは、開発そのものを破綻させてしまいます。

本当に正しいテストかどうか、テストの質はどうか、そもそもテストを設計しにくい仕様だと長いテストを書いてしまわないか…… テストが正しいということを前提にした開発は、テストがそもそもちゃんとしていなければならないのです。

それはどうやって保証していけばいいのでしょうか。

私のチームではあまりそういった事はなかったのですが、例えば仕様変更などによるテストのメンテナンスコストなども、話には聞きます。 仕様変更に追従してテストを大幅に、やもすれば1から書き直さなくてはいけない。 後からテストを書くケースに対して、この場合はテストも実装もまるごと変わっていくので、大変なのは想像に難くないでしょう。

よければ、TDDを教えてくれたメンバーの記事もご覧下さい! techblog.baseconnect.in

Outro

さて、いかがだったでしょうか? TDDとはどういうものなのか、そしてそれに関して私が感じたことを少しでも共有できたなら幸いです。 一つ言えることは、TDDを導入したからといって、遅刻した時に曲がり角で美少女と運命的なシノニムを起こすということはないということです。ですが、それを補って余りあるTDDの恩恵があることは確かなので、試験的に導入してみてもい良いのではないでしょうか?

Baseconnectでは美少女と出会う時のように、新しい技術に出会った時に運命的なドキドキを感じるエンジニアを募集しています。 興味が湧いた方は、テストケースを握りしめて以下の採用ページを覗いてみましょう。

https://herp.careers/v1/baseconnect/requisition-groups/9607685a-4d6c-4b90-9f44-ac654b11d986

herp.careers

RSGT2023に初参加しました!

はじめに

こんにちは、開発部門で採用や組織改善に携わっている寺尾です!

今回1/11~1/13の3日間にわたって開催された、スクラムのカンファレンス「Regional Scrum Gathering Tokyo 2023」に初めて参加してきたので、記事にしてみたいと思います。

Day1

場所は御茶ノ水ソラシティ カンファレンスセンターで開催されました。会場に入ると、すぐ目の前にスポンサーブースが出展しているエリアがあり、ブースの周りなどいたるところで多くの人が会話をしている様子が見られ、活気と熱気がある雰囲気に包まれました。

私は初参加だったので、名札に「First Timer」というシールを貼ったのですが、他にも「CSM(認定スクラムマスター)」など様々はシールがあり、どういうステータスなのか?が一目で分かるようになっていました。(私も来年はCSMのシールを貼れるように頑張ろうと思います!)

セッションはただ聞くだけでなく、参加者同士でディスカッションをしましょうという機会が多かったのですが、こういった自分のステータスを表すシールがあることで「初参加なんですね」といった、会話のきっかけになったのが有り難かったです。

そんなこんなで、一緒に参加していたプロダクト開発チームの富田さんと合流しました。ドキドキしながら開始を迎えたのですが、まずはじめにRSGTになぞらえた寸劇が始まり、驚いたのと同時に、会場内も笑いに包まれて、気持ちがほぐれました。

その後は、David Bernsteinさんによるkeynoteが始まり、いよいよスタートです。

▽David BernsteinさんによるFive Development Practices for Building Software with Scrumのスライド

speakerdeck.com

CI, CD, TDD, リファクタリング, ペアプログラミングについて、なぜそれが有効なのか、ポイント等の紹介がされています。

そこからは、各部屋ごとにセッションが行われて、参加者は自分の興味のあるセッションに参加することができます。

▽当日のスケジュール

https://confengine.com/conferences/regional-scrum-gathering-tokyo-2023/schedule

私も事前にスケジュールを確認して、参加したいセッションの目星を付けていたのですが、途中で知り合った方に誘われて、新しいセッションに参加してみるなど、リアルの場だからこそ生まれる偶発的な出会いを楽しむことが出来ました。

Day2

Day2はLyssa Adkins さんによる「The Agilists’ Emerging Superpower and Our Planetary Challenge」というkeynoteから始まりました。アジャイルとは何なのかという話から、地球規模の課題である気候変動に対して私たちはどう振る舞うべきか?という大きなテーマの内容でした。

▽Lyssa Adkins さんによるThe Agilists’ Emerging Superpower and Our Planetary Challengeのスライド speakerdeck.com

参加したセッションの中でも印象的だったのは、スタメンさんによる「事業部全体を巻き込んだ アウトカム文化への道のり」です。

組織内で「価値の流れ」に関するコミュニケーションが高コストで行われているという課題に対して、EMの役割の定義の見直しや組織体制の見直しを行い、よりアウトカム文化を根付かせていった取り組みが参考になりました。

▽スタメンさんの事業部全体を巻き込んだ アウトカム文化への道のり

speakerdeck.com

また、森さんによる「楽しいだけじゃない、次の一歩を自分で踏み出し続けられるふりかえりへ~」も印象的でした。

チームでより良い未来に向かっていくために、チーム全員で立ち止まり、より良いやり方を見つけるために話し合いをして、行動を少しずつ変えていく活動は改めて大切だなと思いました。

その他にも、Day1やDay2が終わった後に、参加者同士で近くのお店に行き、参加した感想などをシェアする交流の機会があったのが、とても良かったです。

ご飯を食べながらだからこそ出来る話や、盛り上がりもあって、たくさんの出会いや繋がりが生まれました。(RSGT歴5年目の富田さんとご一緒させていただけたおかげで、沢山の人に出会えたので、とっても感謝です!)

Day3

最終日は、OST(Open Space Technology)に参加しました。OSTとは、ワークショップの進め方の1つで、参加者自身が話したいと思っているアイデア、解決したい議題などを持ち寄って、皆の前で発表し、興味を持った他の参加者がそれぞれのテーマごとに集まりディスカッションを繰り返していくというものです。

あっという間に30以上のテーマが集まり、ディスカッションが開始されました。途中での参加や中抜けに制限がないので、参加者も色々なディスカッションを見て回ることができます。

共通の課題感を感じて、ディスカッションに参加しているので、初対面の人同士も、あっという間に白熱した議論になっていきました。とても活気のある空間が生まれて、こういった場を社内でも生み出していきたいなと強く感じさせられました。

おわりに

今回初めて参加させてもらいましたが、アジャイルに関わる方の温かさや、良いプロダクト開発をしていきたいと共通の目的を持った人々が集まる場を実際に体感できて、すごく良い経験になりました!

また、イベントを運営する・場を作るという観点からも、ワークショップやイベントの合間や終了後など、至るところに、参加者同士の会話や出会いのきっかけ作りの工夫がされており、ただセッションをするだけでなく、人と人との出会いをすごく大切にされているのだなと伝わってきて、運営の視点からも勉強になりました。

学んだ内容を社内でも活かしていきたいですし、来年のRSGT2024もぜひ参加したいと思います。ありがとうございました!

RSGT2023に誘って下さった富田さんの記事もぜひご覧下さい^^ techblog.baseconnect.in

Regional Scrum Gathering Tokyo 2023に参加しました!

プロダクト開発チームの富田です!

1/11(水)〜1/13(金)まで開催されたRegional Scrum Gathering Tokyo 2023(以下RSGT)に参加してきました。 RSGTは、毎年1月に東京で開催されるアジャイル関連のカンファレンスです。

去年も参加したのですが、今年も参加することが出来ました!

スライドはこちらのブログ記事がまとまっていて便利です!

参加してどうだったか?

参加したセッションで印象に残ったものをピックアップしてみます

大規模ゲーム開発におけるリモートモブワークの導入事例

詳細はこちら

私の居るチームでもモブプロを行う時間を設けているのですが、他社の事例を聞くことが出来、とても参考になりました。

モブ毎にふりかえりは行っていなかったのですが、取り入れてやってみたいと思います。

「私考える人、あなた作業する人」を越えて、プロダクトマネジメントがあたりまえになるチームを明日から実現していく方法

詳細はこちら

ProductManagerと開発チームに分断が発生しがちなこと関しては、なかなか身につまされるものがありました。 お互いの価値観を共有することで、見える未来もあるんだ(どんな形であれ)、、

録画された動画を、プロダクト開発メンバーと一緒に見てみたいと思います!

「教えない教え方」を活用してスクラムを理解して実践するワークショップ

詳細はこちら

3日目は、こちらのワークショップに参加しました。

「教えない教え方」自体も興味深かったのですが、ワークを一緒に行ったチームの動きがとても素晴らしく、社内で若干グダグダになりがちだったスプリントの運用をしっかり見直そうと思わされました。

▽記念写真をパシャリ

一緒に参加したメンバーからの感想

今回、私はRSGTに初参加、これだけ大規模な社外イベントに初参戦しました!一番感動したのは、運営の方、参加者の方の熱量の高さです。

良いプロダクトを開発していきたいという共通の思いを持った方々が、国内外問わず一斉に集った、その「場」の熱量は実際に現地に行ってみないと得られないものだなと実感しました。

各セッションもとても学びが多かったですが、OSTを通じて、お互いに自分たちが抱えている課題をテーマに議論し合う中で、社内だとどうしても視点が偏りがちですが、社外からの視点として、新しい意見をもらえてとても新鮮でした。(また私も記事を書いてみたいと思います。)

RSGT2023で学んだことを活かして、自分たちのチームにも貢献していきたいです!

まとめ

去年は一人で参加したのですが、今年は二人で参加することができました。 昼休みや一日の終わりに「どうだったか?」と感想戦をしたり、帰ってから何をしよう?と相談出来たのが良かったです!

また、登壇を聞いたりや他の方と話していると、同じような悩みを抱えている企業は多いとも感じました。 社内には色々な課題が山積みなので、一つずつ切り崩して解決していきたいと思います!

「創業期のスタートアップにおける技術選定とAWS」というイベントに登壇しました

こんにちは、エンジニアの奥野です!

今年の11月にAWSさんのイベントに登壇させて頂いたので、記事にしてみたいと思います。

イベント概要

今回のイベントのテーマは「創業期のスタートアップにおける技術選定とAWS」というものでした。創業前・創業間もないスタートアップにおいて、プロダクトやサービス開発をどう効果的・効率的に進めるべきかについて、スケールを前提とし、 AWSさんのサービスを含めて実例を踏まえて紹介するというものです。

イベントの詳細はこちらからご覧ください。

open.kyoto

当日の流れ

タイムスケジュールは以下の流れで進行していきました。

  • オープニング (18:00-18:05)
  • AWS さまセッション (18:05-18:25)
  • アトモフさまセッション (18:25-18:55)
  • Baseconnectセッション (18:55-19:25)
  • クロージング (19:25-19:30)

会場の様子はこちらです。会場設営準備中の様子。広々としたスペースでした!

登壇の様子

いよいよ登壇の順番になりました。私たちの発表では、事業の創業期から振り返り、その中の開発組織変遷や各フェーズごとの課題についてご紹介させていただきました。 弊社は2017年に創業されたのですが、2022年の現在に至るまで、様々な変化やそれに対する取り組みを重ねてきたものを一連の流れとしてまとめたものになります。

詳しい内容についてはこちらのスライドからぜひご覧ください! (弊社のデザインチームメンバーがスライドを作ってくれました)

speakerdeck.com

終わりに

こういったイベント登壇を通じて、自分たちの取り組みを振り返る良い機会になりました。 今後もBaseconnectではこういったイベント登壇を増やしていきたいと思っています! 色々とお世話になり、このような場を設けて下さったAWSさん、たくさんのサポートをくれた開発チームやデザインメンバーの皆さん、本当にありがとうございました!!

フロントエンドの歴史変遷

どうも!Baseconnect のエンジニアの山本です。

さて、今回はBaseconnectのプロダクトである、営業リスト作成から営業管理までを一括管理できる法人営業支援データベース「Musubu」のフロントエンドの歴史についてご紹介させていただきます。 創業当初の様子はわかりませんので、物語は私が入社した2018年から始まります。

大雑把にフロントエンドの技術スタックの変遷を絵にすると、こんな感じです。

2018年 入社当時

私が入社したタイミングのムードと言えば、プロダクトが成功する兆しが見えてきたぞ...という感じでした。 ヨシ、プロダクトに新機能を追加していくんだってね。

当時は代表がすべてを掌握し、指示を出し、レビューをするという超中央集権的指揮系統で、デザイナーがデザインからコーディングまでを担当し、エンジニアもフルスタックで様々な業務をこなしていました。

こりゃえげつないフローだなぁとビックリしましたが、一気にプロダクトを具現化するタイミングで必要なダイナミックさでもあったなぁ。

React / Redux で スタイリングは Sass、バックエンドは Ruby on Rails という当時としては鉄板構成だったんじゃないかな? でもまぁ、フロントエンドのコードのカオスぶりはナカナカのものでした。様々なスキルレベルのエンジニアが、コードを追加しているような感じ。特にCSSの上書き合戦による膨大化には遠目になりました。

膨大なコードを目の前に、どうしたものかと躊躇しながら、Typescriptを採用し、JSX(js) から TSX(ts) への移行が始まっていました。

Atomic Design / Storybook

フロントエンドのコードは、それぞれが一つ一つ心を込めて作っている工芸品のようでした。とても似ているボタンが無数にあり、デザインルールも明確ではありませんでした。

まず、UIコンポーネントを整理・掌握し、再利用性を向上させる必要がありました。 当時、コンポーネントの分割手法として盛り上がっていた Atomic Design、コンポーネントカタログとしてStorybookを採用しました。

フロントエンドエンジニアとしての専業化も、ジワジワ進んでいきます。

2019年 : プロダクトリリース期

しかし、コンポーネントの整理はあまり進捗しなかったかもしれません。 プロダクトとして方向性を変える、いくつもの機能を実装することに奔走していたからです。

Styled-Components

Sass でスタイリングをコントロールすることが難しくなっていました。人力による命名規則でスタイリングのスコープをコントロールするってのは無理になってきたのです。Styled-Components を採用し CSS in JS へ移行していきました。

そしてついに、2019年11月11日に「Musubu」をリリースしました。

2020年

2020年は、あるべき姿にしていこうという動きが徐々に活発になってきていた。 これまで自由なインスピレーションと創意工夫でこさえてきたが、世のベストプラクティスを学び、適用していこうという流れでしょうか。

Redux Toolkit

Reduxにおいて、より効率的に開発を行うためのライブラリで、Reduxの公式サイトでも強く推奨されています。「Reduxを簡潔に書くためのスターターキットである」というよく見る解説も納得できますが、Reduxにおけるベストプラクティスが取り入れられた、Reduxを利用する時の間違いを防止し、正しく利用するための知恵の集合とも言えます。これはプロダクトをより安全・堅牢にしてくれるでしょう。

React Query

データ同期については長らくフロントエンジニアの悩みのタネでした。 取得、キャッシュの扱い、更新、ポーリング、エラー処理... 「SPAあるある」な、それらの憂鬱を解消するライブラリとして登場したのが、おなじみ TanStack の React Query でした。

React Hook Form

バリデーションルールは、整理・共通化されていたり、そうでない箇所もあったりと、とっ散らかっていました。React Hook Form を採用し、そのバリデーションスキーマに Yup を使用し統合・再利用性を向上しました。

xstyled

CSS in JS ライブラリとして既に Styled-Components を採用していましたが、互換性のある props ベースのフレームワークを採用しました。参照:[CSSフレームワーク「xstyled」について]

Styled-Components はなんだかんだ言って、ベタなCSSの記述が必要です。あぁ、本当はこう書けたらかっちょいいのになぁ、を実現してくれるのが「xstyled」です。

プロダクトのテーマカラーを刷新するというプロジェクトで、広範囲で適用され、しぶとく残っていた Sass によるスタイル指定を大量に排除することができました。

Atomic Design を破棄

Atomic Design に沿ったコンポーネント分割を放棄しました。 理念にはとても共感するのですが、多数のレイヤーに分類する方法は、私たちにはマッチしませんでした。

2021年 : 主要機能のUI刷新とリファクタリング

フロントエンドのリファクタリングがとても進捗した年です。

プロダクトのビジョンを具現化するための大規模改修が計画されていました。 その要件化を緻密・詳細に行った結果、フロントエンドとしては停滞したタイミングがありましたが、その時間を利用して大規模なリファクタリングに着手したのです。(タイミングを虎視眈々と狙ってた)

リファクタリング

一定のリソースを担保し、コツコツと負債を解消に取り組むことで、劇的にコードの透明性が向上しました。

  • RTK Query & Aspida 組み込み
  • テスト改善
  • ディレクトリ構成
  • FC 化

...などなど

RTK Query

APIとの通信やキャッシュ管理に React Query の適用に着手していましたが、Redux Toolkit との相性が抜群に良い RTK Query に仕切り直すことにしました。

Aspida

また、HTTPクライアントのラッパーである Aspida を採用し、APIリクエスト/レスポンスが型安全になりました。 パス/URL、クエリ、ヘッダー、ボディ、レスポンス...全てに型を指定でき、axios にも対応しています。

UI & Frontend Meeting

デザインチームとのディスカッションの機会で、アイデアや意図が共有され、早期からその実現性やレンダリングの負荷、使い勝手について検証しました。 そのためのツールの模索も行われ、デザインツールは figma に変更。実装の共有・ディスカッションツールとして chromatic を採用しました

主要機能のUI刷新

主要機能のUI刷新は無事にリリースされ、ユーザーに好意的に受け入れられました。

  • リファクタリングという地ならしによって、コードの透明性・開発体験透明性が向上した。
  • デザインの目的・意図を汲み取り、その実現方法についてデザインナーとエンジニアが知恵を出し合った。

難工事に取り組んでくれたメンバーに感謝しています。

現在

現在、Musubuの新機軸となる機能群を、モリモリ実装中です。

その中で、これまで模索してきたことをさらに昇華し、より良い体験をユーザーに提供できるよう取り組んでいます。

  • デザインシステムの構築 / DesignOps
  • ユーザーの視点に立った継続的改善
  • より良い方法・手法を積極的に採用していく

一流のフロントエンドと胸を張るには、あと何ステップか成長しなければなりません。 ご興味を持たれた方は、ぜひ覗いてみてください。

参照

求人機能の実装の概要について(AWS Startup Tech Meetup 関西 #1より)

こんにちは、エンジニアのAlvinです!今回は、AWS Startup Tech Meetup 関西 #1の登壇でお話しした「サーバレスを使って大量データ処理を実装した話」の概要について書いていきたいと思います。

背景

少し背景を説明すると、Baseconnectが提供する企業情報データベース「Musubu」は、企業の営業活動を支える高品質なデータを提供するために、技術と人力を組み合わせ、単なるスクレイピングやクローリング技術では実現できない独自のデータ製造に取り組んでいます。

しかし、日々更新されるジョブデータや外部媒体からの企業データの取得には限界があります。特に情報の更新性、網羅性に課題がありました。

そこで今回、パートナー企業様と連携することになりました。パートナー企業様の求人データとMusubuのデータベースを連携させることで、求人媒体に掲載されている企業の検索が可能になります。ターゲティング精度を高めることで、求職者の検索ニーズを最適化することを目指しました。

やろうとしたこと

システムを設計する場合、まずは要件を知ることが必要不可欠だと思います。そこで弊社が保持している情報を精査すると、以下のようなことを考慮する必要がありました。

  • データはBaseconnectが作成したAPI Endpointに送信される
  • 求人データは、パートナー企業様から、週1回受信する(数万件のデータ)
  • どの会社の情報なのか特定する必要がある
  • 企業が特定された求人データはMusubuのデータベースに追加する必要がある

これらの内容を実現するために、まず最初に思い浮かんだのはサーバーで構築することです。求人データを受信するエンドポイントとして機能し、それを処理してMusubuのデータベースに挿入するための常時稼働のサーバーです。

しかし、週1回実行される処理の場合、インスタンスを構築するのは無駄が多いと考え、別の選択肢を検討することにしました。

サーバーレスの活用

次に考えたのがサーバーレスについてです。 エンドポイントには、AWS API GatewayAWS Lambdaを使うのはどうかと考えました。しかし、ここで厄介なことがありました。

それは、送られてきた求人データをどのように処理するかです。理想としては、受け取ったものを、そのまま処理することですが、ここでいくつかの問題がありました。

問題点

  • 忙しい時間帯には、Musubuのデータベースが負荷に耐えられない恐れがある。
  • 処理にかかる時間は少なくとも3時間が必要と予測される。対して、AWS Lambdaは15分しか起動しない。

そのため、これらの問題点をクリアにするために、新たなサービスを探しました。そこで見つけたサービスが「AWS Batch」です。サーバーレスでの実行ができ、好きなタイミングでのトリガー設定や、長時間実行できるという、まさに求めていた内容にぴったりの優れたサービスでした。

開発プロセス

ここでは、そのAWS Batchを使った開発過程を簡単にご紹介します。

  1. まず、ローカルにDockerイメージを構築し、gitでコードを管理します。コンテナを作って、その中でコードを実行できれば問題ありません。
  2. コーディング後、AWS Elastic Container Registryでイメージリポジトリを作成し、そこにプッシュしました。毎回ローカル環境からプッシュするのは運用効率が悪いので、CI/CDを設定しています。Githubのgitリポジトリを更新すると、CI/CDパイプラインがAWS ECRの更新を代行してくれます。
  3. 最後に、週1回バッチを実行させたいので、AWS Eventbridgeを利用しています。AWS EventbridgeはAWS Batchと統合されており、どのジョブをいつ実行するかを選択するだけでできます。これでScheduledジョブは完了です。

※実装の詳細については省略します。

まとめ

全体として、このような仕組みになりました。

  1. パートナー企業様から求人データを受け取って、当社のストレージ(AWS S3)に格納します。
  2. 翌日、AWS Batchのジョブが実行され、処理されます。まず、CSVからのデータを抽出し、弊社のデータベーススキーマに変換します。
  3. 次に、どの求人データがどの会社のものかを弊社の名寄せシステムで識別します。
  4. 最後に、品質を保証するため、データのチェックを行います。問題がなければ「Musubu」で公開し、お客様に提供します。

終わりに

Baseconnectでは「これは本当にベストな方法なのか?」と常に新しいやり方を模索することを大事にしています。今後もより良いユーザーエクスペリエンスを実現するために、日々取り組んでいきたいと思います。ありがとうございました。 今回の取り組みの詳細はこちらからご覧下さい!

speakerdeck.com