TECH PLAY

株式会社ラクス

株式会社ラクス の技術ブログ

932

こんにちは。 株式会社 ラク スで先行技術検証をしたり、ビジネス部門向けに技術情報を提供する取り組みを行っている「技術推進課」という部署に所属している鈴木( @moomooya )です。 ラク スの開発部ではこれまで社内で利用していなかった技術要素を自社の開発に適合するか検証し、ビジネス要求に対して迅速に応えられるようにそなえる 「技術推進プロジェクト」 というプロジェクトがあります。 このプロジェクトで過去に検証した「継続的アプリケーションセキュリティ」について共有しようかと思います。 課題の経緯、前提条件 課題の経緯 期待する導入成果 シフトレフトや、脆弱性診断ツールに関する概念 前提条件 実現手法 SASTとIASTの特徴 共通の特徴 SAST IAST SAST/IASTを導入したらDASTが不要になるか どこまでコストをかけられるか ツール所感 → 今後に向けて SAST/IASTツールの製品傾向 SCMサービスに付随するサービス GitHub Code Scanner 調査の中で分かった導入に向けたハードル 最後に 課題の経緯、前提条件 課題の経緯 脆弱性 を含めた不具合の発生タイミングについては、発生するタイミングが開発工程の後であればあるほど、開発全体への影響が大きいです。しかしながら特別な対策を行わなければ開発工程の後半ほど不具合が見つかることが多いというのが現実ではないでしょうか。 それはプログラムが動く状態になってからの方がテストしやすいということが最大の理由かと思いますが、テストのタイミングを開発工程のなるべく早い段階、すなわち不具合発生の原因が生まれるタイミングに移す(=シフトレフト、開発工程を左から右に流れるとイメージして前工程である左側に移すこと)方法が考えられ生み出されています。 (出典: IPA 『 セキュリティ・バイ・デザイン 導⼊指南書 』 p.36) ラク スでもそれほど多いわけではありませんが、リリース前に不具合が見つかることがあり課題感がありました。 本調査ではテストのシフトレフトについて、有効そうな手法の探索と導入可否の検討を行いました。 なお、上で図を引用した IPA から発行されている『セキュリティ・ バイ・デザイン 導⼊指南書』は、このあたりの考え方がまとまっている資料なのでぜひ参考にしてみてください。 www.ipa.go.jp 期待する導入成果 期待する導入効果としては、 開発プロセス 全体で不具合対応にかかっているコストを現状よりも小さくすることです。そのために従来開発工程の後半で見つかっていた不具合を少しでも早い段階で検知できる仕組みを期待しています。 ただし、導入することで今までよりも手間がかかるようでは本末転倒 1 なので、導入後にセキュリティのシフトレフトによるコスト増(ツール費用など)を含めて現状よりも小さくなることが大前提となります。 ※なお実際の不具合対応コストはこんなに割合多くないです🙂 シフトレフトや、 脆弱性 診断ツールに関する概念 CAS: Continuous Application Security 継続的アプリケーションセキュリティ CIに組み込むなどして日常的に意識することなくセキュリティ向上策を実施するプ ラク ティス SAST: Static Application Security Testing 実装中に適用 設計にも適用できるという話もあるが現実的には実装中での適用になると思われる コード診断を行い、Linterのように動作する 製品としては SonarQube があったり、 GitHub やGitLabにも組み込まれている IAST: Interactive Application Security Testing E2Eテスト中に適用 操作と並行して検査する 製品としては Seeker , Contrast Security など DAST: Dynamic Application Security Testing リリース前に適用 DASTはすでに ラク スでも導入していたため今回の調査からは除外 SCA: Software Composition Analysis 利用しているライブラリの既知の 脆弱性 を検出できる SASTツールの機能として組み込まれている場合がある RASP: Runtime Application Self-Protection アプリケーション実行中に異常を検知する仕組み 本稿では直接扱わないが参考として 前提条件 現在の ラク スでは実装工程として 単体テスト 、その後 結合テスト 工程に 脆弱性 診断ツールを用いてのテスト(DAST)を行なっています。 DASTツールの見直しについては別途定期的に取り組んでいるため、シフトレフトするとなると検討すべきはSAST, IASTツールになります。今回はSAST, IASTツールの調査と ラク スで導入しやすそうなツールの検討を行なっていきます。 また、調査当時は ソースコード 管理にGitLab CEを利用しており、 クラウド 版 GitHub Enterpriseへの移行を検討していたこともあり、GitLab, GitHub に依存したGitLab SAST, GitHub Code Scannerについては調査対象外にしていました。 実現手法 SASTとIASTの特徴 共通の特徴 ホワイトボックステスト 対応できるのはメジャー言語に限られる しかし長期的にメンテナンスする想定のサービスで採用されるような言語は対応しているので実用上は問題なさそう コード外由来の 脆弱性 には対応できない ソースコード を対象に捜査するため仕方がない SAST 誤検知が多くなりがち フルスキャン可能で カバレッジ を100%にしやすい IAST 誤検知は少ない 機能操作に伴って カバレッジ が高まるため、 カバレッジ を高めるのは大変 カバレッジ 100%を目指すためには、すべての処理分岐を網羅するようなアプリケーション操作が必要 SAST/IASTを導入したらDASTが不要になるか 結論から言えば、SAST/IASTを導入してもDASTは不要にならなず、現状DASTツールにかけているコストはなくなりません。 なぜならば、DASTで出来ずSAST/IASTで対応可能な観点のテストがある一方で、SAST/IASTで出来ずDASTでしか出来ない観点のテストもあるためです。 例えばSAST/IASTでは ソースコード をフルスキャンしてのテストが可能だが、DASTで行うような外部ライブラリや複数のモジュールを結合してのテストは行うことが出来ません。 既存のDASTで無理してカバーしているような部分がある場合(例えば細かな条件違いの正常系経路の網羅など)は該当箇所をSASTおよびIASTに適切に移行することで、トータルのメンテナンスコストは削減できる可能性はあると思います。 どこまでコストをかけられるか 今回の調査を始めるにあたって少し甘かった部分ですが、調査中盤で改めて 社内で開発工程後半で不具合が発覚することによる手戻りの 工数 がどの程度か確認したところ、想定以上に開発品質が良く手戻りが多いサービスでも「2, 3人日程度」ということがわかりました。この時点で高額なツールの導入は割に合いません。むしろ「まだ導入する必要がない」という選択が現実的だと判断できるボリュームです。 セキュリティ関連のツールは総じて高額な事が多く、今回調査したツール類も有償ツールはすべて導入のコストメリットは見いだせませんでした。一方でCommunity Editionなどの無償でのツール提供が行われているものだと機能面で弱く、これも導入メリットが小さいと判断されました。 ツール所感 → 今後に向けて さて、有償無償問わずツール導入のメリットが薄くなってしまいましたが、こういった状況だとSAST/IASTツールの導入はかなり難しいです。 SAST/IASTツールの製品傾向 無償ツールとして利用できるものは機能制限が多い 自前運用しようとするとCI環境のマシンリソースを確保する問題が発生する 常時稼働するわけではないが、少ないと待ち時間が開発速度の悪化に直結する 多くのツールは クラウド サービスとして展開されている テスト環境での操作情報を外部に送信しなければならない セキュリティが厳しい会社だとこの部分で導入は厳しそう 2 予算が潤沢であれば、機能面でContrast Securityが良さそうに見えました www.contrastsecurity.com SCMサービスに付随するサービス GitHub Code Scanner 調査当時もCode Scanningは存在していましたが、当時弊社の ソースコード 管理はGitLab CEを利用していたため候補から外していました。またGitLab SASTも GitHub 移行の検討が始まっていた頃だったため、除外していました。 現在はほぼすべての ソースコード を クラウド 版 GitHub Enterpriseに移しているのでCode Scanningも候補に入ってきます。 課題として挙げたCI環境のリソースもCode Scanningであれば、(多少のお金の力があれば)なんとかなります。 と思ったら……Code Scannerの利用はプライベー トリポジ トリ対象だと、 GitHub Advanced Securityライセンスが必要で、アクティブコミッター1人あたり月額$49が追加で必要になるので弊社のようにそれなりの規模のチームで開発している場合に導入するのはハードルが高かった…… 3 。 docs.github.com 調査の中で分かった導入に向けたハードル 既存 ソースコード で検出される項目の扱い 導入時が一番多く検出される 検出されたから修正、とすると「今」必要ではない修正が多発する 導入直後に検出された不具合の扱いは事前に定めておかないと混乱のもと 現状の品質に対して期待できるメリットのコスト対比がまだ低い 以下のいずれかの状況にならない限り導入メリットが薄い 今後 ウェブサービス 開発が複雑化して不具合対応コストが増加 今後 ウェブサービス 開発速度が向上して不具合対応コストが ボトルネック となる SAST/IASTツールが コモディティ化 して導入コストが減少 最後に セキュリティのシフトレフト自体は 開発プロセス における理想であることに違いはないと考えています。 ただし商用サービスを提供する立場としては実現するためにはもう少し普及して コモディティ化 (に伴う低価格化)してくれないと導入は正直厳しいというのが現時点での判断です。 一方でライブラリなどを オープンソース で公開する場合など、不具合の影響が広範囲に波及するようなプロダクトに関していえば、 GitHub のパブリック リポジトリ でのCode Scanningが無料で利用できるため積極的に使っていくべきだと感じました。 いわゆるオーバーエンジニアリングになってコスト増を招いてしまうことは、ビジネスとしてサービス開発を行っている以上は避けるべき。 ↩ そしてセキュリティのシフトレフトに興味を持つ会社は比較的セキュリティ意識が高いはず……。 ↩ パブリック リポジトリ であれば無料で導入できるようなので、公開しているライブラリなどにはぜひ導入したいですね。 ↩
アバター
こんにちは、あるいはこんばんは。 私は楽楽販売の案件開発チーム(新機能開発チーム)の開発リーダーをしている @taclose です☆ 今回のブログでは、楽楽販売の案件開発チームの構成や業務を紹介しようと思います! 累計導入社数4,400社突破 の楽楽販売がどのような開発体制で、普段どんな事に取り組んでいるのかを知ってもらえればと思います! 楽楽販売の開発チーム構成 チームの紹介 チームのミッションは何か? 普段具体的にはどんな事をやっているのか?どんな事を考えているのか? 最近行った業務改善とは具体的にどんなものがあるのか? 今後の展望 さいごに まずは各チームの業務分担から説明します。 楽楽販売の開発チーム構成 チーム名 業務 DevOpsチーム 運用・保守、リリース作業等を行うチーム SAチーム カスタマーサポートが対応出来ない技術的な問い合わせに対応するチーム VCチーム ベトナム 開発拠点とのオフショア開発をするチーム 案件開発チーム 新機能の開発を行うチーム 楽楽販売開発課のチームは業務毎に大きく分けてこのように分かれています。 私たち案件開発チームはメインとなる開発以外とも言える運用・保守・サポート・定例作業等から独立しており、 メインとなる業務に集中する事ができます! 他のチームの方々に感謝ですね! そのおかげで、リソース調整も非常にやりやすく 計画的に業務を進める事ができています 。 私は 開発に集中できて ワークライフバランス が保ちやすいこのチーム が一番気に入っていますっ! では、もっと具体的にチームの紹介をしていきましょう。 チームの紹介 楽楽販売は既に多くの機能が存在していますが、法改正の影響や顧客のニーズに合わせて常に新しい機能が要望されています。 そんな機能追加を概要設計〜実装/テストまで行うのが案件開発チームになります。 メンバーは8名。だいたい常に2案件の機能開発が同時進行で開発が進められており、新機能開発以外にもバグ改修、 リファクタリング なんかも行っています。 構成としてはこんな感じでしょうか 役割 業務内容 AM(1名) アシスタントマネージャー。メインはリソース調整やスケジュールの調整。課長と開発メンバーの間に入って活躍してくれます。概要設計とかもやってます。 SP(2名) 開発リーダー的存在。コードレビューや設計方針、開発フローの見直し等をメインに行う。直接コーディングする機会は少ないです。 開発メンバー(5名) 実装の要。詳細設計、実装、テストを行う主力部隊です。 一覧にすると上のような立ち回りですが、SPと開発メンバーの垣根はそこまで厳密ではありません。 私としては、「 スケジュールとかリソースとかの調整毎から解放されてメイン業務に集中できる 」これがまたうれしいポイントですね! AMお疲れ様です!! とは言いつつも表面的な事を話しても余りイメージがわかないかもしれないですね! FAQ的な形で魅力を紹介していこうかと思いますっ! チームのミッションは何か? 一つは言わずもがなですが、顧客が求める機能を迅速に実装する事です。 もう一つは 内部品質の向上というのも手が抜けないミッション となっています。 楽楽販売は15年以上開発が続けられている長い商材であるため、内部品質としては問題がある実装というのが存在しています。 紆余曲折とした経緯があるのはエンジニアであれば容易に想像がつくでしょう・・・ でも、楽楽販売がすごいなと思うのは、「 リファクタリング 」「 アーキテクチャ 見直し 」といったような、 内部品質の改善を行う事も機能開発の一環として実施している事 です。 これの何がすごいのか? エンジニアならわかるかもしれませんが、案外ここにコストを割く事を経営側は良しとしないからです。 でも 楽楽販売は違います!今後の更なる成長のためには必要な事なら リファクタリング だって実施します! デメリットとして バグを出すかもしれない(何か機能がグレードアップするわけでもないのに) コストがかかる(何か機能がグレードアップするわけでもないのに) こんな事があるのはわかった上でミッションコンプリートを目指します。 では、「具体的にはどんな事をやっているのか?」を話していこうと思います。 普段具体的にはどんな事をやっているのか?どんな事を考えているのか? ざっくり言うなら、新機能の開発に対して 概要設計を作成する 実装する テストする 当然これが主な業務になります。60%〜80%の時間はこれに使ってます。1週間単位で見るなら 1週間のスケジュールでどこまで開発が進められるか話す 主業務を1週間やる 目標通り進んだか? KPT (Keep, Probrem, Try)で振り返る ここがよかった!今後これはルール化しよう! これは改善しないとまずいよ! こんな感じですね!じゃ 残りの20%ぐらいは何をやっているのか? 「 KPT で出たTryや、積み残されていた業務改善をしています」 最近行った業務改善とは具体的にどんなものがあるのか? 例えばですが、最近は プルリク エス トの粒度を小さくしよう メトリクスを計測して複雑度を意識しよう 機密情報が リポジトリ にpushされるのを事前に防ごう XXX(色々)を自動化しよう リファクタリング を提案しよう とかでしょうかっ!あくまで読者に伝わりやすい例です。他にも色々やってますよ! 今後の展望 これからもまだまだ楽楽販売は進化を続けます 。そのため、 内部品質の改善 というのは重要なテーマとなっています。 案件開発チームは新機能を開発出来る土台作りも担っているわけです。 今後としては 新機能の迅速なリリースが行える体制作り 新機能を不具合なくリリースできる内部品質の更なる向上 これを推し進めていきたいと思います。 さいごに 楽楽販売の案件開発チームについて紹介させてもらいました。 チームが一丸となり ラク スが掲げる リーダーシッププリンシプル を念頭に置きながら、常に発生する課題(理想と現実のギャップ)とどう向き合っていくべきかを考え、「限られたリソースの中で今は何をどのようにするべきか?」を考え、それを行動にうつしているすぱらしいチームです。 時にユーモア、時にエレガント、興味があれば是非楽楽販売の開発チームに来てくださいね!
アバター
はじめに ltreeとは ltree型 ltreeの操作 活用法 1. 承認フローの構築 事前準備 テーブル作成 データ追加 2. テーブルに細かくアクセス制御をかける 事前準備 ltreeの有効化 テーブル作成 ポリシー作成 行セキュリティポリシーの有効化 ポリシーの設定 データを追加 ユーザー作成 試す まとめ はじめに こんにちは! エンジニア2年目のTKDSです! 今回はltreeについて調べ、その活用法を考えてみました。 ltreeについて、ltreeの活用法の2段構成です。 ltreeとは 階層ツリー構造を模した構造を格納する機能を提供する 拡張機能 です。 詳しくは ドキュメント をみてください。 ltree型 階層ツリー構造を表す型です。 例)`Company.Department.Team1 ドット区切りで大文字小文字は区別しないようです。 各データはラベルと呼びます(上記でのCompany、Department、Team)。 ltreeの操作 よく使いそうな操作だけ2つ挙げます。 ltree @> ltree : 左辺の引数が右辺の親要素(か同じ)かどうか 例) SELECT name FROM organization WHERE path @> 'Top.IT.Software'; テーブルのpathがTop.IT.Softwareの親に該当する要素をすべて探します。 ltree <@ ltree : 左辺の引数が右辺の子要素(か同じ)かどうか 例) SELECT name FROM organization WHERE path <@ 'Top.IT'; テーブルのpathがTop.ITを親に持つ要素を探します。 このSELECT文では、Top.ITを親に持つ要素をすべて探します。 ~ :一致するパスの検索 右辺に指定したパスに一致するltreeを探します。 SELECT name FROM organization WHERE path ~ ' Top.IT.* ' ; SELECT name FROM organization WHERE path ~ ' Top.I*.* ' ; 活用法 2種類ほど活用例を考えてみました。 1. 承認フローの構築 ltreeを使って、承認フローに使えるテーブルを構築してみます。 事前準備 compose. yaml ces : db : image : postgres:16.4-bullseye container_name : db environment : POSTGRES_USER : postgres POSTGRES_DB : postgres POSTGRES_PASSWORD : postgres ports : - "127.0.0.1:5432:5432" volumes : - db_data:/var/lib/postgresql/data - ./init.sql:/docker-entrypoint-initdb.d/init.sql healthcheck : test : [ "CMD-SHELL" , "pg_isready -U postgres -d postgres" ] interval : 30s timeout : 10s retries : 5 start_period : 10s volumes : db_data : init. sql -- ltree拡張の有効化 CREATE EXTENSION IF NOT EXISTS ltree; テーブル作成 CREATE TABLE approval_flow ( id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, flow_path ltree UNIQUE , -- 階層構造を表現するためのltreeカラム status text, -- 各承認ステップのステータスを格納 approver text -- 承認者(ユーザーIDや名前) ); データ追加 INSERT INTO approval_flow (flow_path, status, approver) VALUES ( ' 1.approver.userA ' , ' open ' , ' userA ' ), ( ' 2.approver.userB ' , ' pending ' , ' userB ' ), ( ' 2.approver.userC ' , ' pending ' , ' userC ' ), ( ' 3.approver.userD ' , ' closed ' , ' userD ' ); ここまででデータ投入までできました。 では、2の承認者でpendingのひとを検索してみましょう。 SELECT approver FROM approval_flow WHERE flow_path ~ ' 2.approver.* ' AND status = ' pending ' ; userCを approved にしてみましょう。 UPDATE approval_flow SET status = ' approved ' WHERE flow_path = ' 2.approver.userC ' ; 1ユーザー検索結果から消えてるのがわかります。 階層構造を表現できるので、1列で承認が必要な人を管理できて便利です。 2. テーブルに細かくアクセス制御をかける 次に活用例2です。 もともと考えてたのはこの使い方でした。 スキーマ よりも細かく、グループを区切ってアクセス制御できないかなと考えたことがありました。 そのときに、調べてみつけたのが階層構造を扱うltreeでした。 この活用方法では、ltreeでグループを作り、 Row Level Security (行セキュリティポリシー) の有効化で参照単位を制限してアクセス制御を実現します。 テーブルの関連のイメージは以下の図です。 基本的にすべてのテーブルをテナントIDで紐付けて、事故ってテナント外のデータを参照しないようにしました。 では、実際に環境を構築してきます。 事前準備 1のときと同じです。 docker compose down -v、docker compose up で環境作り直しておきます。  docker exec -it db psql -U postgres でログインします。 ltreeの有効化 -- ltree拡張の有効化 CREATE EXTENSION IF NOT EXISTS ltree; ついでにtest スキーマ を作って参照するようにしておきます。 ltreeの設定はpublic スキーマ にインストールされるようなので、publicも追加しておきます。 publicを含めないとltreeが参照できず、ltree型がないエラーになります。 CREATE SCHEMA test; set search_path to test, public ; テーブル作成 tenantテーブル CREATE TABLE test.tenants ( id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, name TEXT NOT NULL ); usersテーブル CREATE TABLE test.users ( id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, username TEXT NOT NULL , email TEXT NOT NULL , tenant_id BIGINT NOT NULL , CONSTRAINT fk_tenant FOREIGN KEY (tenant_id) REFERENCES test.tenants(id) ); rolesテーブル ロールの名前を設定するテーブル CREATE TABLE test.roles ( id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, name TEXT NOT NULL , tenant_id BIGINT NOT NULL , CONSTRAINT fk_tenant FOREIGN KEY (tenant_id) REFERENCES test.tenants(id), CONSTRAINT unique_role_name_per_tenant UNIQUE (name, tenant_id) ); role_permissionsテーブル:ロールに紐づく権限を設定するテーブル ltreeでアクセス制限を設定します。 CREATE TABLE test.role_permissions ( id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, role_id BIGINT NOT NULL , access_ltree LTREE NOT NULL , tenant_id BIGINT NOT NULL , CONSTRAINT fk_role FOREIGN KEY (role_id) REFERENCES test.roles(id), CONSTRAINT fk_tenant FOREIGN KEY (tenant_id) REFERENCES test.tenants(id) ); user_rolesテーブル:ユーザーとロールの紐付けを管理するテーブル CREATE TABLE test.user_roles ( id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, user_id BIGINT NOT NULL , role_name TEXT NOT NULL , tenant_id BIGINT NOT NULL , CONSTRAINT fk_user FOREIGN KEY (user_id) REFERENCES test.users(id), CONSTRAINT fk_tenant FOREIGN KEY (tenant_id) REFERENCES test.tenants(id) ); documentsテーブル:アクセス制限するデータを投入するテーブル CREATE TABLE test.documents ( id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, title TEXT NOT NULL , content TEXT NOT NULL , tenant_id BIGINT NOT NULL , access_ltree LTREE NOT NULL , CONSTRAINT fk_tenant FOREIGN KEY (tenant_id) REFERENCES test.tenants(id) ); すべて作成したらテーブル一覧を確認してみます \dt test.* ポリシー作成 アクセス制御を実現するためのルールを作っていきます。 行 セキュリティポリシー の有効化 ALTER TABLE test.documents ENABLE ROW LEVEL SECURITY; ALTER TABLE test.documents FORCE ROW LEVEL SECURITY; 有効になっているか確認します。 SELECT relrowsecurity, relforcerowsecurity FROM pg_class WHERE relname = ' documents ' ; ポリシーの設定 詳しくは ドキュメント をみてください CREATE POLICY tenant_rbac_ltree_policy ON test.documents USING ( EXISTS ( SELECT 1 FROM test.user_roles ur JOIN test.roles r ON ur.role_name = r.name AND ur.tenant_id = r.tenant_id JOIN test.role_permissions rp ON r.id = rp.role_id WHERE ur.user_id = current_setting( ' session.authorization_user_id ' )::BIGINT AND rp.tenant_id = test.documents.tenant_id AND rp.access_ltree @> test.documents.access_ltree ) ); CREATE POLICY tenant_rbac_ltree_policy_insert_update ON test.documents WITH CHECK ( EXISTS ( SELECT 1 FROM test.user_roles ur JOIN test.roles r ON ur.role_name = r.name AND ur.tenant_id = r.tenant_id JOIN test.role_permissions rp ON r.id = rp.role_id WHERE ur.user_id = current_setting( ' session.authorization_user_id ' )::BIGINT AND rp.tenant_id = test.documents.tenant_id AND rp.access_ltree @> test.documents.access_ltree ) ); session.authorization_user_idを設定することで実際のアクセス制御を実現します。 データを追加 テナントデータの投入 INSERT INTO tenants (name) VALUES ( ' Tenant A ' ); INSERT INTO tenants (name) VALUES ( ' Tenant B ' ); ロールデータの投入 -- Tenant Aのロール INSERT INTO roles (name, tenant_id) VALUES ( ' Admin ' , 1 ); INSERT INTO roles (name, tenant_id) VALUES ( ' User ' , 1 ); -- Tenant Bのロール INSERT INTO roles (name, tenant_id) VALUES ( ' Admin ' , 2 ); INSERT INTO roles (name, tenant_id) VALUES ( ' User ' , 2 ); ロール権限の投入 -- Tenant AのAdminロールの権限 (Sales部門全体にアクセス可能) INSERT INTO role_permissions (role_id, access_ltree, tenant_id) VALUES ( 1 , ' TenantA.Sales ' , 1 ); -- Admin role for Tenant A (Sales部門全体) -- Tenant AのUserロールの権限 (Sales部門のTeam 2のみアクセス可能) INSERT INTO role_permissions (role_id, access_ltree, tenant_id) VALUES ( 2 , ' TenantA.Sales.Team2 ' , 1 ); -- User role for Tenant A (Team 2のみ) -- Tenant BのAdminロールの権限 (Marketing部門全体にアクセス可能) INSERT INTO role_permissions (role_id, access_ltree, tenant_id) VALUES ( 3 , ' TenantB.Marketing ' , 2 ); -- Admin role for Tenant B (Marketing部門全体) -- Tenant BのUserロールの権限 (Marketing部門のTeam 2のみアクセス可能) INSERT INTO role_permissions (role_id, access_ltree, tenant_id) VALUES ( 4 , ' TenantB.Marketing.Team2 ' , 2 ); -- User role for Tenant B (Team 2のみ) ユーザーデータの投入 -- Tenant Aのユーザー INSERT INTO users (username, email, tenant_id) VALUES ( ' user_a1 ' , ' user_a1@example.com ' , 1 ); INSERT INTO users (username, email, tenant_id) VALUES ( ' user_a2 ' , ' user_a2@example.com ' , 1 ); -- Tenant Bのユーザー INSERT INTO users (username, email, tenant_id) VALUES ( ' user_b1 ' , ' user_b1@example.com ' , 2 ); INSERT INTO users (username, email, tenant_id) VALUES ( ' user_b2 ' , ' user_b2@example.com ' , 2 ); ユーザーとロールの紐付け -- Tenant Aのユーザーにロールを割り当て INSERT INTO user_roles (user_id, role_name, tenant_id) VALUES ( 1 , ' Admin ' , 1 ); -- user_a1 is Admin in Tenant A INSERT INTO user_roles (user_id, role_name, tenant_id) VALUES ( 2 , ' User ' , 1 ); -- user_a2 is User in Tenant A -- Tenant Bのユーザーにロールを割り当て INSERT INTO user_roles (user_id, role_name, tenant_id) VALUES ( 3 , ' Admin ' , 2 ); -- user_b1 is Admin in Tenant B INSERT INTO user_roles (user_id, role_name, tenant_id) VALUES ( 4 , ' User ' , 2 ); -- user_b2 is User in Tenant B ドキュメントデータの投入 -- Tenant Aのドキュメント (会社=Tenant A, 部門=Sales, チーム=Team 1) INSERT INTO documents (title, content, tenant_id, access_ltree) VALUES ( ' Document A1 ' , ' Content of Document A1 ' , 1 , ' TenantA.Sales.Team1 ' ); INSERT INTO documents (title, content, tenant_id, access_ltree) VALUES ( ' Document A2 ' , ' Content of Document A2 ' , 1 , ' TenantA.Sales.Team2 ' ); -- Tenant Bのドキュメント (会社=Tenant B, 部門=Marketing, チーム=Team 1) INSERT INTO documents (title, content, tenant_id, access_ltree) VALUES ( ' Document B1 ' , ' Content of Document B1 ' , 2 , ' TenantB.Marketing.Team1 ' ); INSERT INTO documents (title, content, tenant_id, access_ltree) VALUES ( ' Document B2 ' , ' Content of Document B2 ' , 2 , ' TenantB.Marketing.Team2 ' ); ユーザー作成 postgresユーザーのままだとすべてのレコードがみえてしまうので、別のユーザーを作成します。 CREATE USER access_user WITH PASSWORD ' password ' ; -- スキーマへのアクセス権限(USAGE)を付与 GRANT USAGE ON SCHEMA test TO access_user; -- テーブルに対するCRUD操作権限を付与 GRANT INSERT, SELECT, UPDATE, DELETE ON ALL TABLES IN SCHEMA test TO access_user; 試す 最初に全データをpostgresユーザーでみておきましょう。 各記事に access _ltreeが設定されているのがわかります。 この権限通りにアクセス制限できているか確認していきます。 ログインします。 docker exec -it db psql -U access_user -d postgres どの権限でアクセスするかは、 session.authorization_user_id で決められます。 まずは設定なしでやってみます。 権限がないのでみれません。 次はuser_id=1でやってみます。 権限はTenantAのSales部門全体にアクセス可能です。 次はuser_id=2でやってみます。 権限はTenantAのSales部門のTeam 2のみアクセス可能です。 次はuser_id=3でやってみます。 権限はTenantBのMarketing部門全体にアクセス可能です。 次はuser_id=4でやってみます。 権限はTenantBのMarketing部門のTeam 2のみアクセス可能です。 次はuser_id=5でやってみます。 紐付けられるユーザーはいません。 しっかり操作権限が絞られているのが確認できました! まとめ ltreeについて紹介と活用方法を考えてみました。 階層構造を簡単に扱えて、パターンマッチで検索もできるので非常に便利です。 記事をみてくださったかたもぜひ活用方法を考えてみてください!(社内のかたはこっそり教えていただけるとありがたいです) ここまで読んでいただきありがとうございました!
アバター
こんにちは、あるいはこんばんは。 だいたいサーバサイドのエンジニアの( @taclose )です☆ GitHub Copilotが活躍している昨今、弊社では GitHub で更に開発効率を良くしていこうという流れで日々自動化が行われております。 今回はそんな時代だからこそ求められている GitHub Actionsについて、初心者向けにワークフロー作成の際に知っておきたいコツと教訓について紹介します。 GitHub Actionsのワークフローを読めるけど、まだ自信がないという方はぜひ参考にしてください! 「それもっと早く知っておきたかった!」「初心者がつまづきがちなポイント!」を解説します! 読者ターゲット ワークフロー作成のコツ 1. run セクションで式 ${{}} は極力使わない 危険その1:コードインジェクションのリスク 危険その2:データのサニタイズ不足 2. workflow_call を使う際の注意点 注意点その1:github コンテキストは引き継がれる 注意点その2:secrets の扱い 3. GITHUB_TOKEN で行った操作は再度トリガーされない 補足: workflow_run トリガーを活用する まとめ 参考記事・お勧めサイト 読者ターゲット GitHub アクションなんとなく書いてるけど、 最適な書き方が出来ているか自信がない 方とか! ワークフロー作成のコツ 1. run セクションで式 ${{}} は極力使わない 例: jobs : example-job : runs-on : ubuntu-latest steps : - run : echo "Hello, ${{ github.event.inputs.name }}!" このように、 run セクションで ${{ }} 式を使われるのはよく見かけますが、実は避けるべきです! 理由は主に2つあります。 危険その1:コードインジェクションのリスク ${{ github.event.inputs.name }} などを直接 run に渡すと、もしその値が悪意のあるものであった場合、 意図しないコマンドが実行される危険 があります。 例えば、もしシークレットの中に rm -rf / なんてあったら…ッ!! 危険その2:データの サニタイズ 不足 データを サニタイズ (無害化)せずに渡すことで、特定の記号や文字列が予期しない動作を引き起こすことがあります。 GitHub Actions内で式を使う場合は、 env 変数や他の手段を使ってデータの安全性を確保しましょう。 良い例: jobs : example-job : runs-on : ubuntu-latest steps : # "${NAME}" このダブルクォーテーションで囲んでいるのがミソ!何を代入されてもこけません! - run : echo "Hello, ${NAME}!" env : NAME : ${{ github.event.inputs.name }} このように、式を直接 run に渡さず、 環境変数 ( env ) に渡してから使うと、 "(ダブルクォーテーション) が混じっているかも?とかの考慮が要らず安全です。 2. workflow_call を使う際の注意点 workflow_call を使うと、他のワークフローを再利用できて便利 です。 時には リポジトリ を跨いで共通のワークフローなんて事もやりたいですよね。 しかし、いくつか気を付けるべき点があります。 注意点その1: github コンテキストは引き継がれる 呼び出し元のワークフローで使用していた github コンテキストは、そのまま呼び出し先にも引き継がれます。 例えば、 github.event や github.actor などは呼び出し元のものが反映されるため、何か 特定のイベントやユーザーで動作させたい場合には注意が必要 です。 例: on : workflow_call : inputs : name : required : true type : string jobs : example-job : runs-on : ubuntu-latest steps : # ここで出力されるevent_nameは呼び出し元になります! - run : echo "Running as ${{ github.actor }} for event ${{ github.event_name }}" 注意点その2: secrets の扱い workflow_call では、 secrets が自動で渡されるわけではなく、呼び出し側で明示的に渡す必要があります 。 忘れがちなポイントなので注意しましょう! 例: # workflow_callを呼び出してる側の実装 jobs : call-reusable-workflow : uses : ./.github/workflows/reusable-workflow.yml secrets : # secretsはこのように渡してあげないと参照出来ません! MY_SECRET : ${{ secrets.MY_SECRET }} 呼び出し元でこのシークレットを適切に設定しないと、ワークフローがうまく動かない可能性があるので、しっかりと設定してください。 3. GITHUB_TOKEN で行った操作は再度トリガーされない 何言ってるんだろ?って思うかもしれませんが、ワークフローで色々自動化していると案外詰まるポイントです! GitHub Actionsでは、デフォルトで GITHUB_TOKEN が提供されており、これを使って API 操作や リポジトリ への変更を行うことができます。 しかし、ここで一つ覚えておきたい仕様があります。 それは、 GITHUB_TOKEN で行った操作は再度ワークフローがトリガーされない という点です。 例: # GITHUB_TOKENを使ってissueを投稿しているサンプルです。 jobs : example-job : runs-on : ubuntu-latest steps : - name : Create a new issue run : | curl -X POST -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ -d '{"title":"New Issue","body":"This issue is created by GitHub Actions!"}' \ https://api.github.com/repos/your-repo/issues このように GITHUB_TOKEN を使って何かissueを投稿した場合、その操作自体が新しいワークフローを起動することはありません。 つまり、「issueが作成されたら通知するワークフロー」とかを作っていたとしても通知が飛ばない結果になります。 これを知らないと「なんでワークフローが動かないんだろう?」とハマることがあるので覚えておきましょう! 補足: workflow_run トリガーを活用する もし、 GITHUB_TOKEN での操作後にワークフローを自動的に起動したい場合は、 workflow_run トリガーを活用することを検討してみるのも良いかもしれません。 これで他のワークフローの完了をトリガーにできます。 まとめ GitHub Actionsでワークフローを作成する際には、いくつかの落とし穴や仕様に注意する必要があります。 今回紹介した3つのポイントを押さえておけば、初心者でも安全かつスムーズにワークフローを作成できるはずです。 run セクションで式 ${{}} は使わず、代わりに env を活用しよう。 workflow_call では github コンテキストと secrets の扱いに注意! GITHUB_TOKEN の操作では再度ワークフローがトリガーされない仕様を覚えておこう。 このコツを頭に入れて、快適な GitHub Actionsライフを送ってくださいね! 参考記事・お勧めサイト 最後に参考にした記事やお勧めのサイトを紹介しておきます。 actionlint playground workflowの構文チェックが出来ます。pushする前にサッと確認すると無駄が減ります! GitHub CI/CD実践ガイド――持続可能なソフトウェア開発を支えるGitHub Actionsの設計と運用 (エンジニア選書) 初心者から上級者まで幅広い人にお勧めできる良書です! zenn.dev
アバター
こんにちは。 株式会社 ラク スで先行技術検証をしたり、ビジネス部門向けに技術情報を提供する取り組みを行っている「技術推進課」という部署に所属している鈴木( @moomooya )です。 ラク スの開発部ではこれまで社内で利用していなかった技術要素を自社の開発に適合するか検証し、ビジネス要求に対して迅速に応えられるようにそなえる 「技術推進プロジェクト」 というプロジェクトがあります。 このプロジェクトで「 PostgreSQL 環境における、DB定義変更を伴う無停止リリース」にまつわる検証を進めているので、その中間報告を共有しようかと思います。 ※本記事はタイトルに 「概要と計画」編 とあるように、通年で行う調査の前半時点の中間報告となります。 実際の検証結果については3月末に予定している後編をお待ち下さい。 課題の経緯、前提条件 課題の経緯 無停止リリース実現のモチベーション 前提条件 実現手法 候補に上がった手法 DDL最適化によるロック時間短縮 リトライ機構によるロック時間回避 pg-oscを利用してのロック時間短縮 pglogicalを利用してのロック時間短縮 Patroni + etcd pgpool-II 検証対象とならなかった手法 pglogicalを利用してのロック時間短縮 を除外した理由 Patroni + etcd / pgpool-II を除外した理由 検証の観点 最後に 課題の経緯、前提条件 課題の経緯 ラク スではこれまでも特定条件下のリリースにおいては無停止でのリリースを実現していましたが、一部のパターン、特にDB定義に変更が入る場合に無停止でのリリースを実現できずにいました。 これに対して、2020年に新規サービスを想定して(≒ ミドルウェア もゼロベースで選定して)の無停止について検証を行いました( 参考記事1 , 参考記事2 , 参考記事3 )が、それほど新規サービスが多くなかったことと、既存サービスへの転用コストが高すぎるためにノウハウを流用できないことから、さらなる検証を必要としていました。 今回の検証では既存サービスで主に採用されている ミドルウェア やシステム構成をベースとして、無停止リリースを実現するために検証を進めています。 無停止リリース実現のモチベーション そもそもなぜ無停止リリースを行いたいかというと、主としてはリリースの自由度を高めたい、逆に言えばリリース時の制約を減らしたいというのが最大のモチベーションです。 近年注目されるDORA, Four Keysといった開発生産性の観点でもリリース単位を小さくすることを良しとされていますが、1日に何度もリリースすることが必ずしも正しいとは言えない 1 ものの、無停止リリースが出来ないがためにリリース規模を大きくしなければならないという状態は良い状態ではありません。 無停止リリースを実現することで、意図に反するリリース規模肥大が抑制できることが期待する状態です。 前提条件 前述の通り、今回の検証では既存サービスで主に利用している PostgreSQL をベースとした無停止リリースの実現となります。 ここでいうリリースには、テーブル定義の変更を伴うものも含みます。 PostgreSQL にはオンライン DDL が用意されていませんが、サービス全体としてオンラインでの DDL 適用を実現することが目標となります。 なお、「サービス全体で」としているように、無停止の定義も 「リリース中のエンドユーザーの操作を欠落、およびエラーにしないこと」 として取り組みます。 実現手法 本記事はタイトルにもあるように通年で行う調査の前半中間報告記事となります。 課題を解決するための候補となった手法と、それらを用いてどういった検証を行う予定なのかを記述したいと思います。 候補に上がった手法 調査の結果、候補に上がった手法は以下の6つです。それぞれに対して概要をまとめます。 DDL 最適化によるロック時間短縮 リトライ機構によるロック時間回避 pg-oscを利用してのロック時間短縮 pglogicalを利用してのロック時間短縮 Patroni + etcd pgpool-II DDL 最適化によるロック時間短縮 PostgreSQL の DDL 実行において、例えばカラムの追加と制約の付与を1クエリで実行すると、すべての処理が終わるまで高いロックレベルでロックされるという現象があります。 これを「カラムの追加」と「カラムへの制約付与」の2クエリにすることで、高いロックレベルと低いロックレベルの2段階になり、ロックされる操作が緩和される状態を狙います。 ただ PostgreSQL もバージョンアップに伴い、上記のようなクエリを内部で最適化して実行してくれるケースも増えているため、改めて効果のあるもの無いものを整理して、必要なものだけに DDL の最適化を適用するような ガイドライン を導ければと考えています。 リトライ機構によるロック時間回避 DDL によるロックは一時的なものなのでアプリケーション側にリトライ機構を用意することで、 DDL によるロックをアプリケーション側からみて「なかったこと」に出来ないかという試みです。 今回の検証では Java (かつSpringを利用したアプリケーション)に限定されてしまいますが、Spring Retryを用いたリトライ機構を組み込むことで、 DDL を実行してもアプリケーション側からは意識することなく処理を継続できることを期待します。 github.com pg-oscを利用してのロック時間短縮 DDL 適用によるロック時間の短縮テクニックとして、テーブルのコピー(これをシャドウテーブルと呼ぶ)を作成し、シャドウテーブルに対して定義変更やデータ マイグレーション を行ってから、元のテーブルと差し替えることでロック時間を短くするというテクニックがあります。 作業中はトリガーを利用してデータの同期も行います。 ただしこれは、手作業で行うには手順が煩雑でミスのもとになりそうな危険性を感じます。 これを補助してくれるツールがpg-oscとなります。 github.com pglogicalを利用してのロック時間短縮 PostgreSQL には スキーマ やテーブルの単位で複製を行う「論理 レプリケーション 」という機能があります。 論理 レプリケーション ではWALではなく、WALをデコードした操作内容で同期を取るため、大雑把にいえば同じ SQL を適用できるのであれば余計なカラムが増えていたりテーブル定義が厳密に同一ではなくても同期を取ることができるようです。 pglogicalは論理 レプリケーション を補助するツールで、論理 レプリケーション を上述のシャドウテーブルのように使ってロック時間を短縮することができるのではないかと考えました。 github.com Patroni + etcd Patroniは PostgreSQL ノード内に設置し、外部のetcdなどと連携して PostgreSQL ノードの状態管理を行ってくれるツールです。 これによって PostgreSQL がロックしている間の状態管理と振り分けを行えないかと考えましたが……あくまでPatroniは高可用性ソリューションで PostgreSQL の死活監視を行ってくれるもので、テーブル単位のロックを監視するものではなさそうでした。 github.com pgpool-II こちらもpgpool-IIのコネクションプーリング機能で対応できないかと考えましたが、Patroni同様死活監視を行うものでロックによるフェイルオーバーを行うものではなさそうです。 www.pgpool.net 検証対象とならなかった手法 本検証はメインの開発業務の傍らで特別チームを組んで行っているため、すべてを検証することは出来ません。 そのためこの時点で優先度が低いと考えた以下の手法については検証対象外としました。 pglogicalを利用してのロック時間短縮 Patroni + etcd pgpool-II pglogicalを利用してのロック時間短縮 を除外した理由 発想としてはpg-oscと同様だが、pg-oscよりもより低レイヤを扱うツールであるため、pg-oscで必要な操作が賄えるのであればより人手を介さない手法のほうが今後の運用トラブルを避けることができると考え、pg-oscを優先しました。 Patroni + etcd / pgpool-II を除外した理由 これらは初期調査時は使えるかと思っていましたが、上述の通りそもそも用途が違っていた(ロックの監視ではなく、死活監視)ので対象外にしました。 また、Patroniの場合は新たにetcd クラスタ を構築しなければならず増加する運用コストもそれなりに高額になることも見込まれたため対象外になりました。 検証の観点 今後の予定として、10月以降の後半では、以下の3つの手法について検証を進めていく予定です。 DDL 最適化によるロック時間短縮 リトライ機構によるロック時間回避 pg-oscを利用してのロック時間短縮 検証内容としては、アプリケーションからの SQL クエリ(SELECTによる参照や、UPDATEによる更新など一通りのパターン)が連続してリク エス トされている状況をテスト環境に構築し、それぞれの手法を用いた状況で DDL クエリ(ロックレベル別に主要な DDL クエリを試します)を実行し、アプリケーション側からの SQL クエリに欠損や、エラーが出ないかを観測します。 実運用時よりも高密度な連続リク エス ト環境を用意して、アプリケーションでのエラーが発生しないことを目指します。 また手法についても結果と必要によっては組み合わせた環境での検証も行い、理想的な実現方法を見つけたいと思います。 最後に ラク スの技術推進プロジェクト(本取り組み)では、世間的に「切り替えは一瞬で完了する」「ドキュメント上は〇〇パラメータによって実現可能」と謳われている技術要素に関しても、自社の基準と照らし合わせて要求を満たしているかどうかを検証しています 2 。 これらは一見無駄にも見える検証ではありますが、ユーザーに満足してもらえるシステムを提供するエンジニアの責任として地道に取り組んでいきたいと考えています。 検証結果は3月末(もしかしたら4月になるかも)にまた記事にして公開したいと思いますので、しばしお待ちいただければと思います。 私としては妄信的に1日に何度もデプロイする運用にすべきではないという考えです。1日に何度もデプロイ可能な環境を整えること自体はそこまで否定しない(それによって運用コストが上がるなら正しく技術評価しないといけないけど)ですが。もちろん事業内容や業績上プラスになると評価できるサービスであれば目指すべきです。 ↩ 「一瞬」が数秒だったり、「◯◯パラメータ」が動作しなかったり、特定環境下で無効だったり、ということはよくある。 ↩
アバター
初めまして!新卒1年目のmochi_proteinと申します。 CSR / SSR / SSG / ISRがどのような概念か、 架空アプリを例として、それぞれの違いを初学者向けにやさしく解説していきます! 🔖目次は以下の通りです🔖 はじめに 架空アプリ「楽楽鮮魚」の仕様 前提知識 レンダリングとは? 動的にHTMLを生成するとは? CSR(クライアントサイドレンダリング)とは? 概要 「楽楽鮮魚」が CSR を採用したら? 初期画面(在庫一覧画面)表示までの流れ 詳細画面への遷移時の流れ CSRのメリット CSRのデメリット どのようなサービスに向いているか SSR(サーバーサイドレンダリング)とは? 概要 「楽楽鮮魚」が SSR を採用したら? 初期画面(在庫一覧画面)表示までの流れ 詳細画面への遷移時の流れ SSRのメリット SSRのデメリット どのようなサービスに向いているか SSG(スタティックサイトジェネレーション)とは? 概要 「楽楽鮮魚」が SSG を採用したら? 初期画面(在庫一覧画面)表示までの流れ 詳細画面への遷移時の流れ SSGのメリット SSGのデメリット どのようなサービスに向いているか ISR(インクリメンタルスタティックリジェネレーション)とは? 概要 「楽楽鮮魚」が ISR を採用したら? 初期画面(在庫一覧画面)表示までの流れ 初期リクエスト後、複数回/ユーザからの在庫一覧画面へのアクセス時(キャッシュ有効期限内)の流れ キャッシュの有効期限後のリクエスト時の流れ 詳細画面への遷移時の流れ ISRのメリット ISRのデメリット どのようなサービスに向いているか おわりに 参考 はじめに 今回、4つの レンダリング 手法を解説するにあたり、 「楽楽鮮魚」という架空の在庫管理アプリ を例として、それぞれの レンダリング 手法を採用した時、 どこで レンダリング が行われて画面表示されるのか、流れを追っていくことで理解していきましょう! 楽楽鮮魚(架空アプリ)の仕様 架空アプリ「楽楽鮮魚」の仕様 「楽楽鮮魚」は、自社の魚の在庫状況を確認することができるアプリ 初期画面=在庫一覧画面(一覧テーブルに「魚種名 / 在庫(匹数) / [詳細ボタン]」がある) [詳細ボタン]押下で、詳細画面に遷移する 詳細画面は、「魚種名 / 在庫 / 産地 / 入荷日」が表示される 実際にこのアプリをリリースするならどの手法が良いのか も考えながらご覧になってみてください! 前提知識 レンダリング とは? 「 レンダリング 」という単語自体は、
広くデータを視覚化することを指しますが、
 CSR や SSR といった概念が指す「 レンダリング 」として、ここでは
 JavaScript などで 動的にHTMLを生成すること を指して解説いたします。 動的にHTMLを生成するとは? 動的にHTMLを生成するとは、 JavaScript などによって新たなHTML要素を生成したり、既存のHTMLを更新することを指します。 
例えば、
ユーザーがボタンを押すなどのアクションを取ったとき、またはサーバーから新しいデータを取得した際に、その内容に基づいてページのHTMLを動的に書き換えることで、ページを再読み込みすることなく内容を更新することができます。 CSR (クライアントサイド レンダリング )とは? 概要 CSR は、 C :Client / クライアント = ブラウザ S :Side / サイド = 側 R :Rendering / レンダリング = 動的にHTMLを出力する の略で、 つまり、 「ブラウザ側で動的にHTMLを生成する」 手法を指します。 「楽楽鮮魚」が CSR を採用したら? 初期画面(在庫一覧画面)表示までの流れ 初期表示(在庫一覧画面表示)までの流れ / CSR ブラウザはWEBサーバーに、リク エス トをします WEBサーバーはブラウザに、在庫情報が 埋め込まれていないファイル をレスポンスします
 ブラウザは API サーバーに、在庫情報をリク エス トします
 API サーバーはブラウザに、在庫情報をレスポンスします ブラウザは、 レンダリング を行い(JSによってDOMが更新され)、在庫一覧画面が表示されます 詳細画面への遷移時の流れ 詳細画面への遷移時の流れ / CSR ブラウザは API サーバーに、詳細情報をリク エス トします
 API サーバーはブラウザに、詳細情報をレスポンスします ブラウザは、 レンダリング を行い、詳細画面が表示されます CSR のメリット ページ遷移が早い サーバーの負荷が軽い CSR のデメリット 初期表示が遅い(初期ロードで大量のJSを読み込むため)
 SEO 対策が難しい(ページの内容が JavaScript で後から表示されるため、 検索エンジン が内容を正しく認識できず、検索結果に反映されにくくなる) JSが⁨⁩無効だと正しく表示されない ページごとのOGP(Open Graph Protocol)設定ができない
 クライアントのスペックに依存する どのようなサービスに向いているか 部分的にコンテンツを、動的に更新するアプリ(map系など) チャットアプリや SNS など頻繁に投稿などが更新されるアプリ SSR (サーバーサイド レンダリング )とは? 概要 SSR は、 S :Server / サーバー = サーバー S :Side / サイド = 側 R :Rendering / レンダリング = 動的にHTMLを出力する の略で、 つまり、 「サーバー側で動的にHTMLを生成する」 手法を指します。 「楽楽鮮魚」が SSR を採用したら? 初期画面(在庫一覧画面)表示までの流れ 初期表示(在庫一覧画面表示)までの流れ / SSR ブラウザはWEBサーバーに、リク エス トします WEBサーバーは API サーバーに、在庫情報をリク エス トします API サーバーはWEBサーバーに、在庫情報をレスポンスします WEBサーバーは、 レンダリング を行います
 WEBサーバーはブラウザに、 レンダリング 済みのファイルをレスポンスします ブラウザは、 レンダリング しなくとも5の時点で在庫情報が埋め込まれているため、ブラウザでJSを動作させる前に在庫一覧画面が表示されます 詳細画面への遷移時の流れ 詳細画面への遷移時の流れ / SSR ブラウザはWEBサーバーに、リク エス トします WEBサーバーは API サーバーに、詳細情報をリク エス トします API サーバーはWEBサーバーに、詳細情報をレスポンスします WEBサーバーは、 レンダリング を行います
 WEBサーバーはブラウザに、 レンダリング 済みのファイルをレスポンスします ブラウザは、 レンダリング しなくとも5の時点で詳細情報が埋め込まれているため、ブラウザでJSを動作させる前に詳細画面が表示されます SSR のメリット SEO 対策に優れている(サーバーでページ内容が生成され、 検索エンジン が JavaScript を実行しなくてもコンテンツを容易に読み取ることができる) 初期表示が早い(既に レンダリング 済みなため)
 OGPを設定できる SSR のデメリット サーバー負荷が高い(リク エス トごとにサーバーで レンダリング 処理が必要なため) どのようなサービスに向いているか SEO 対策が重要なサービス(ECやニュースなど)
 初回表示速度が重要なサービス
 SSG (スタティックサイトジェネレーション)とは? 概要 SSGは、 S :Static / スタティック = 静的に S :Site / サイト = サイト G :Generation / ジェネレーション = (あらかじめ)HTMLを生成する の略で、 つまり、 「あらかじめ、完成された(静的な)HTMLを生成しておく」 手法を指します。 SSGには、 CSR や SSR のように「Rendering」ではなく、
「Generation」の文字が使われています。 SSGでは、ビルド時に レンダリング を行い、生成済みのHTMLをWebサーバー上に配置しておくことで、クライアントサイド・サーバーサイドどちらでも JavaScript による初期 レンダリング を行わなわない方式を指しています。 よって厳密には、 CSR や SSR のようにリク エス ト時にどちら側で レンダリング を行うかといった観点の レンダリング 方式を指している言葉ではありません。 「楽楽鮮魚」が SSG を採用したら? 初期画面(在庫一覧画面)表示までの流れ 初期表示(在庫一覧画面表示)までの流れ / SSG  0.【前提】 ビルド時に レンダリング を行います   *SSGでは、ビルド完了時にはすべてのページが静的なHTMLファイルとして生成され、   WEBサーバー上に配置されます。  1.ブラウザはWEBサーバーに、リク エス トします
  2.WEBサーバーはブラウザに、 レンダリング 済みのファイルをレスポンスします  3.ブラウザは レンダリング しなくとも2の時点で在庫情報が埋め込まれているため、    ブラウザでJSを動作させる前に在庫一覧画面が表示されます 詳細画面への遷移時の流れ 詳細画面への遷移時の流れ / SSG ブラウザはWEBサーバーに、リク エス トします WEBサーバーはブラウザに、 レンダリング 済みのファイルをレスポンスします ブラウザは、 レンダリング しなくとも2の時点で詳細情報が埋め込まれているため、ブラウザでJSを動作させる前に詳細画面が表示されます SSGのメリット サーバーの負荷が軽い(リク エス トごとにサーバーで レンダリング しないため) セキュリティが高い(動的な要素が無いため) SEO 対策に優れている(静的に生成されたページは、 検索エンジン が JavaScript を実行しなくてもコンテンツを容易に読み取ることができる) 初期表示が早い SSGのデメリット コンテンツの更新が難しい(デプロイ時にしかコンテンツを更新できないため) リアルタイムに更新できない
 ビルド& レンダリング に時間がかかる どのようなサービスに向いているか コンテンツ更新頻度の低いサービス(個人ブログ・ ポートフォリオ など) SEO 対策が重要なサービス ISR (インクリメンタルスタティックリジェネレーション)とは? 概要 ISRは、 I :Incremental / インクリメンタル = 増分的 S :Static / スタティック = 静的に R :Regeneration / リジェネレーション = 再生成 の略で、 つまり、 「静的に生成されたHTMLを、定期的に裏で再生成する」 手法を指します。 ISRは、 SSR とSSGの掛け合わせのような手法です。
 具体的には、初期リク エス トが来た時に レンダリング を行い、
その レンダリング 結果をサーバー側に有効期限付きのキャッシュとして一時的に保存をします。

 基本的にクライアントにはキャッシュを返すことで、サーバー側の負荷を下げます。
 有効期限後にリク エス トが来ると裏で再 レンダリング を行い、キャッシュを更新します。 「楽楽鮮魚」が ISR を採用したら? 初期画面(在庫一覧画面)表示までの流れ 初期表示(在庫一覧画面表示)までの流れ / ISR  1. ブラウザはWEBサーバーに、リク エス トします
  2. WEBサーバーは、 API サーバに在庫情報をリク エス トします  3. WEBサーバーは、 API サーバに在庫情報をレスポンスします  4. WEBサーバーは レンダリング を行います  5-1. WEBサーバーは、 レンダリング 結果を有効期限付きのキャッシュとして一時的に保存します
  5-2. WEBサーバーはブラウザに、 レンダリング 済みファイルをレスポンスします  6. ブラウザは レンダリング しなくとも5-2の時点で在庫情報が埋め込まれているため、   JSを動作させる前に在庫一覧画面が表示されます 初期リク エス ト後、複数回/ユーザからの在庫一覧画面へのアクセス時(キャッシュ有効期限内)の流れ 初期リク エス ト後、複数回/ユーザからの在庫一覧画面へのアクセス時(キャッシュ有効期限内)の流れ / ISR ブラウザはWEBサーバーに、リク エス トします WEBサーバーはブラウザに、キャッシュの レンダリング 済みファイルをレスポンスします ブラウザは レンダリング しなくとも2の時点で在庫情報が埋め込まれているため、JSを動作させる前に在庫一覧画面が表示されます キャッシュの有効期限後のリク エス ト時の流れ キャッシュの有効期限後のリク エス ト時の流れ / ISR  1.ブラウザ1はWEBサーバーに、リク エス トします(これまでのキャッシュの有効期限後、最初のリク エス ト)
  2.WEBサーバーはブラウザに、これまでのキャッシュの レンダリング 済みのファイルをレスポンスします  3.ブラウザ1は、 レンダリング しなくとも2の時点で在庫情報が埋め込まれているため、   JSを動作させる前に在庫一覧画面が表示されます

  2’.裏側でWEBサーバーは API サーバーに、新しい在庫情報をリク エス トします  3’. API サーバーはWEBサーバーに、新しい在庫情報をレスポンスします
  4.WEBサーバーは、 レンダリング を行います  5.WEBサーバーは、キャッシュを新しい レンダリング 結果に更新します
  6.ブラウザ2はWEBサーバーに、リク エス トします(これまでのキャッシュの有効期限後、2回目のリク エス ト)
  7.WEBサーバーは、更新したキャッシュの レンダリング 済みのファイルをレスポンスします  8.ブラウザは レンダリング しなくとも7の時点で(新しい)在庫情報が埋め込まれているため、   JSを動作させる前に(新しい)在庫一覧画面が表示されます 詳細画面への遷移時の流れ 詳細画面への遷移時の流れ / ISR  1.ブラウザはWEBサーバーに、リク エス トします
  2.WEBサーバーは、 API サーバーに詳細情報をリク エス トします  3.WEBサーバーは、 API サーバーに詳細情報をレスポンスします  4.WEBサーバーは レンダリング を行います  5-1.WEBサーバーは、 レンダリング 結果を有効期限付きのキャッシュとして一時的に保存します   *SSGとは違い、必要なページだけをアップデート(生成)することができることから   増分的(Incremental)という言葉が使われています。  5-2.WEBサーバーはブラウザに、 レンダリング 済みファイルをレスポンスします  6.ブラウザは レンダリング しなくとも5-2の時点で詳細情報が埋め込まれているため、   JSを動作させる前に詳細画面が表示されます ISRのメリット SSGの高速性を維持しつつ動的なコンテンツも扱える 指定された時間で自動的にページを再生成できる 必要なページだけを再生成するため、大規模サイトでも効率的に最新コンテンツを提供できる ISRのデメリット リアルタイム性の欠如 どのようなサービスに向いているか 大規模サイト(サイトに多数のページがある場合、SSGと比べビルド時間を大幅に短縮できる) リアルタイム性を必要としないサービス おわりに これらの レンダリング 手法は、一概に「この レンダリング 手法が優れている」と言えるものではありません。 サービスの特性や目的によって最適な手法は異なります。 例えば、リアルタイムでのデータ更新が必要なアプリケーションでは CSR が適していて、 SEO 対策や初期表示速度が重要なウェブサイトでは SSR やSSGが効果的です。 また、コンテンツの更新頻度が高くないが、定期的な最新情報を提供したい場合にはISRが有用であると言えると思います。 それぞれの手法の特徴やメリット・デメリットを理解し、プロジェクトの要件やユーザー体験を考慮して最適な選択をすることが重要です。 ISRの登場が2020年であるように、技術の進化に伴い新しい手法やツールも登場するので、継続的な学習と情報収集が欠かせないことに変わりはなさそうです。 この記事では、初学者の方へ向けて レンダリング 手法について解説してきました。 最後までご覧いただき、ありがとうございます。 参考 『フロントエンドの知識地図』出版のお知らせ - ICS MEDIA Rendering on the Web  |  Articles  |  web.dev Incremental Static Regeneration (ISR) Data Fetching: Incremental Static Regeneration (ISR) | Next.js CSR,SSR,SSG,ISRについて理解する SPA, SSR, SSGって結局なんなんだっけ? CSR、SSR、SSG、ISRの違いをわかりやすく解説 もう迷わないNext.jsのCSR/SSR/SSG/ISR Next.jsのCSR(SPA),SSR,SSG,ISRのまとめ&メリットデメリットについて - Wiz テックブログ レンダリング方式ごとの組み込み方法|microCMSドキュメント SSRってMPAやSPAと何が違うの!? - ecbeing labs(イーシービーイング・ラボ) EC構築のSEO対策におけるCSRとSSRの違いを徹底比較 SSR, CSR, SSG, ISG, ISRとは?それぞれの基本的な定義と特徴を解説 | 株式会社一創 CSR/SSR/SG/ISRについてまとめ│てりーのフロントエンドBLOG CSRとSSRとSSGの違い #Next.js - Qiita フロントエンド理解必須のCSR、SSR、SSG #初学者向け - Qiita 【初心者向け】クライアントサイドのメリット・デメリットや、サーバーサイドとの違いなどわかりやすく紹介! KURO DIGITAL LOG
アバター
はじめに こんにちは。SREの gumamon です! NewRelic、Datadog、モダンな監視ツール(オブザーバビリティ)って良いですよね。弊社も Kubernetes ( k8s )等を利用した環境が増えてきた折、そろそろ必要になってきたのですが、NewRelic、Datadog等の クラウド サービスは ランニングコスト が高くなりがちです。 では内製できないかやってみよう!・・・というようなことを昨年度から取り組んでいたのですが、やっとこさ形になりましたので改めてブログで紹介させて頂こうと思います。 今回ご紹介するのは、大まかなシステムの構成と設計時の観点です。各 コンポーネント の詳細や工夫できた点などについては、改めて別の記事でご紹介できればと思います。 また、「オブザーバビリティとは?」や「試行錯誤の過程」については、以前執筆した以下のブログをご参照ください。 tech-blog.rakus.co.jp 目次 はじめに 目次 全体構成 設計観点:ユーザーの認知負荷を低く保つ ユーザーインターフェイスはGrafanaに統一 プリセットのダッシュボードとアラート 設計観点:変更容易性を高く保つ テレメトリの種別ごとにパイプラインを水平分割する 目的別(テレメトリ収集・集約)にIngressを挟んで垂直分割する まとめ 全体構成 さっそくですが、今回構築した環境の全体像は以下のとおりです。 ※ k8s 上にデプロイしています Architecture 今回の設計では下記を重視しています。 ユーザーの認知負荷を低く保つこと 変更容易性が高いこと それぞれのポイントについて、設計観点を記載します。 設計観点:ユーザーの認知負荷を低く保つ ユーザーインターフェイス はGrafanaに統一 何かを確認したいときに、あちこち情報を探すのは面倒です。このため、テレメトリを見たい=Grafanaを見れば良い、という導線になるように インターフェイス を統一しました。今回の構成では複数のサービスが連携してオブザーバビリティを提供していますが、ユーザーが見るのはGrafana(とSlack)のみです。 User Interface この統一が実現できたのは、Grafanaの設計理念のおかげです(私はこの考え方がとても気に入り、Grafanaを中心に アーキテクチャ を構築しました)。 Grafanaの設計理念は Big Tent Philosophy と呼ばれています。 「データがどこにあってもアクセスでき、観測可能性戦略に最適なツールを選択できるべきだ」という考えが根底にあり、Grafanaは プラグイン ベースの アーキテクチャ を採用しています。 その結果、多くのデータソースに対応する プラグイン がコミュニティや企業で開発されており、Grafana上でほぼ何でも可視化できるという状況が生まれました。 Prometheus , Loki , OpenTelemetory , Cloudwatch , Datadog , PostgreSQL ... etc プリセットの ダッシュ ボードとアラート サービスの増減に伴うGrafanaのメンテナンスも面倒です。そのため、SREがプリセットの ダッシュ ボードやアラートを管理・提供し、ユーザーが自身で作りこむ必要がないようにしました。 ただし、これはGrafanaの優秀さだけではなく、オブザーバビリティを提供する対象が k8s 上のサービスだったことも幸いしています。 k8s はコア コンポーネント がPodやService、PersistentVolume等のメタ情報を持っているので、多くのメトリクスを容易に収集することができます(ログも決まったところに決まった形式で出力されてきます)。これらを先に述べた ダッシュ ボードやアラートに紐づけることで、SRE側も無理なく k8s 環境全体のオブザーバビリティを提供できています。 Dashboards Dashboards AlertRules AlertRules 設計観点:変更容易性を高く保つ 今回の構成では アーキテクチャ 選定に悩みました。PoCや ステークホルダー との議論で「とりあえずこれでよさそう」となりましたが、より良い選択肢が後から見つかる可能性も十分にあるため、将来的に「やっぱり変えます」が容易にできる構成にしたいと考えました。各 コンポーネント が 疎結合 になるよう、以下の軸で整理しています テレメトリの種別ごとにパイプラインを水平分割する Metrics, Logs, Traces は、それぞれ異なる性質を持つテレメトリです。 取得目的が違う 取得方法が違う 通信規格が違う 負荷のかかるタイミングが違う そのため、各テレメトリを独立させ、シンプルに扱える構成としました。初歩的な実装ならばオールインワンのエージェントを導入する方が楽ですが、運用の柔軟性を高めるのであれば、Prometheusなどの草分け的な OSS をテレメトリごとにそのまま使う方が最終的には楽だと判断しました。また、異なる種類のメトリクスを同一サービスに集約しないことにもこだわりました。これにより、どれか一つを別のサービスに置き換えたい場合の移行がスムーズに行えます。 Horizontal Split PrometheusはPull型の アーキテクチャ ですが、別のPrometheus Serverへメトリクスをリレーする RemoteWrite 機能を持っています。PrometheusとVictoriaMetrics間の通信は、この RemoteWrite を用いて実現しています。 目的別(テレメトリ収集・集約)に Ingress を挟んで垂直分割する 今回の主な監視対象は k8s 上のサービスです。 k8s はClusterやNodeが増減するため、データ収集を行うエージェント(Edge)と、データ集約を行う中央集権的なサービス(Central)は多対一の関係になります。このため、中央集権的なサービスの前に Ingress を配置し、エージェントは Ingress のエンドポイントにテレメトリデータをPushする構成にしました。 Vertical Split Edgesは必ずしも k8s である必要はありません。(ある程度手作業にはなりますが)通常の Linux 環境などからも、エージェントを配置することで情報を集約可能です。 まとめ 今回は Grafana Stack x OpenTelemetryを使ったオブザーバビリティ構成についてご紹介させていただきました! 同じようなチャレンジをされている方の一助となれていましたら幸いです。 なお、今後の展望としては・・・ フロントエンド監視やプロファイル監視を追加したい SLI・SLOをいい感じに設計して行きたい Traceについてはまだまだ改良をしていきたい(SLI・SLOとも深く関連してくる) 以上、最後までお読み頂きありがとうございました!
アバター
背景 経費精算システム「楽楽精算」は2009年にリリースされ、15年以上にわたり運用されてきました。 その間、基本的なシステム設計はリリース当初のまま維持されています。 しかし、年月が経つにつれ、技術トレンドやビジネス的な要求は大きく変化しましたが、現状のシステムではそれらの変化に柔軟に対応することが困難になってきています。 システムの柔軟性は低く、機能追加のたびに既存機能への影響を広範に調査する必要があり、既存の処理フローを変えることができないため、イレギュラーなテクニックが必要となることも多く、追加開発のたびに多くの手間とコストがかかるようになってきました。 すべての問題が現行システムに起因するわけではありませんが、特定の ミドルウェア に強く依存した構造を持っているため、将来的な技術革新や新しい ミドルウェア への移行が困難であるという課題も抱えていました。 このような背景から、 ミドルウェア に依存しない中立的な アーキテクチャ が必要であり、その実現のためにリ アーキテクチャ に近い大規模な リファクタリング が計画されました。 その際に最も懸念されたのは、 リファクタリング による動作不具合のリスクです。 現状では、すべての動作を保証する自動テストが存在しないため、このリスクを無視することはできませんでした。 加えて、仕様書は完全には整備されておらず、初期リリース時から積み重なった変更仕様が複雑に絡み合い、システム全体の動作を統一的に把握することが困難な状況にありました。 このような状況下で、 リファクタリング を成功させるためにはどのような対策が必要かが、プロジェクトの大きな課題となりました。 このプロジェクト「 リファクタリング に向けた自動インテグレーションの実装」は、こうした背景を踏まえ、動作を保証するためのインテグレーションプロセスを自動化し、 リファクタリング を安心して進められる環境を整備することを目指しました。 背景 使用した技術とツール 直面した課題 解決策と手順 結果 考察と今後の展望 最後に 使用した技術とツール プロジェクトで中心的な役割を果たしたのは、 AOP ( Aspect -Oriented Programming)、 JUnit 、そして DBUnit という3つの技術です。 リファクタリング を行う際に最も重要なのは、動作に変更がないことです。 そのためには、現行のシステムがどのように動作しているかを正確にトレースする必要がありました。 システムの動作は単純に言えば入力と出力です。 エンドユーザーの操作によってシステムに情報が入力され、その結果としてデータベースや画面に情報が出力されます。 操作時に呼び出されるエンドポイントへの入力と出力、そしてその前後でデータベースの状態がどのように変化しているかを記録する必要がありました。 しかし、これを手動で行うのは非常に手間のかかる作業です。 そこで、 AOP を用いてエンドポイント呼び出し前と呼び出し後の状態を自動的に取得する仕組みを構築しました。 これにより、通常の操作を行うだけでテストデータが自動的に蓄積されていく仕組みが出来上がりました。 次に、取得したデータを自動テストに活用するために、 JUnit と DBUnit を選定しました。 まず、取得したテストデータから事前のデータベースの状態を DBUnit でリストアします。 JUnit でテストデータの入力情報をエンドポイントに入力することで処理が行われ、データベースの変更と画面出力が行われます。 それらの結果を DBUnit と JUnit を用いて事後のテストデータと比較することで、動作を検証します。 JUnit は Java での 単体テスト の標準 フレームワーク であり、楽楽精算ではすでに ユニットテスト で使用していたため、その知見を活かせることが選定理由です。 DBUnit は、データベースの状態をテストケースごとに再現するためのツールであり、データベースを利用した システムテスト において非常に有効です。 この2つのツールを組み合わせることで、取得したデータを効果的にテストに利用し、 リファクタリング 後のシステムの安定性を保証することができました。 直面した課題 プロジェクトを進める中で、最も困難だったのは、現行のモジュール構成と リファクタリング 後のモジュール構成が互換性を持たない可能性が高かったことです。 このため、 単体テスト の範囲を限定することが難しく、ほぼすべてのケースをインテグレーションテストでカバーする必要がありました。 特に、仕様書が不完全であったことから、どの部分を優先的にテストすべきかを判断するのが非常に困難でした。 テストケースの作成とテストデータの取得にも多くの時間と労力を要しました。 テストケースの作成からテストデータの収集までを本プロジェクトのチームのみで行うのは現実的ではなく、大きな課題でした。 特に特殊なケースについては製品に対する深い知識が必要であったため、外部委託は難しい状況でした。 その際に頼りになったのがオフショアチームでした。 ラク スは ベトナム にも開発チームを有しており、10年以上にわたる開発経験があります。 楽楽精算の開発にも長く携わっているため、製品や仕様に精通しており、テストケースの作成からテストデータの収集までを一貫して行うことができました。 これにより、短期間で膨大な量のテストケースの作成とテストデータの収集を行い、プロジェクトを前進させることができました。 解決策と手順 このプロジェクトを成功させるために、いくつかの重要なステップを踏みました。 要件定義と技術選定 プロジェクトの初期段階で、すべての要件を詳細に分析し、それに基づいて最適な技術を選定しました。 AOP の導入により、システムの動作をトレースし、 JUnit と DBUnit を活用してそのデータを効率的にテストに利用することで、手作業の負担を大幅に軽減しました。 システム設計と開発 システムの設計段階では、 AOP を活用してエンドポイント呼び出し前後のデータを自動的にキャプチャする仕組みを構築しました。これにより、 リファクタリング 後のシステムが現行システムと同様に動作することを確実にしました。また、 JUnit と DBUnit を活用して自動テスト環境を整備し、開発中のモジュールが正しく動作するかを常に確認できる体制を構築しました。 テストとデプロイ テストの段階では、広範囲にわたるテストケースを作成し、手動で収集したデータを活用してすべてのケースをカバーすることを目指しました。特に、 リファクタリング 後の動作が現行と一致するかを検証するため、各テストケースでデータベースの状態が正確に再現されることを確認しました。 結果 プロジェクトの結果として、私たちは広範な自動テストを構築し、 リファクタリング による不具合のリスクを最小限に抑えることができました。 自動化されたテストが存在することで、システムの変更に伴うリスクを可視化し、迅速に対応することが可能となりました。 この結果、 リファクタリング の過程で発生する可能性のある多くの問題を事前に検出し、対応することができました。 実際の リファクタリング の際も、自動インテグレーションテストをTDDのように使用することで、着実に リファクタリング を進めることができました。 考察と今後の展望 このプロジェクトを通じて、自動テストの重要性と有効性をあらためて認識しました。 自動テストが存在することで、システムに対する信頼性が格段に向上し、 リファクタリング やシステム変更の際の不安を大幅に軽減することができます。 これは、システムの継続的な変化が求められる現代においては、不可欠な要素です。 一方で、自動テストのメンテナンスコストが予想以上に高くなることも判明しました。 今回の リファクタリング のために作成した自動テストは、今後も機能開発時の自動テスト(主に リグレッション テスト)として活用したいと考えていました。 しかし、現状の自動インテグレーションテストは基本的に入出力の完全一致を確認するものであるため、入力や出力に変更がある場合はテストデータを修正する必要があり、 その作業コストが当初の想定以上に大きくなっています。 今後は、自動インテグレーションテストの検証範囲を制限し、 ユニットテスト で担保できる部分はそちらで対応するなど、新たなテストプロセスの構築が求められます。 最後に このブログが、同様の課題に直面しているエンジニアにとって有益であることを願っています。
アバター
はじめに ラク スが開発する楽楽精算は、東京開発統括部の楽楽精算開発部が担っています。 楽楽精算の iPhone (Swift)& Android (Kotlin)対応のモバイル アプリ開発 を担当しているのが、モバイル開発課です。 本記事では、楽楽精算のモバイル アプリ開発 案件を担当しているモバイル開発課のマネージャーが厳選した 「モバイル開発を軸に、キャリアをステップアップするために役立つ書籍」をご紹介します。 それぞれの書籍に推薦コメントを記載していますので、是非ご参考になさってください。 はじめに モバイル開発でおすすめの書籍 Androidを支える技術<Ⅰ・Ⅱ> iOSアプリ設計パターン入門 Androidアプリ設計パターン入門 プロダクト開発・アジャイル開発でおすすめの書籍 プロダクトマネジメント ビルドトラップを避け顧客に価値を届ける プロダクト開発の罠:エンジニアの最大稼働率が生む遅延とその克服法 アジャイルな見積もりと計画づくり その他技術のおすすめ書籍 UNIXという考え方: その設計思想と哲学 SQLアンチパターン Webを支える技術 ― HTTP,URI,HTML,そしてREST おわりに モバイル開発でおすすめの書籍 Android を支える技術<Ⅰ・Ⅱ> LooperとHandlerによるイベント処理が Linux 上のイベント処理機構でどのように処理されるか、タッチイベントがどのように伝搬されて Android 上で処理されるのか、など Android システムの低レイヤーな部分に焦点を充てた良書です。 古い書籍だが Android の基本は変わっていないので押さえておくと普段の開発に役に立ちます。 iOS アプリ設計パターン入門 iOS アプリ開発 における設計パターンの基本から最新までを徹底解説した本です。 MVC 、MVVM、Redux、Clean Architectureなど、さまざまな設計パターンを包括的に扱い、設計の選定に迷っている開発者向けに、具体的な実例をもとにその歴史や選定基準を学べます。チーム内で共通認識を持ち、よりメンテナンス性の高い アプリ開発 を目指すための入門書となっています​。 Android アプリ設計パターン入門 Android アプリ開発 における設計手法を、初心者から上級者まで幅広く学べる書籍です。 MVC 、MVVM、MVPなど、主要な アーキテクチャパターン を基本から実際のプロジェクトに基づいた実例を用いて解説しています。DroidKaigiやメルカリなどの実際の アプリ開発 を参考にし、設計上の課題やその解決方法にフォーカスしています。また Android Architecture Componentsにも触れ、設計のベストプ ラク ティスを提供しています。 プロダクト開発・ アジャイル 開発でおすすめの書籍 プロダクトマネジメント  ビルドトラップを避け顧客に価値を届ける アウトカムを意識しないアウトプットを重視すると顧客のニーズではなくスケジュール優先やリリース回数などを重視する「ビルドトラップ」に陥ってしまいます。 ビルドトラップを避け、顧客の課題にフォーカスする プロダクトマネジメント の原則を解説した本です。 プロダクト開発の罠:エンジニアの最大 稼働率 が生む遅延とその克服法 プロダクト開発におけるリードタイム増大の原因と対策について、リソース効率とフロー効率という視点で書かれた本です。 リソース効率だけを追い求めるとタスクの受け渡しで待ち時間や切り替えコストが発生し、一生懸命稼働しているつもりでも結果的に全体のリードタイムは伸びてしまうというパラドクスが存在するが、これを解消するためにフロー効率を上げる事が大事、という事が書かれています。 アジャイル な見積もりと計画づくり ソフトウェア開発における見積もりの不確実性に焦点を当て、 アジャイル 手法を用いて効果的な計画を立てる方法を解説しています。不確実性コーンなどの概念を活用し、プロジェクトの進行に伴い見積もりの精度が向上する仕組みを紹介します。 アジャイル 開発における変化への柔軟な対応と、計画と見積もりのバランスを取るための実践的なアプローチを提供します。 その他技術のおすすめ書籍 UNIX という考え方: その設計思想と哲学 UNIX の歴史を紐ときながらなぜここまで UNIX 系のOSが普及したのか、その設計思想や哲学を学べます。 なぜ UNIX は初心者にやさしくないのかなど、 UNIX が何を重視し、何を犠牲にしてきたのかを解説しています。 UNIX の話とは言えコマンドの設計思想などは日々のプログラム開発の参考になります。 SQL アンチパターン RDB のテーブル設計でやりがちな アンチパターン を具体例を交えて解説しています。 DB設計はアプリケーションのパフォーマンスや設計に影響するのでとても大事です。 正規化できていないテーブルなどは被害が広がり易く負債解消のコストがとても高いのでしっかり理解して防ぐ必要があります。 Webを支える技術 ― HTTP, URI ,HTML,そしてREST HTTPメソッドや ステータスコード の役割と正しい使い方、ステートレス性などWeb本来の設計思想を学べます。 モバイル開発にとってもWebの技術は使われており、基礎をしっかり理解しているかどうかはとても重要となっております。 おわりに 今回は、モバイル開発を軸にキャリアをステップアップするために役立つ書籍とその理由を紹介させていただきました。 Android や iOS の基礎から設計パターン、 プロダクトマネジメント まで、幅広い知識が得られるラインナップです。 これらの書籍を通して、モバイル アプリ開発 における技術力を高めるだけでなく、プロダクト開発全体の視野を広げることができるのではないかと思います。 モバイル開発者として成長を続けたい方は、ぜひ一度手に取って、キャリアの指針として参考にしてみてください。
アバター
はじめに こんにちは。楽楽電子保存のバックエンド開発チーム兼オフショア開発のリーダーを務めています、small-chestnutです。 今回は、私が担当しているグローバル開発におけるチームビルディングの経験をシェアしたいと思います。 この記事では、弊社の子会社である ラク ス ベトナム (以下、RV)との協働を通じて経験したチームビルディングの遷移や、各年度ごとに取り組んだ施策、課題解決のプロセスを振り返ります。グローバル開発やチームビルディングに悩んでいる方々にとって、参考になれば幸いです。 はじめに サービス紹介 チーム紹介 2022年度:立ち上げ期(形成期) オフショアチームの立ち上げ 施策と課題 2023年度:RVの本格開発参入(混乱期) サービス成長とチーム体制の変化 成果と混乱 2024年度:RVの統一と安定期 チームの成熟と新たなステップ 今後の展望 まとめ:グローバル開発で築く強いチームビルディングの5つのポイント 1.基本的な認識合わせの明文化と資料化 2.タスクやドキュメントの形式化 3.同じ資料・チケット管理システムの使用 4. KPIの設定による品質改善 5.チーム開発を意識したソフトウェア設計の改善 さいごに サービス紹介 「楽楽電子保存」は、 電子帳簿保存法 に準拠した帳票保存サービスで、特に受取側企業向けに利用されています。紙の帳簿や書類をデジタル化し、CMでおなじみの「楽楽明細」と連携することで、効率的な管理が可能です。2022年1月にリリースされ、今年で3年目を迎えます。法改正の影響もあり、ユーザー数は着実に増加しており、現在は機能拡充のフェーズに入っています。 楽楽電子保存 チーム紹介 「楽楽電子保存」は、 PMF (プロダクトマーケットフィット)が見え始め、開発の規模も拡大している段階です。日本チームによる対応が一段落したタイミングで、RV主導での開発に移行しました。これは、楽楽電子保存が新規プロジェクトであり、他の10年以上運用している複雑なサービスに比べて、RV中心での開発が行いやすいという背景があります。 また、 ベトナム では日本よりもIT人材の採用しやすく、組織をスケールしやすいという利点もあります。 2022年度:立ち上げ期(形成期) オフショアチームの立ち上げ 2022年は、RVとの初期連携を強化した時期でした。RVは開発4名、テスター2名の体制で、日本チームは7名でサポート。ブリッジSE(以下BrSE)と共に作業依頼や連携を進めながら、RVを徐々に育成していく計画を立てました。 RVは「期日までに作り切る」という意識は強い一方で、 ソースコード の品質(可読性・保守性)を高める意識が弱いという課題があります。 2022年度 立上げ期体制 施策と課題 比較的簡単なタスクから徐々に難易度を上げていきましたが、RVと日本チームの間で品質に対する意識の違いがありました。また、日本側のレビュー観点やドキュメントの形式化が不十分だったため、RVの成果物に対するレビュー指摘が多くなりました。さらに、RVと日本チーム間のレビュー連携がうまく進まず、課題に直面しました。 加えて、既存コードの一部が ドメイン 駆動設計(DDD)の貧血モデルとなっており、品質維持が難しい場面もありました。 2023年度:RVの本格開発参入(混乱期) サービス成長とチーム体制の変化 2023年、RVは10名体制に拡大し、本格的な開発フェーズに入りました。一方、日本チームは他サービス対応の優先度が上がり、メンバーが4名に縮小。日本チームはRVの成果物レビューに多くの時間を割くことになり、リソースが逼迫する状況になりました。 2023年度 RV本格参入期体制 さらに、サービス利用が急増し、2023年9月時点で月160万リク エス トだったものが、2024年3月には1,400万リク エス トにまで急増。問い合わせ対応も日本チームが担っていたため、レビューや開発に加え、対応業務が増え、チーム全体に大きな負担がかかりました。 成果と混乱 RVが本格的に開発に参入する中、日本チームではレビュー作業に多くの時間が割かれることに不満が高まりました。特に、自分たちも開発に携わりたいというメンバーの声があり、レビュー作業が増える現状にフラストレーションが溜まっていました。レビューによって開発リソースが圧迫されていたことも問題でしたが、私自身がリーダーとして、日本チームとの認識共有や方針の説明が不足していたことも一因でした。 当初、RVの品質向上を優先し、その後に日本チームが再び実装に戻る方針を考えていましたが、この計画を十分に共有できず、不満が広がってしまいました。日本チームとRVの双方に対して、明確に計画やビジョンを共有するべきだったと感じています。 そこで、まず KPI(レビュー指摘数、開発量に対するレビュー時間など) を設定し、それを基にRVの品質を向上させる施策を進めました。また、日本チームが感じる課題がRV側では同じように捉えられていない場合もあり、 定量 的な情報を用いて認識のズレを埋める努力をしました。 さらに、RVでテスト仕様書やフォーマットの整備を進める一方、日本チームには新技術採用の見通しや関連実装の機会が増えることを共有し、チーム間の連携強化を図りました。結果として、改善の兆しが見え始めましたが、依然として課題は残っている状況でした。 2024年度:RVの統一と安定期 チームの成熟と新たなステップ 現在、RVは開発10名、テスター3名体制で、日本チームと共にほぼすべての機能実装を担当しています。レビューの連携も次第に改善され、日本と ベトナム 間での出張を通じて認識を合わせ、同じチケット管理システムを活用により、タスクの透明性を確保されてきました。言語の違いはあるものの、成果物の形式化やドキュメントベースでの進行管理が効果を発揮し始めています。 また、品質向上のため、KPIに基づいた改善活動を計画的に進めており、着実な成果が見られています。さらに、 ドメイン 設計の見直し(アグリゲイト デザインパターン の導入検討など)を進めており、RVの設計・実装を明確化することで、日本チームとRVが並行して開発を進めやすい環境の整備を検討しています。 今後の展望 今後、チーム トポロジー のプ ラク ティスを活用し、RVをストリームアラインドチーム、日本チームをイネイブリングチームとして役割を明確にしていきたいと考えています。 これにより、RVは機能実装を主導し、日本チームは技術支援や リファクタリング 、ソフトウェア改善に集中できる体制を構築します。両チームが効率的に連携し、モチベーションを高めながらプロジェクトを進めていく予定です。 今後のチーム認識 まとめ:グローバル開発で築く強いチームビルディングの5つのポイント 1.基本的な認識合わせの明文化と資料化 問題点や組織としてあるべき状態を文書化し、全員が共通の理解を持つ。 2.タスクやドキュメントの形式化 作業の流れや文書をフォーマット化し、属人化を防ぐ。 3.同じ資料・チケット管理システムの使用 言語が異なる場合でも、できる限り同じ資料を共有し、透明性と一貫性を確保。 4. KPIの設定による品質改善 定量 情報に基づいてチームの改善を進め、品質向上を目指す。 5.チーム開発を意識したソフトウェア設計の改善 良い設計手法を採用し、人員増加による効率向上を実現して ベトナム の豊富なIT人材を活かす。 さいごに 最後までお読みいただき、ありがとうございます! ラク ス ベトナム (RV)との協働を通じて経験したチームビルディングの遷移とそのポイントをご紹介しましたが、いかがでしたでしょうか。この記事を読んで「興味を持った」「もっと知りたい」と感じられた方は、ぜひ当社の採用サイトや主催イベントの情報をご覧ください!
アバター
はじめに ラク スでは、「PdM(プロダクトマネージャー)」をテーマにした対談イベントを積極的に開催しております。 本記事では、その目的や、各回の概要・内容、今後の開催テーマをご紹介します。 イベントでのリアルな取り組み紹介を通じて、各社の開発戦略やPdM組織の役割、さらにはプロダクトを通じた顧客課題解決への想いを知る一助になれば幸いです。 ※明日開催のイベント情報もあります!是非最後までご覧ください! はじめに 開催背景と目的 各回の内容 【PdM Meetup】プロダクトマネジメントの最適解とは?~BtoB SaaS 3社合同イベント 【ログラス×ラクス】PdM Meetup ~製品・組織フェーズによって異なるPdMの役割や考え方〜 【弁護士ドットコム × ラクス】PdM Meetup〜ビジョンを成功に導く効果的なPdM組織とは? 【日経 × ラクス】PdM Meetup〜 toC/toBの違いから学ぶプロダクトマネジメント実践 ARR300億超え! ラクスPMが語るPM組織と仕事【PM Career】 番外編:RakusTechConference2024での発表もご紹介 今後開催予定のイベント 9/18開催!【オープンロジ×ラクス】バーティカル/ホリゾンタルの違いから学ぶプロダクトマネジメントのアプローチ 最後に 開催背景と目的 「顧客志向」を大事にし続け、マルチプロダクトで成長を続けてきた ラク ス。 ラク スのPdM組織「製品管理課」は「ビジネス、エンジニアリングの架け橋となり、カスタマーサクセスに導く、売れる製品を実現する」をミッションとし、 顧客課題の解決につながる製品づくりのため積極的に活動中です。 本記事でご紹介するイベントの目的は、PdM組織の役割や取り組み、課題をリアルに知っていただくことです。 より具体的には、組織の目的や役割、製品解像度の上げ方や ステークホルダー との関わり方、マネジメントの方法、 PdMのあるべき人物像などを参加者の皆さんと一緒に考え、少しでもお伝えできればと考えています。 また、各社で プロダクトマネジメント を取り巻く組織のあり方は大きく異なります。 対談させていただくことで、それぞれのPdMの役割や考え方が浮き彫りになり、参加者皆が大きな学びを得られると考えています。 各回の内容 【PdM Meetup】 プロダクトマネジメント の最適解とは?~BtoB SaaS 3社合同イベント rakus.connpass.com <概要> BtoB SaaS サービスを展開する3社(Chatwork株式会社、株式会社LegalOn Technologies、株式会社 ラク ス)で、 プロダクトマネジメント のあり方について下記 トーク テーマでディスカッションしました。 PdMの責任と役割定義について PdMの責任と役割は、企業・製品・組織フェーズによって異なります。本セッションでは、PdMの責任と役割に焦点を当て、プロダクト開発を取り巻く ステークホルダー との連携方法やその苦労、今後の方向性について話し合います。 PdMによる顧客志向な組織作り PdMはどのようにお客様と向き合っているのか、そしてお客様の声や課題をどのようにプロダクト開発に活かし、またプロダクト開発組織をどう顧客志向に導いているのかについてディスカッションします。 PdM業務での仕組み化について 製品フェーズが進んでくると、1プロダクトで複数のPdMが関わります。そういった状  況下で、 プロダクトマネジメント の質を落とさずお客様に選ばれる製品づくりを継続的に遂行する必要があり、再現性は重要なキーワードとなります。PdM業務の中で「仕組み化」をキーワードにどういった取り組みをしているかについて議論をします。 <登壇者紹介> ・松下 三四郎 様 | Chatwork株式会社 コミュニケーションプラットフォーム本部 プロダクトマネジメント 部 Product Strategist 大阪府 出身、神奈川県 三浦郡 葉山町 在住。ソフトウェアエンジニアのバックグラウンドを持ちながら、 ディー・エヌ・エー 、スマートニュース、ヤフー、プレイドで、本部長、事業責任者などを務め、主に プロダクトマネジメント 領域を担当。 ToC 、 ToB 問わず、多くのプロダクトのグロース戦略に関わり、描き、成長に導く実績を持つ。2023年6月Chatworkにジョイン。趣味はDJ25年目。ヨーロッパツアー、大型フェス出演、書籍出版など。 ・泉 真悟様|株式会社LegalOn Technologies プロダクトマネジメント グループ マネージングディレクター 1999年4月株式会社 PFU に入社。文書管理、AI OCR 、 電子帳簿保存法 対応ソリューションをはじめとするドキュメント関連ソフトウェアの企画に従事。 株式会社Cogent Labsの マーケティング & プロダクトマネジメント のシニアプロダクトマネージャー、 執行役員 を経て、2023年4月に株式会社LegalOn Technologiesに入社。 現在、 プロダクトマネジメント グループにて、LegalForceキャビネのプロダクト マーケティング マネージャー等を担当。 ・稲垣 剛之|株式会社 ラク ス 楽楽精算開発部 PdMチーム マネージャー 大学卒業後、独立系 SIer 企業に入社。約10年間、WEB系 システム開発 ・運用のPG、SE、PMを経験。その後、ファッション ECサイト の立ち上げ直後から約9年間、開発責任者として参画。最終的には企画・デザイン・開発といったプロダクト開発全般の責任者を担当。 ラク スに入社後は楽楽精算のPdM及びプロダクトサポート、QAといった、開発の中でもプロダクトを全体視点で見る組織のマネージャーを経て、現在は プロダクトマネジメント 領域に特化した組織のマネージャー ※以降各回とも、当社からはPdM組織マネージャーが登壇しております。 <当社セッションのポイント(一部)> ・PdMはなぜやるのか、スコープ、ゴールに集中し、製品戦略上の優先度提示を行う ・顧客課題の解像度向上には、CSを通じたお客様の声の収集や、アンケート、 ヒアリ ングを実施。王道の方法をしっかりやることに注力。 ・CS・営業によるお客様の声の収集内容をフォーマット化し、解像度向上に努めている。 【ログラス× ラク ス】PdM Meetup ~製品・組織フェーズによって異なるPdMの役割や考え方〜 loglass-tech.connpass.com <概要> 製品や組織のフェーズが異なるBtoB SaaS サービスでは、製品やPdMを取り巻く組織の組み方はどう異なるのか下記 トーク テーマで対談しました。 ミッション達成に近づけるプロダクト開発とは 製品や組織フェーズによってPdMに求められるミッションも違います。ミッション達成のために求められる素養や考え方は何かをディスカッションします。 PdMの育成と採用の実例 PdMの育成と採用は会社ごとに異なります。各社が自社の状況を踏まえた上で重要視している考え方、捨てている考え方とともにその実例を紹介します。 <登壇者紹介> 斉藤 知明様|株式会社ログラス 執行役員 VPoP 東京大学 在学時にAI研究に従事、動画像を対象としたDeepLearningの研究でICME2016に論文が採択される。在学中に英単語アプリmikanを運営する株式会社mikanを協同創業しCTOに従事。その後Fringe81株式会社(現Unipos株式会社)に入社、ピアボーナスサービスUniposを立ち上げ子会社化、代表に就任。2023年5月、株式会社ログラスに入社。 執行役員 VPoPとして従事。「すべての挑戦が報われる社会に」を個人ミッションとする。 <当社セッションのポイント(一部)> ・「製品をグロースさせることで、企業の成長に貢献すること」への強い共感が大前提。 ・製品フェーズの変化に対応するための、思考力、行動力、変化への適応力が大事。 ・オンボーディングでは顧客理解、製品理解、 ステークホルダー との関係性理解に注力。 【弁護士ドットコム × ラク ス】PdM Meetup〜ビジョンを成功に導く効果的なPdM組織とは? rakus.connpass.com <概要> 効率的なPdM組織はどのようにあるべきか、下記の トーク テーマで対談しました。 PdMの責任と役割定義について PdMの責任と役割は、企業・製品・組織フェーズによって異なります。本セッションでは、PdMの責任と役割に焦点を当て、プロダクト開発を取り巻く ステークホルダー との連携方法やその苦労、今後の方向性について話し合います。 プロダクト 開発プロセス の工夫とこだわり 機能ごとにMVPとして何を作り、何を作らないか、開発効率を高めるためにどのような工夫や取り組みを行ってきたか、理想のプロセスとはどのようなものか、各社の取り組みを比較・紹介しつつ、ディスカッションします。 PdMの育成と採用の実例 PdMの育成は会社ごとに異なります。各社が自社の状況を踏まえた上で重要視している考え方、捨てている考え方とともにその実例を紹介します。 <登壇者紹介> 松井 聡様|弁護士ドットコム株式会社 クラウド サイン事業本部 プロダクトマネジメント グループ 大学院修了後、スタートアップ企業でイベント管理システムのプロジェクトマネージャーとしてキャリア開始。 マーケティング 系 SaaS のQAエンジニア、バックエンド開発エンジニアを経験後、プロダクトマネージャーとして製品企画を担当。 フィンテック 系企業のプロダクトマネージャーを経て、弁護士ドットコムに参画。 B2B 領域における プロダクトマネジメント と開発の広範囲な知識と経験が強み。 <当社セッションのポイント(一部)> ・PdM組織の発足経緯 ・プロダクト4階層で見るPdMとPMMの役割分担 ・ ディスカバリー に集中するための仕組み化と、迅速な情報共有に徹底的にこだわる 【日経 × ラク ス】PdM Meetup〜 toC / toB の違いから学ぶ プロダクトマネジメント 実践 rakus.connpass.com <概要> BtoCサービス『日経電子版』を展開する 日本経済新聞社 に登壇いただき、BtoBサービスの プロダクトマネジメント との違いや共通点を探りました。組織の位置づけや優先順位、KPIについて、下記 トーク テーマで対談を行いました。 ・PdMの開発組織での立ち位置や役割について PdMの立ち位置や役割は、開発組織の規模や構造によって異なります。本セッションでは、PdMがどのように開発チームと連携し、効果的なプロダクト開発を推進しているかを探ります。 具体的には、PdMが開発チーム内で果たすべき役割、コミュニケーション方法、また各組織における成功事例と課題についてディスカッションします。 ・プロダクト開発の優先順位やKPIについて プロダクト開発において、優先順位の設定とKPIの管理は重要な役割を果たします。本セッションでは、PdMがどのようにしてプロダクトの優先順位を決定し、KPIを設定・管理しているのかに焦点を当てます。 toB / toC サービス観点での違いにも注目です。 <登壇者> 鈴木 陽介様|株式会社 日本経済新聞社 デジタル編成ユニット Product Manager/Engineering Manager 大学卒業後、新卒で 日本経済新聞社 に入社。ウェブ向けの編集者、新聞記者などを経て、日経電子版の企画開発に従事。米国駐在を経て、2022年から日経電子版のProduct Managementを担当。 <当社セッションのポイント(一部)> ・PdMとPMMの役割分担 ・優先度決定のロジック ・ユーザー価値を測るノーススターメトリックの採用 ARR300億超え! ラク スPMが語るPM組織と仕事【PM Career】 pmclub.connpass.com <概要> 日本最大級のプロダクト開発コミュニティ PM Clubの「PM Career CrossTalk vol.7」に登壇させていただきました。 ラク スのプロダクト、PdM組織の概要や役割のほか、 ラク スのPdMならではの楽しさや難しさ、人物像についてもご紹介しました。 <登壇者> PdM組織マネージャーの稲垣のほか、楽楽精算PdMの紀井と、楽楽明細PdMの柴が登壇いたしました。 <当社セッションのポイント(一部)> ・ベストオブブリード型開発で、プロダクトの顧客課題に焦点を絞って解決できる組織構造 ・PdMは ディスカバリー の領域に集中。仕組み化にも注力 ・製品満足度指標にはノーススターメトリックを設定し運用。 番外編:RakusTechConference2024での発表もご紹介 当社PdM組織の活動内容を、当社主催のRakus TechConference2024で発表いたしました。 上記各イベントでのセッションの雰囲気も感じていただけるかと思いますので、是非ご覧ください。 speakerdeck.com 今後開催予定のイベント 9/18開催!【オープンロジ× ラク ス】 バーティカル / ホリゾン タルの違いから学ぶ プロダクトマネジメント のアプローチ rakus.connpass.com <概要> 「物流版 AWS 」をコンセプトに物流プラットフォームを展開する「オープンロジ」様に登壇いただきディスカッションを行います。 いわゆる バーティカル SaaS (業界/業種特化型)と ホリゾン タル SaaS (業種不問、汎用型)というターゲットの違いによって プロダクトマネジメント の在り方が大きく異なるのではないか、というテーマで開催いたします。 製品やお客様との向き合い方について ターゲットの異なる2社がどのように製品やお客様と向き合っているか?具体的にはユーザーとの接点・ ヒアリ ング・課題感の違いなどを軸にディスカッションします。 今どのような課題にチャレンジしているのか(今後求めるPdM像) 2社のPdMが現在どのような課題に取り組んでいるのかをざっくばらんに語り合います。本 トーク から2社が求めるPdM像も見えてくるのではないでしょうか。ターゲット・市場の違いによるPdMのあるべき姿なども注目です。 <登壇者> 高橋 祐哉様| 株式会社オープンロジ プロダクトマネージャー/UIUXデザイナー HR系プロダクトのPM/カスタマーサクセス/開発を経験し、DevOps組織のマネジメントを数年担当した後、業務アプリの ユーザビリティ をなんとかしたいとデザイナーに転身。現在はプロダクト戦略/UX/組織作りに注力してプロダクト開発を行っています。 開催は明日となります!ご都合のつく方は是非お越しください。 最後に 今後も各社様と共催形式で、プロダクトの成長を支える開発戦略や プロダクトマネジメント 、技術マネジメント領域の発信に取り組んでいきますので、是非ご参加ください! また、当社とイベントを共催頂ける会社様もご連絡お待ちしております!!是非 X でお気軽にメッセージ頂けますと幸いです。 https://x.com/DevRakus
アバター
はじめに 事前準備 トリガーを使用する方法 補足:トリガーと関数のみ消す方法 まとめ はじめに こんにちは! エンジニア2年目のTKDSです! PostgreSQL でのテーブル変更検知方法について調べました。 今回はトリガーを使用する方法について説明します。 事前準備 DBの準備(compose. yaml ) services : db : image : postgres:16.4-bullseye container_name : db environment : POSTGRES_USER : postgres POSTGRES_DB : postgres POSTGRES_PASSWORD : postgres ports : - "127.0.0.1:5432:5432" volumes : - db_data:/var/lib/postgresql/data - ./init.sql:/docker-entrypoint-initdb.d/init.sql healthcheck : test : [ "CMD-SHELL" , "pg_isready -U postgres -d postgres" ] interval : 30s timeout : 10s retries : 5 start_period : 10s volumes : db_data : 初期化 SQL (init. sql ) CREATE TABLE users ( id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, name TEXT NOT NULL , email TEXT NOT NULL , created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP ); INSERT INTO users (name, email) VALUES ( ' user1 ' , ' user1@example.com ' ), ( ' user2 ' , ' user2@example.com ' ), ( ' user3 ' , ' user3@example.com ' ); トリガーを使用する方法 PostgreSQL の機能であるトリガーを使用すると、特定のイベントが発生した時に指定した関数を実行することができます。 トリガーについての詳細は ドキュメント をみてください。 下記の例では、トリガーを使用して、テーブルの操作をしたときのログを記録します。 create_table. sql CREATE TABLE audit_log ( id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, operation TEXT, -- 操作の種類(INSERT、UPDATE、DELETE) old_data JSON, -- 変更前のデータ(UPDATEやDELETE時) new_data JSON, -- 変更後のデータ(INSERTやUPDATE時) query TEXT, -- 実行されたクエリ changed_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP -- 変更時刻 ); create_trigger. sql CREATE OR REPLACE FUNCTION log_table_changes() RETURNS TRIGGER AS $$ BEGIN IF TG_OP = ' INSERT ' THEN -- INSERT操作の新しいデータを記録 INSERT INTO audit_log (operation, new_data, query) VALUES ( ' INSERT ' , row_to_json(NEW), current_query()); ELSIF TG_OP = ' UPDATE ' THEN -- UPDATE操作の変更前と変更後のデータを記録 INSERT INTO audit_log (operation, old_data, new_data, query) VALUES ( ' UPDATE ' , row_to_json(OLD), row_to_json(NEW), current_query()); ELSIF TG_OP = ' DELETE ' THEN -- DELETE操作の削除されたデータを記録 INSERT INTO audit_log (operation, old_data, query) VALUES ( ' DELETE ' , row_to_json(OLD), current_query()); END IF ; RETURN NEW; END ; $$ LANGUAGE plpgsql; CREATE TRIGGER audit_trigger AFTER INSERT OR UPDATE OR DELETE ON users FOR EACH ROW EXECUTE FUNCTION log_table_changes(); まず CREATE OR REPLACE FUNCTION log_table_changes() に続く SQL でトリガー起動時に実行する関数を定義します。 TG_OP は実行された操作を表す特殊な変数です。 NEW はINSERT/UPDATE操作によって更新された行を保持する変数です。 OLD はUPDATE/DELETE操作によって更新される前の行を保持する変数です。 これらについては詳しくは トリガプロシージャ のページに載ってます。 current_query() は、現在実行中の SQL クエリを文字列として返す PostgreSQL の関数です。 詳細は システム情報関数 に載ってます。 この関数では操作を判別し、データを記録してます。 3つが分かれているのは、 OLD がUPDATE/DELETEしか対応しておらず、 NEW がINSERTとUPDATEしか対応してないのと、操作種別を固定値でいれるためです。 次にトリガー作成部分について説明します。 CREATE TRIGGER audit_trigger に続く部分です。 一行目でトリガー名、2行目で実行タイミングと対象操作、3行目でトリガーの起動単位(行)と実行される関数を指定してます。 下記に実行手順と結果を示します。 準備 # コンテナ起動 docker compose up # 記録用テーブル作成 cat ./sql/create_table.sql | docker exec -i db psql -U postgres -d postgres # トリガー作成 cat ./sql/create_trigger.sql | docker exec -i db psql -U postgres -d postgres 試す コンテナに接続 docker exec -it db psql -U postgres -d postgres 動作確認用 SQL を実行 postgres=# INSERT INTO users (name, email) VALUES ('auditlog1', 'aaa@example.com'); INSERT 0 1 postgres=# INSERT INTO users (name, email) VALUES ('auditlog2', 'sss@example.com'); INSERT 0 1 postgres=# SELECT * FROM users; id | name | email | created_at ----+-----------+-------------------+------------------------------- 1 | user1 | user1@example.com | 2024-09-10 14:34:03.56919+00 2 | user2 | user2@example.com | 2024-09-10 14:34:03.56919+00 3 | user3 | user3@example.com | 2024-09-10 14:34:03.56919+00 4 | auditlog1 | aaa@example.com | 2024-09-10 14:35:49.888486+00 5 | auditlog2 | sss@example.com | 2024-09-10 14:36:02.663281+00 (5 rows) postgres=# UPDATE users SET email = 'update@example.com' WHERE name = 'auditlog2'; UPDATE 1 postgres=# DELETE FROM users WHERE name = 'auditlog1'; DELETE 1 postgres=# SELECT * FROM users; id | name | email | created_at ----+-----------+--------------------+------------------------------- 1 | user1 | user1@example.com | 2024-09-10 14:34:03.56919+00 2 | user2 | user2@example.com | 2024-09-10 14:34:03.56919+00 3 | user3 | user3@example.com | 2024-09-10 14:34:03.56919+00 5 | auditlog2 | update@example.com | 2024-09-10 14:36:02.663281+00 (4 rows) postgres=# SELECT * FROM audit_log ORDER BY changed_at DESC; 結果は以下の通りです。 操作が記録されているのが確認できました。 補足:トリガーと関数のみ消す方法 以下のコマンドで消せます。 DROP TRIGGER IF EXISTS audit_trigger ON users; DROP FUNCTION IF EXISTS log_table_changes(); DROP TRIGGER IF EXISTS トリガー名 ON テーブル名; DROP FUNCTION IF EXISTS 関数名; 簡単に投入・削除ができるのでテスト時など記録がほしいときだけいれて、終わったら消すこともできますね、便利です。 まとめ 今回は PostgreSQL のデータ変更検知方法について調べました。 トリガーを使用する方法はDBへの負荷などデメリットもあるみたいですが、簡単で導入しやすそうです。 活用例として、テスト時にステートストアのレコードの内容が期待通りに遷移してるか確認する、ORMを通して実際に実行された SQL を記録するなどに使えそうです。 ログで検知する方法やWALを使用する方法もあるみたいなのでいずれ調べてみたいです。 ここまで読んでいただきありがとうございました!
アバター
はじめまして。私は楽楽精算の機能開発チームのマネージャーを務めている高波です。 今回のブログでは、楽楽精算の開発チームの組織構成、これまでの取り組み、そして今後の展望についてお話しします。 チームの紹介 開発組織構成 チームのミッション チーム体制と担当業務 取り組み事例 二重計上リスクを防ぐ機能開発 申請の差し戻し負荷を軽減する機能開発 今後の展望 業務効率を向上させるUI/UXの改善 利用者増に対応したパフォーマンスの向上 経費精算業務へのAI活用 チームの紹介 開発組織構成 楽楽精算の開発は、3つの課に分かれて行っています。 内部構造の刷新(技術負債の解消)とオフショア開発を担当する開発1課、機能開発を担当する開発2課、そしてモバイルアプリを担当するモバイル開発課です。 今回は、私が担当する開発2課について紹介します。 チームのミッション 顧客に求められる機能を開発・提供することで顧客の経費精算業務を楽にする 開発2課のミッションは、顧客の経費精算業務を「楽」にするため、最も効果的な解決策を製品機能として設計・開発し提供することです。 ラク スのミッション「ITサービスで企業の成長を継続的に支援します」を体現するために、私たちは楽楽精算を通じてお客様の業務を効率化し、企業の成長をサポートしています。 チーム体制と担当業務 現在、開発2課には課長の私を含め12名のエンジニアが所属しています。 チームはベテランから新卒まで多様なメンバーで構成され、3つのサブチームに分かれて開発を行っています。 主な業務内容は以下の通りです。 法制度や顧客業務の効率化に基づく機能開発 インシデント発生時のプログラム改修 経費精算業務におけるAI活用の機能検証 機能開発においては、まずPMMとPdMがお客様の課題を調査し、その中で最も高い価値を提供できるものを決定します。 この結果に基づいて開発リストとPRDが作成されます。 開発2課は、そのPRDをもとに具体的な機能要件やUX設計を行い、製造を担当します。 要求仕様からどれだけお客様にとって価値ある機能を提案できるかが、私たちの腕の見せ所です。 楽楽精算は2009年7月にサービスを開始し、今年で15年目を迎えます。 システムがカバーする業務は多岐にわたり、複雑です。 これらの機能を深く理解することが、顧客の課題に対して最適な解決策を提示するために不可欠です。 また、お客様の業務プロセスやシステムをどのように利用しているかを理解することで、真のニーズに応える価値ある機能を提供できると考えています。 このため、チーム内で製品機能や顧客業務に関する勉強会を開催したり、開発案件に取り組む際にPdM主催の要求に至った顧客課題の理解を深めるための説明会に参加したりと、技術力と顧客視点を強化する取り組みを行っています。 取り組み事例 楽楽精算は、 インボイス 制度や 電子帳簿保存法 対応に伴い、システムが法制度に対応することで 経理 部門の業務効率を高める機能を開発してきました。 現在は、より多くの顧客に選ばれ、選ばれ続けるための機能開発に注力しています。 最近の取り組み事例として、以下の2つを紹介します。 二重計上リスクを防ぐ機能開発 電子帳簿保存法 の普及に伴い、同一の領収書や請求書が二重に使用されるリスクが増加しました。 これにより、 経理 担当者の確認業務が増加するという課題が発生しています。 楽楽精算では、この課題を解決するため以下の機能を実装しました。 領収書や請求書の登録・申請・承認時に二重申請を防止する機能 承認済みの二重申請を検知する機能 これにより、申請者が誤って同じ領収書や請求書を登録してしまうケースを警告し、 経理 担当者の確認業務を軽減することができます。 申請の差し戻し負荷を軽減する機能開発 インボイス 制度の導入に伴い、事業者登録番号の管理が必要になりました。 しかし、システム利用者が制度を十分に理解していないため、未入力や誤入力が発生し、申請の差し戻しが増えるという課題が発生しています。 これを解決するため、楽楽精算では以下の機能を実装しました。 領収書や請求書の登録時に事業者登録番号が未入力の場合の警告機能 登録された事業者登録番号を承認者が修正する機能 この機能により、申請に不備があった場合の差し戻しを軽減し、経費精算の申請から承認完了までのリードタイムを短縮することが可能です。 今後の展望 楽楽精算は法制度に関する機能開発を経て、今後もお客様の課題を継続的に解決するために以下の取り組みを続けていきます。 業務効率を向上させるUI/UXの改善 経年による操作性の低下を改善し、操作手順を整理することで、より直感的に操作できるUI/UXを実現します。 これにより、経費精算業務を一層効率的に行えるようにします。 利用者増に対応したパフォーマンスの向上 社員数や組織規模、取引量・データ量が多いお客様にも安心してご利用いただけるよう、システムのパフォーマンスを向上させていきます。 経費精算業務へのAI活用 AIの普及に伴い、バックオフィス業務での活用への期待が高まっています。 楽楽精算では、AIを活用してお客様に価値を提供できる機能を開発・提供していきます。 これらを達成するために、開発組織のスケールと開発リードタイムの短縮を両立させる必要があります。 お客様に最も価値ある機能をタ イムリ ーに提供できるよう、エンジニア一人ひとりの成長と 開発プロセス の強化を目指していきます。 ◆ 関連記事のご紹介 career-recruit.rakus.co.jp career-recruit.rakus.co.jp career-recruit.rakus.co.jp
アバター
こんにちは! 技術広報課のyayawowoです。 今回は、 ラク スのPdMが所属している製品管理課が どのような目的と目標を持った組織なのか を詳しくご説明します。 2021年10月にPdM組織「製品管理課」を新設してから3年目となる今、 どのような役割でプロダクトの価値を上げているのでしょうか 。 PdM組織「製品管理課」を新設した背景と経緯 背景 「あるべき姿」に向けて 実際に実行した8つのこと 現在のミッション/ビジョン/組織の役割 新規PRJでのプロダクトへの貢献 AIの製品活用PRJ 楽楽シリーズブランド統一PRJ まとめ ラクスのPdM組織で働いてみませんか? PdM組織「製品管理課」を新設した背景と経緯 背景 2021年10月、東京開発部門の横断組織としてPdM組織「製品管理課」を新設しました。 まずは、製品管理課を新設した背景をご説明します。 【プロダクト開発体制:製品管理課の存続前】 製品管理課の新設前、上記の通り、ビジネスサイドに所属する「製品企画」という組織がPdMとPMMの両方の役割を担っていました。 まずは、このプロダクト体制での課題を理解することが必要です。 このようなプロダクトチーム体制の場合、プロダクト開発にてよく言われている課題は以下の通りです。 ラク スのPdMが経験を基にまとめました。 開発側の課題 こうして欲しいという要望(HOW指定)が多く、顧客の声や課題がぼんやりしている 開発する項目の優先度が属人的で納得感が十分に持てない システムが肥大化し品質維持のためにかかる 工数 が多く、新規機能開発に時間がかかる 品質が安定せず、バグの発生都度高く、その対応に追われ開発が計画的に進まない 問い合わせや仕様確認等が多く、開発に専念できない ビジネスサイド側の課題 開発側へしっかり要望が伝わらず、何度もやり取りや資料のやり直しが発生する 思った通りのタイミングでリリースができないことがある バグが発生して、その対応に追われている もっと多くの要望を実現して、色々試したいがそれが十分にできない では実際、社内の状況はどうでしょうか。 現状把握を行うため、製品管理課に所属するPdMが開発/ビジネスサイド側のキーマン数名に ヒアリ ングしました。 ヒアリ ング結果が以下になります。 ポジティブな意見 品質が高い、軽微なバグはあるものの致命的なものは皆無 開発プロセス がしっかりしているため、手戻りは少ない 各組織の目標や役割が明確である ネガティブな意見 事業部から開発へ課題や要求が上手く伝わらず、互いに効率が悪い部分がある 10年以上の運用しているシステムであり、開発規模も大きくなり 計画通りに進める難易度が年々あがっている 開発する項目の優先度を決める基準がややあいまいな部分がある ポジティブな意見としては、役割分担でしっかりと品質が高いプロダクト開発ができているという点が分かります。 一方、ネガティブな意見として前述したプロダクト開発にてよくある課題と同様の意見と、15年弱運用してきて一気に成長したプロダクトならではの課題が上がっています。 「あるべき姿」に向けて 現状把握後、 ヒアリ ング内容の課題が問題であるかをはっきりすべく、目標設定とあるべき姿を定義しました。 ◆ 何から決めたのか  1. Missionの設定  2. KGI・KPI/コンテキストの設定 まずは、Missionの設定とKGI・KPI/コンテキストを決めました。 但し、最初から確定するには難しいため、下記ポイントを注意・意識しながらも変化を前提としております。 ◆ 設定時に注意・意識したポイント  1.いずれも変化することを前提に設定  2.「KGI・KPI/コンテキスト」はいきなり理想の追及にはせずに段階を踏むようにした  3.初期の「KGI/コンテキスト」は以下を意識   ・プロダクト開発チームへ価値や貢献がもたらされ、半年以内で変化をさせられる   ・メンバーの現時点での強みが活かせるものにする メンバーの強みを活かして変化や貢献できることから、設定した形になっております。 ◆ 【目標設定】あるべき姿 では、製品管理課の新設時に設定した目標設定をご紹介します。 Mission ビジネス、エンジニアリングの架け橋となりカスタマーサクセスに導く、売れる製品を実現する KGI・KPI/コンテキスト 【ステップ1】開発組織への貢献 開発者がより開発に集中できる環境の提供 【ステップ2】ビジネスサイドへの貢献 PMMがより事業戦略やGTMに集中できる環境の提供 【ステップ3】顧客、プロダクトへの貢献 PdMがより直接的に製品へ貢献できるようにする 製品管理課の新設前は、上記のステップ1〜3を順次進めていくことで、開発組織内外から見てもどのようなステップで進めているかを明確にしておりました。 ラク スのPdMは開発組織に所属しているため、まずは開発組織への貢献を第一に置きました。 次に、ビジネスサイドとPMMがより事業戦略やGTMに集中できるような環境の提供、最後は、直接的に顧客製品への貢献ができるようなステップを踏みました。 実際に実行した8つのこと では、実際に新設時〜現在までに実行した「KGI・KPI/コンテキスト」の3ステップを細かくご紹介します。 前述にもある通り、まずは開発組織への貢献を第一に考えて実行しております。 【ステップ1】開発組織への貢献(1年目) まずは、開発組織への貢献とPMMが得意としていない業務の巻き取りです。 製品管理課の新設前は、PRD(Product Requirements Document)の作成をPMMが担当しておりました。 開発からの信頼獲得とPMMの苦手業務を移管するために、PRDの作成はPdMが作成することに変更し、PdMの観点でPRDを作成することにしました。 これにより、開発組織向けの資料となり、開発の要件定義以降のフェーズの効率化に繋がりました。 【ステップ2】ビジネスサイドへの貢献 (2年目) PdMのあるべき姿を踏まえ、PMMとPdMの役割分担も明確にしました。 実際にどういった開発案件をしていくかの決定フローを含め、PMMと相談をしながら決めていきました。 案件創出を担う役割をPMMからPdMに切り替え、PMMとPdMの業務の無駄を無くすことで効率化に繋げました。 【ステップ3】顧客、プロダクトへの貢献(3年目) PdMが一番重要としている、プロダクトに価値をより出していく部分になります。 当時の課題に対して打ち手は以下の通りです。 ①プロダクト開発計画の作成 問題 :年間でどのような開発を進めるのかが明確になっていない 打ち手 :「プロダクト開発計画の策定」を明確にすることで、開発の効率化を目指した ②PdMでの顧客解像度を向上 問題 :PdMの顧客解像度が低く、一次情報が取れていない 打ち手 :価値のあるプロダクト開発を目指し、「Discovery( ディスカバリー )」の領域をメインとした業務を遂行した ラク スの代表的プロダクトである 楽楽精算 は、ステップ3まで取り組むことができました。 今後は、他プロダクトにもこの取り組みを活用することで、より高いレベルでPdMができる可能性があるため、担当する対象のプロダクトを増やしていく方針です。 現在のミッション/ビジョン/組織の役割 では改めて、現在の製品管理課のミッション/ビジョンと組織の体制/役割をご説明します。 ■ミッション ビジネス、エンジニアリングの架け橋となり、カスタマーサクセスに導く、売れる製品を実現する ■ビジョン テク ノロ ジー ・UIで最高のUXを製品にもたらし続ける 【プロダクト開発体制:現在】 製品管理課のミッションは、課の立ち位置を踏まえた上でビジネス側にPMM、開発側にPdMがいることで 『ビジネス、エンジニアリングの架け橋となり』 、開発本部が掲げているミッション「顧客をカスタマーサクセスに導く圧倒的に使いやすい SaaS を創り提供する」の 『カスタマーサクセス』 と、PMMが所属する製品企画のミッション「ユーザーニーズを捉えた、売れる、選ばれ続ける製品を創る」の 『売れる製品を創る』 を踏まえた上で考えられました。 また、ビジョンの 『テク ノロ ジー ・UIで最高のUXを製品にもたらし続ける』 はユーザ体験を重視し、継続的に製品にもたらす状態にしておくという思いで掲げています。 続いて、「プロダクトの4階層」から見たときの製品管理課のPdMの役割を紹介します。 ■PdM組織の役割 緑:PMM(ビジネスサイド)が担っている役割 紫: PdM /PMMと合同で担っている役割 青: PdM が担っている役割 薄い青:開発/デザイナー 一般的にPdMの役割は「Discovery( ディスカバリー )」と「Delivery(デリバリー)」の領域があると言われていますが、 ラク スのPdMは、「Discovery( ディスカバリー )」のWhy、Whatに役割が集中しています。 製品管理課を立ち上げた際、開発側に属しているPdMが得意分野としているプロダクト、テク ノロ ジー 、顧客を紐づけた「Discovery( ディスカバリー )」を巻き取り、PdMの強みを活かしているためです。 これにより、ビジネスサイドにいるPMMは事業戦略やGTMに集中できる環境となり、開発側の生産性も上げることができました。 また「Delivery(デリバリー)」領域は、PdMとてはPMのような振る舞い等での役割は担っておらず、以下のような観点に対し、レビューアとしての役割を担っています。 顧客の要求を満たせているか プロダクトが顧客に価値を出せているか 等 このように、組織としての役割分担を明確にし、各フェーズでの専門性を高めることで、より効果的なプロダクト開発を可能としています。 ◆ 関連記事 career-recruit.rakus.co.jp 新規PRJでのプロダクトへの貢献 今後、製品管理課は新規PRJでプロダクトへの貢献に力を入れていきます。 今回は、代表的な2つについてご説明します。 AIの製品活用PRJ 製品管理課が携わっている楽楽精算はこれまでAIの活用をしていましたが、しっかりと発信やロードマップを示せていませんでした。 ◆ 楽楽精算のこれまでのAI活用 ・ 「楽楽精算」が最新のAI機能を活用した領収書読み取りアプリをリリース|「楽楽精算」 ・ 「楽楽精算」v10.5を提供開始。業務負荷が高い”紙請求書受け取り/処理の効率化”を支援し請求書の読取精度”99.9%”以上を実現|「楽楽精算」 楽楽精算は1.7万社以上のお客様に導入されており、お客様の苦労や成功体験が利用実績としてデータに蓄積されています。 今後、このデータをAI活用し、現在導入しているお客様のみならず、新たに導入されるお客様へも価値を提供できるように新しいプロジェクトにも力を入れていく予定です。 楽楽シリーズブランド統一PRJ 2つ目は、楽楽シリーズブランド統一に向けてのPRJです。 本PRJは、ブランド統一のためにUI/UXについてもシリーズ間で ガイドライン を一部揃え、複数導入したお客様に対して、それぞれの製品が最適なUXを提供できるようにすることを目的としています。 今後、こういった新規取り組みをプロジェクト化し、遂行していく予定です。 製品管理課の今後に乞うご期待ください! まとめ PdM組織「製品管理課」の紹介記事はいかがでしたでしょうか? 有難いことに ラク スのプロダクトは年々利用者が増え、会社規模も大きくなってきております。 製品管理課は、プロダクトの価値を上げるためにPdM組織としての目的/目標/役割を明確にし、顧客解像度上げることでプロダクト開発の生産性を上げているのをご理解いただけたのではないでしょうか。 また製品管理課のPdMは、弊社プロダクトの製品開発力や 組織力 の強みを社外に発信するべく、定期的に外部イベントに登壇しております。 直近では、「物流版 AWS 」をコンセプトに物流プラットフォームを展開する「オープンロジ」様と合同で、 プロダクトマネジメント の在り方についてディスカッションを行います。 オフラインイベントのため、イベントに参加するPdMやPdMを目指す方との交流ができますのでお気軽にご参加ください! 開発エンジニア、デザイナー、マーケターもお待ちしております! ◆ PdMイベントのご案内 お申込みはこちらから! rakus.connpass.com ラク スのPdM組織で働いてみませんか? AI・デザイン・ 経理 分野での ドメイン エキスパートついてはPdMの経験がなくても問題ございません。 しっかりとPdMの部分を支援や成長できるように努めてまいります! 少しでもご興味ある方がいらっしゃいましたら以下URLをご確認ください。 career-recruit.rakus.co.jp 製品管理課は、これらの取り組みに共感/情熱をもって一緒に働いてくれる方を募集しています! 最後までお読みいただき、ありがとうございました。 ◆ 関連記事のご案内 クライス&カンパニー様の Podcast で、PdM組織マネージャーの稲垣が及川 卓也様にインタビューいただきました! 顧客・事業貢献への思いや展望を語っております。是非ご覧ください! 「 ディスカバリー にとことん集中できる環境で、企業のバックオフィス業務を効率化するプロダクトを。」 www.kandc.com 開発本部のミッションに込めた想いをエンジニア/デザイナーが発信した、 「RAKUS Tech Conference 2024」のまとめ記事です!是非ご確認ください。 tech-blog.rakus.co.jp
アバター
はじめに はじめまして、楽楽精算のサポートエンジニアを担当している梅田です。 私たちのチームは、お客様がサービス利用におけるお困り事を解決できるよう、エンジニアの立場からサポートを行っています。 本記事では、生成AIを活用して問い合わせ対応業務を効率化し、回答までにかかる時間を75%削減した取り組み、具体的な活用方法や効果、AI活用のポイントをお伝えします。 はじめに サポートエンジニアの概要 サポートエンジニアの役割 サービスデスク 問題管理 リリース管理 サポートエンジニアの連携先 サポートエンジニアの課題 問い合わせ対応における問題 問い合わせ対応における課題 サポート業務改善に生成AIの導入 改善に生成AIを選定した理由 生成AIを使った問い合わせの効率化 計画 工夫 成果 更なる改善   サポートエンジニアの概要 サポートエンジニアの主な業務の1つはお客様からの問い合わせ対応です。 基本的には、お客様からの問い合わせはカスタマーサクセスで回答をしています。 ただし、技術的な内容などについてはカスタマーサクセスからエンジニアへ エス カレーションが上がってきます。 サポートエンジニアは、このカスタマーサクセスから上がってきたお客様からの問い合わせの エス カレーション対応を行っております。 サポートエンジニアの役割 サポートエンジニアが エス カレーション対応を通じて担当している役割は、 ITサービスマネジメント のベストプ ラク ティスである ITIL の フレームワーク に基づいて、以下の3つに分類できます。 サービスデスク サービスデスクの目的は、問い合わせや問題報告に迅速に対応し て、お客様に サービスを継続利用いただけるようにすることです。 ラク スの開発本部では顧客視点を重要視しています。 問い合わせ対応を迅速に対応することで、お客様が楽楽精算を利用して 経理 業務を円滑に実施いただけるようになるので、顧客視点の面からも重要な役割となります。 サポートエンジニアは、お客様からの問い合わせに対し、カスタマーサクセスから エス カレーションされた技術的な問題に対する初期調査を担当 しています 。 ソースコード レベルでの解析が必要な場面などでは開発チーム と連携し、早急に 対応して 、お客様がサービスを継続利用できるようサポート しています 。 問題管理 問題管理の目的は、 繰り返し発生するシステムの問題を特定し、その根本原因を解決することです。 サポートエンジニアは、 暫定対応が完了した問い合わせに対して、恒久対応の実施可否や対応時期について開発チームと連携し、対応を調整を行います。 恒久的な対応が適切なタイミングで実施され、お客様の問題が解決されることで システムが安定し、お客様が安心してサービスを利用できるようサポートしています。 リリース管理 リリース管理の目的は、 計画的かつ円滑な機能リリースを行うことにより、新規または変更されたサービスをお客様が問題なく利用できるようにすることです。 サポートエンジニアは、 リリースプロセス全体の調整や管理、特にリリースに向けた準備やテストの実施、リリース後のシステム動作確認を担当しています。 リリースが計画した通りに行われることで、お客様へ新しい機能や改善が円滑にリリースされ、お客様の業務がより効率的に進められるようサポートしています。 サポートエンジニアの連携先 「サポートエンジニアの役割」の中でも登場しておりますが、サポートエンジニアはお客様へ安心して利用できるサービスを提供し続けるために 下記をはじめとするチーム と連携して います。 サポートエンジニアの連携先 サポートエンジニアの課題 現状サポートエンジニアは少人数でカスタマーサクセスからの問い合わせに対応しており、迅速な回答ができていない時が発生していました。 問い合わせ対応における問題 楽楽精算の利用社数が増える中で、当初想定しきれなかったカスタマイズをしてご利用いただくケースも増えてきました。 カスタマーサクセスから エス カレーションされた内容について高度な調査が必要になる場面も増えてきて、以下のような 問題が出てきました。 迅速な対応の難しさ カスタマーサクセスからの問い合わせや緊急の問題報告に対して、問い合わせの内容によっては調査や暫定的な解決策の提供に時間がかかることがあります。 スパイク的な問い合わせ対応 スパイク的に問い合わせが重なる場合、サポートエンジニアの対応が追いつかなくなることがあります。 一貫した対応品質の維持 問い合わせ ごとに適切な対応を行うためには、過去の事例やナレッジベースを参照する必要がありますが、手動での検索や分析には限界があります。 問い合わせ対応における課題 問い合わせ対応 の 問題 を見直したところ、主に問い合わせ対応の調査で手動作業や解析に時間がかかっていることが 課題だとわかりました 。 サポート業務改善に生成AIの導入 これらの作業を効率化することで 課題 解決できると考え、生成AI導入を決めました。 改善に生成AIを選定した理由 前述のように課題解決のために生成AI導入を決めましたが、選定理由を正直に言えば、ChatGPTのような生成AIが持つ革新性に強く惹かれたからです。 ChatGPTに初めて触れた際、生成AIが質問に対して即座に的確な回答をするだけでなく、関連する知識や背景情報を自然な対話形式で提供してくれる点に非常に感銘を受け、単なる情報提供を超えた可能性を秘めていると感じました。 また、 エンジニアとして新しい技術に触れ、その可能性を試したいという思いがありました 。 加えて、 ラク スの行動指針であるリーダーシッ ププリン シプル「小さく試して大きく育てる」に基づき、まずは 問い合わせ対応 に適用し、成功すれば他の領域にも展開できると考えました。 生成AIを使った問い合わせの効率化 サポートエンジニアの業務に生成AIを導入することで、問い合わせの効率化を実現しました。 サポートエンジニアが問い合わせの効率化を計画し、どのような工夫で生成AIを活用し、成果を出すことが出来たのかを説明いたします。 計画 現状(図:GPTsを使う前の問い合わせ対応)の問い合わせ課題 を解決するためにChatGPTのGPTsを活用する計画を立てました。 GPTsは、 自然言語処理 ( NLP )技術を利用してユーザーからの問い合わせを解析し、適切な回答を生成する機能を持っているため、カスタマーサクセスからサポートエンジニアへの エス カレーション後に行う調査時間を短縮するのに最適であると判断したためです。 GPTsを使う前の問い合わせ対応 現状の問い合わせ対応における課題 迅速な対応の難しさ スパイク的な問い合わせ対応 一貫した対応品質の維持 工夫 計画に基づき、GPTsを活用したカスタマーサクセスからサポートエンジニアへの エス カレーション後に行う調査を自動化しました。 この調査の自動化を効果的に行うため以下のような工夫を実施しました。 複数視点の導入 回答精度を向上させるため、AIに複数の視点を持たせる手法を導入しました。AIが異なる観点から分析を行わせることが狙いです。実際にAIの中で議論を重ねることで、最適な回答を導き出すことができ、精度の高い回答が得られるようになりました。 GoogleDriveAPIによる学習 GPTsにはファイルをアップロードして、追加で知識を学習させる「knowledge」機能がありますが、この機能にはファイル数やファイルごとの容量に制限があります。ChatGPTを Google Drive と連携し、指定フォルダ内のドキュメントを参照させることで、楽楽精算の仕様やマニュアル、過去の問い合わせナレッジに基づいた回答が得られるようになりました。 GPTsへの学習を自動化 調査結果の精度を持続的に向上させるため、過去の問い合わせデータやナレッジベースを整理し、データのクロールと学習プロセスを自動化しました。これにより、 GPTs は継続的に新しい情報を学習し、検索精度と解析能力を向上させています。 成果 GPTs機能を活用することで、サポートエンジニアの問い合わせ対応業務の効率化(図:GPTs導入後の問い合わせ対応)が実現できました。 GPTs導入後の問い合わせ対応 迅速な対応と問い合わせ対応の効率化 関連する過去事例や情報を迅速に検索・参照できるようになり、とある対応では従来よりも調査にかかる対応時間が75%削減できました。 対応品質の向上と エス カレーション件数の削減 GPTsを活用することで、問い合わせ内容を複数の視点から解析できるようになり、ある種の問い合わせ対応においては一貫して高品質な対応が可能になり開発チームへの エス カレーション件数が50%削減できた結果、開発チームの負担も軽減できました。 スパイク的な問い合わせ対応の平準化 サポートエンジニアの調査時間の削減と開発チームへの エス カレーション件数が削減できたことで、スパイク的な問い合わせにも効果的に対応できるようになり、問い合わせ対応の滞りを減少させることができました。 更なる改善 サポート業務への生成AI導入は初期段階として上々の成果を上げました。 これですべての課題が解決できたわけではなく、まだ改善の余地が残っています。 今回は 問い合わせ 対応に GPTs機能 を使用しましたが、今後は他の業務にも GPTs を活用してさらなるお客様へのサービス品質向上を目指していきたいと考えています。
アバター
8/7(水)にRAKUS TechConference(以下TechCon)が開催され、盛況のうちに閉会しました。本記事ではその様子を、TechConを開催する目的や背景、当日発表資料なども交えながらご紹介します! TechConとは? TechConの開催目的 今年のテーマは「顧客志向」 ラクスの開発組織にとって「顧客志向」とは なぜ「顧客志向」をテーマに選んだのか? イベント概要 発表の紹介 「顧客志向」の開発組織 マルチプロダクトでのプロダクトマネージャーのリアル 拡大するマルチプロダクトSaaSの顧客理解にデザイン組織はどう取り組んでいるか 急成長する大規模プロダクト開発のマネジメント課題とアプローチ パフォーマンス向上とリソース管理のためのアプローチ 急成長するサービスを支えるためのインフラ戦略 楽楽精算のQA改革~楽楽精算でのQA専門組織の実践と成功事例 新たな顧客課題に挑む17年目の進化とモダナイゼーション クロージングトーク 終わりに TechConとは? TechConは、 ラク スの開発組織である開発本部が主催する、年に一度の大型イベントです。2022年に初開催し、今年で3回目を迎えました。 毎年、各チームがテーマに沿って取組みを発表する形式で開催しています。 TechConの開催目的 TechConは、当社のエンジニアやデザイナーが日々の業務を通じて得た独自の知見を発信することで、当社の開発組織やカルチャー、 開発プロセス 、利用技術について広く知っていただくことを目的としております。 また社内のエンジニアにとっても所属する組織の文化を改めて認識する機会とし、士気を高める場にしたいという目的もあります。 今年のテーマは「顧客志向」 今年のテーマとして掲げたのは、 「顧客志向」 です。 ラク スの開発組織にとって「顧客志向」とは 私たち開発本部は 「顧客をカスタマーサクセスに導く圧倒的に使いやすい SaaS を創り提供する」 というミッションを掲げています。 このミッションを実現するためには、何よりも「顧客志向」が欠かせません。 ラク ス開発本部にとっての「顧客志向」とは 顧客を深く理解し、本当に必要な機能を見極めた上で開発を行うこと、また顧客フィードバックを迅速かつ的確に製品に反映させることです。 開発本部が「顧客志向」を徹底することは 提供価値を追求し選ばれ続ける製品を提供することであり ひいては 「ITサービスで企業の成長を継続的に支援する」という全社のミッション実現にもつながると考えています。 なぜ「顧客志向」をテーマに選んだのか? 「顧客志向の SaaS 開発組織」であることは、2000年代初頭から顧客視点を重視して開発してきた当社の強みです。 しかし、組織が急成長する中で、メンバー一人一人の顧客に対する解像度が低下するという問題にも直面しており、「顧客志向」の維持・向上という課題にしっかりと向き合わなければなりません。そこで顧客志向の維持・向上という課題に各組織がどのよう取り組んでいるか、現場のリアルな事例を紹介し、顧客志向を持って開発する重要性を参加者の皆様と共有する場にしたいと考えて、このテーマを選びました。 イベント概要 日時 :2024/8/7(水) 14:00-18:00 会場 :オンライン 参加費:無料 主催 : 株式会社ラクス開発本部 X ハッシュタグ : #RAKUSTechCon techcon.rakus.co.jp 【イベントメッセージ】 ラク ス開発本部は「顧客をカスタマーサクセスに導く圧倒的に使いやすい SaaS を創り提供する」をミッションに掲げています。 私たちは、2000年代初期の SaaS 開発時から徹底して顧客視点を大切にし、顧客のペインポイントを理解し、その解決に向けて様々な取り組みを行ってきました。一方、組織が急拡大する中で、エンジニア一人ひとりの顧客に対する解像度が低下するという課題にも直面しました。 本カンファレンスでは、私たちが直面した困難とその乗り越え方、顧客視点を保つための具体的な取り組みを、CTOやPdM・EM・エンジニア・デザイナーが現場のリアルな声でお届けします。 顧客志向の開発を重視し、真のカスタマーサクセスを目指す皆様に、私たちの知見とインスピレーションを少しでも共有できればと思っています。 発表の紹介 ここからは各発表内容の紹介です! 「顧客志向」の開発組織 登壇:公手 真之 [ 執行役員 兼 開発本部長] speakerdeck.com 👉概要 ラク スの開発組織の進化を振り返りながら、「顧客志向の開発組織」となるために取り組んできたことをお話ししました。 初期の ベンチャー 組織から機能別組織、そして現在の 事業部制 へと移行する過程で、組織が大きくなるにつれて、顧客の声を取り入れる難しさが増してきます。 今後も「顧客志向の開発組織」であり続けるために、共通認識を強化するためのワークショップ実施や、各チームで顧客視点を強化するためのアクションを行い始めていることも紹介しました。 マルチプロダクトでのプロダクトマネージャーのリアル 登壇:稲垣 剛之 [製品管理課 課長] speakerdeck.com 👉概要 ラク スのPdM組織がどのようにお客様、製品、 ステークホルダー と向き合い価値を出しているのか、現場でのやりがい、苦労、難しさのリアルをお話ししました。下記のようなテーマで、 ラク スならではの特徴を紹介しました。 ・PdM組織の役割、発足と拡張の経緯 ・ ラク スにおけるPdMの役割分担、日々の プロダクトマネジメント 手法 ・マルチプロダクトならではのチャレンジと楽しさ ・今後の課題と展望 拡大するマルチプロダクト SaaS の顧客理解にデザイン組織はどう取り組んでいるか 登壇:小林 肇 [プロダクトデザイン課 課長]    今村 沙穂理 [プロダクトデザイン課] speakerdeck.com 👉概要 プロダクトデザイン課がマルチプロダクト SaaS の顧客理解にどのように取り組んでいるかをお話ししました。特に、顧客課題を解決するUI/UX設計のために、顧客理解と ドメイン 知識が重要であるということを、過去の失敗例や成功例を通じてご紹介しました。 さらに今後の課題として、顧客理解のさらなる深化と、それをチーム全体で共有することの重要性をお話ししました。 急成長する大規模プロダクト開発のマネジメント課題とアプローチ 登壇:高橋 康弘 [楽楽精算開発部 部長]    小宮山 和彦 [楽楽精算開発1課 課長]    涌井 友輔 [楽楽精算開発1課] speakerdeck.com 👉概要 楽楽精算開発チームが急拡大する中で発生した組織的課題、 開発プロセス 課題、技術的課題を紹介しました。 組織的課題としてはマネジメント負荷の増大、開発効率の低下が挙げられています。 これらの解決策として、役割の専門分化や技術負債の解消を目指したチーム構成の見直しが行われています。 開発プロセス 課題としては、サービス拡大により肥大化するコードに対する認知負荷が挙げられます。 分業化によりこの課題に対処しましたが、顧客視点の希薄化という新たな課題も生まれました。現在は顧客視点を強化するため、PdMとの連携や要求共有、顧客の声を直接聞く機会の提供や、仮説のモニタリングと検証に取り組んでいます。 技術的課題としては、技術的負債の解消が挙げられます。コードの リファクタリング やインフラの刷新に取り組むことで、生産性の向上と顧客価値の最大化を図る方針を紹介しました。 これらの取り組みを通じ、開発効率の向上と顧客ニーズに迅速に対応する体制の強化が期待されます。 パフォーマンス向上とリソース管理のためのアプローチ 登壇:牧野 寛知 [ ラク スライト クラウド 企画課]    上原 崇  [ ラク スライト クラウド 開発部] speakerdeck.com 👉概要 ブラストエンジンは、顧客のメールサーバ運用の課題から生まれた、 API 連携や SMTP リレーを通じて効率的なメール配信を可能にするツールです。 サービスを運営するうえでは、 API 処理の タイムアウト 、ユーザリソースの集中利用をはじめとする、パフォーマンスとユーザリソース管理の課題がありました。 これに対し、非同期 API 設計、レートリミットの採用、MongoDBの導入などの対策を実施しました。その結果、ユーザに安定したシステムを提供でき、利便性も向上できたことをご紹介しました。 急成長するサービスを支えるためのインフラ戦略 登壇:藤井 靖弘 [インフラ開発部副部長] speakerdeck.com 👉概要 ラク スでは急成長するサービスを支えるために、戦略的にオンプレミスを選択しています。 オンプレミスには、コストマネジメントと技術面の自由度を確保できるメリットがあります。セッションでは仮想化技術の導入によるラックコストの大幅な削減や、安定運用を実現するためのIOPS要件の最適化を紹介しました。 新技術導入によるコスト低減とレスポンス性能向上により、 顧客満足 を高める望ましいループを作っていく狙いをお話しました。 楽楽精算のQA改革~楽楽精算でのQA専門組織の実践と成功事例 登壇:金子 佳樹 [東京開発統括部 QA課] speakerdeck.com 👉概要 「楽楽精算」の品質保証(QA)専門組織の取り組みについて紹介しました。 楽楽精算のQA組織は、開発フェーズのテストだけでなく運用にも関わり、サービス全体の品質向上を目指しています。サービス利用社数の増加に伴い、開発とテスト・運用を並行して行うよりも、専門組織化するほうが効率的であるという背景があります。 顧客課題解決のためには、運用フェーズでしか得られないフィードバックも重要であり、それを開発に活かす フィードバックループ を確立する取り組みをお話ししました。 新たな顧客課題に挑む17年目の進化とモダナイゼーション 登壇:大塚 正道 [配配メール開発課 課長]    井上 良太 [配配メール開発課]    亀ノ上 孝雄 [フロントエンド開発1課] speakerdeck.com 👉概要 17年目を迎える「配配メール」は、従来のBtoB向けのメール配信サービスから マーケティング ・オートメーション機能を取り入れたサービスへ進化しました。より顧客に成果を実感していただくために、新たにリード獲得や商談獲得をサポートする機能が追加されました。 技術的には、従来の レガシーシステム のモダナイゼーションや、モダンなフロントエンド技術の導入に挑戦し、多くの一般ユーザーのアクセスに対応するためのフォーム機能やポップアップ機能を実現しました。これらの取り組みにより、サービスの進化と顧客価値の向上が図られています。 クロージング トーク 登壇:矢成 行雄 [大阪開発統括部 統括部長]    小林 肇 [プロダクトデザイン課 課長]    稲垣 剛之 [製品管理課 課長]    大塚 正道 [配配メール開発課 課長] speakerdeck.com TechConの締めくくりとして、エンジニア リングマ ネージャー、 プロダクトデザイナー 、プロダクトマネージャーによるクロージング トーク を行いました。 顧客志向を組織でどのように浸透させていくか ラク スならではの顧客志向の取り組み 生成AIが顧客体験や開発をどう変えるか など、最後まで熱い議論を交わしました! 終わりに 今回のTechConは開発本部のミッションに立ち返り、「顧客志向」をテーマに開催いたしました。昨年度より多くの方にご参加いただいたほか、参加アンケートからも取り組みに共感頂けたことが伺え、感謝いたします。 また社内からもポジティブなフィードバックが多く寄せられ、社内外共に意義深いものになったと振り返っております。 引き続き「顧客志向」重視の開発に取り組み、そこで得られた知見を次回のTechConでお届けしたいと思います! ◆ 関連記事 昨年度(2023年)の開催レポートは以下をご覧ください tech-blog.rakus.co.jp
アバター
概要 プロポーザル提出 採択から練習会まで 当日 感想 良かった登壇内容 概要 2024年8月22日~8月24日に開催された iOSDC Japan 2024 に、登壇者として参加しました。 本イベントは、日本の iOS やSwiftエンジニア向けの最大級のイベントの一つです。 このレポートでは、このイベントでの登壇経験についてご紹介します。 プロポーザル提出 iOSDCで登壇するためには、プロポーザルを提出し、主催側からの採択が必要です。 募集要項 にもあるように、 iOS やSwiftに限定せず、エンジニアにとって興味深いテーマであれば何でも構いません。 弊社でも有志で応募することとなり、私はこのようなイベントに応募した経験はなかったものの、挑戦することで経験を得られると考え、以下の3つのプロポーザルを作成しました。 なお、iOSDCでは初めて登壇する方向けに5分間のルーキーズLTという枠が設けられており、私のような初心者でも気軽に応募できました。 近距離撮影の新常識!iOSカメラアプリ開発におけるピンボケ対策の最前線 メモリ最適化を究める!iOSアプリ開発における5つの重要なポイント 実践!Flutter Add-to-app~既存アプリとの統合で見えたメリットと課題~ 採択から練習会まで 締め切りから約10日後、2番目の「メモリ最適化」に関するプロポーザルが採択されたというメールが届きました。 メールのタイトルに「採択」とあり、正直2度見してしまいました。 その後、メールに記載されていた必要事項の入力、チケットの購入(登壇者は無料です)、 トーク 可否の登録を行いました。 ※詳しい数字は公開できませんが、採択倍率はかなり高かったようです。 登壇資料を作成し、プレゼンの練習を進めていたところ、数日後に iOSDC Japan 2024 ルーキーズLT練習会 の案内メールが届きました。 ルーキーズLTの登壇者向けに本番の機材で練習ができ、経験者からのフィードバックを受けられるということで、少し不安もありましたが参加しました。 練習会には、私を含め5名の登壇者と主催の長谷川さん、スタッフ約10名が参加していました。 スタッフに見てもらえると思っていましたが、長谷川さんから直接プレゼンのフィードバックをいただけたのは非常に有益でした。 この経験のおかげで、本番でも不安を感じることなく登壇できました。大変感謝しています。 ※練習会は毎年開催されているようなので、ルーキーズLTに登壇する方には強くお勧めします。 ただし、カンペ無しで即座に登壇練習が始まるので、練習会の前に練習しておいたほうが良いです。 また、弊社のメンバーにも資料をレビューしていただき、大変感謝しています。 開催の一週間前からは1日2回、3日前からは1日3回程度プレゼンの練習を行いました。 当日 10:00頃に 西早稲田 の会場に到着し、受付を済ませると登壇者専用のネームプレートをいただきました。 私の登壇は17:55からだったので、17:00頃まで他のセッションを楽しむことができました。 ※特に印象に残ったセッションについては最後に紹介します。 当日の案内としては「受付を済ませて、登壇する時間になったら会場に来てください」といったものでした。 緊張しながら会場に向かうと、ペンライトが席に敷き詰められており、「これは何だろう?」と思っていたところ、スタッフの方に「ペンライトの色は何色が良いですか?」と聞かれました。 よく分からないまま「赤色」を選びました。(私はゲームなどでキャ ラク ターの目の色を赤にすることが多いので、ちなみにペンライトは登壇者応援用でした!) PCの接続チェック(外部映像出力の確認や、音声再生の確認)を行い、いよいよ登壇の時が来ました。 私も含めて8名のルーキーズLT登壇者が順番に登壇し、私の番が来たとき、会場はかなり暗く、観客の姿はほとんど見えない状態でした。 そのため、自分の話に集中できました。 練習では約4分50秒の内容でしたが、当日は4分30秒未満で終わってしまい、もう少しゆっくり話しても良かったと感じました。 登壇の様子 感想 iOSDCはコミュニケーションを重視しているイベントで、企業ブースではエンジニア同士の交流が活発に行われていました。 また、登壇内容も参加者が真剣に耳を傾けており、登壇者と直接話せる場も設けられており、エンジニアとして非常に楽しく刺激を受けることができました。 そんなイベントに登壇できたことを非常に嬉しく思いますし、大変良い経験となりました。 来年も登壇できるかはわかりませんが、ぜひ応募し参加したいと思います。 ※ただ弊社メンバーのご厚意で頂いた、たこ焼き引換券を使えなかったことだけが心残りです。 弊社メンバーがGETしたたこ焼き 良かった登壇内容 複雑さに立ち向かうためのソフトウェア開発入門 ソフトウェア開発全体における複雑さにどう対処するかについて、脳の認知リソースやワーキングメモリの観点から説明されていました。 タスクを細分化し、資料化して外に出す、チームメンバーに分散するなど、日常的に行っていることが脳の負荷分散に役立っていることがわかりやすく説明されていました。 また、登壇者のshizさんの話し方が講師のようで、とても聞きやすかったです。 月間4.5億回再生を超える大規模サービスTVer iOSアプリのリアーキテクチャ戦略 TVer が目指している アーキテクチャ の方向性についての説明でした。 長期間のリニューアルはリリースが遅れるリスクがあるため、モジュール分割とフィーチャーフラグを活用して段階的に公開する戦略が特に印象的でした。 審査が入るためリードタイムが発生するアプリのリリースにおいて、フィーチャーフラグで即リリースや ロールバック を制御する手法は非常に有用だと思いました。 快適な開発と高セキュリティを実現するCryptoKitを活用したCoreDataのデータ暗号化術 セキュリティを考慮したアプリ側で保持するデータの暗号化について、SQLCipherでのデータベース全体の暗号化や、CryptoKitでの個別データの暗号化など、実践的な手法が説明されました。 また、暗号化の際の 秘密鍵 の管理方法として、KeyChainを使って機種変更時に新しく生成するというアプローチが推奨されており、納得できる内容でした。 ◆ 関連ブログ 弊社から参加したメンバーのレポートは こちら! ぜひご覧ください。 tech-blog.rakus.co.jp
アバター
こんにちは。モバイル開発課の吉田です。 2024/8/22(木)~8/24(土)の3日間に渡り「 iOSDC Japan 2024 」(以下iOSDC)が開催されました。 そして今年度は弊社歴史上でも初のiOSDC登壇者として、当課メンバーが登壇しました! 応援も兼ねて当課メンバーもイベントに参加しました。 本ブログでは、当日の雰囲気やメンバーの印象に残ったセッションをお届けいたします。 iOSDCとは? 前夜祭 現地の様子 トークセッション メモリ最適化を究める!iOSアプリ開発における5つの重要なポイント 詳解UIWindow 座談会 「Strict ConcurrencyとSwift 6が開く新時代: 私たちはどう生きるか?」 ゼロから始めるiOSセキュリティ ~ OWASP Mobile Top10から学ぶ脆弱性対策 iOSアプリらしさを紐解く Kotlin MultiplatformでSaaS大規模アプリの生産性を向上させる技術的意思決定と導入効果を最大化するための取り組み さいごに iOSDCとは? iOSDCは iOS 関連技術をコアのテーマとしたソフトウェア技術者のためのカンファレンスです。 2016年の初開催から今年で9回目を迎えましたが、年々規模も大きくなり全国の iOS エンジニアからの注目度も非常に高いイベントとなっています。 当日コンテンツもメインとなる トーク セッションの他、ルーキーズLT大会、スポンサー企業ブースでのユニークな展示企画、交流を深める懇親会、果てにはネイルアートやフェイスペインティングなど初心者から熟練者問わず楽しめるコンテンツが準備されています。 今年度も引き続きオンライン( ニコニコ生放送 )+オフライン( 早稲田大学 西早稲田 キャンパス)でのハイブリッド開催でしたが、現地は今年の猛暑に負けないほどの熱気にあふれていました。 前夜祭 iOSDCの初日である8/22は、前夜祭としていくつかの トーク セッションが行われました。 その中でも今年の注目イベントは指示された動作をする Swiftコード をより短く書けた方が勝ち、という1対1の対戦コンテンツである「 Swiftコード バトル」! 予選から熱い戦いが繰り広げられ、前夜祭では決勝の優勝者決定までが配信されました。 内容はシンプルですが、ライブコーディング特有の難しさを感じられる臨場感がありました。 また、優劣が一目で分かるようにリアルタイムでバイト数が表示されたり、決勝では観覧者も急遽同じ問題に挑戦できるようシステムが整備されるなど、運営側の工夫も光り、非常に見ごたえがあり盛り上がりました。 現地の様子 翌日8/23からはいよいよ、朝からiOSDC本編の幕開けです! 当日も厳しい暑さでしたが、多くの方が足を運んでおり、お祭りのような賑わいを見せていました。 会場の様子と登壇ステージ スポンサー企業ブースでは iOS やSwiftにちなんだ趣向をこらした企画が催されており、和気あいあいと交流している姿が素敵でした。 企業ブース企画 また会場には色々なエリアに軽食やフリードリンクが提供され、キッチンカーも設営されるなど参加者への気遣いが感じられました。 改めて運営の方々がイベントを成功させるために毎年努力を重ねられているんだな、というのが伝わりました。 ドリンクと軽食サービス トーク セッション メインとなる トーク セッションは、会場4か所のブースでルーキーズLTも含めると合計91ともなる多種多様な トーク が行われました。 日頃オフラインイベントに参加する事は少ないのですが、やはり現地で直接聴講するとスピーカーの方や会場の熱量も分かりやすく、立て続けの移動で1日の終わりにはクタクタになりましたが、とても濃厚な時間を過ごすことができました。 ここからは、当課メンバーが特に印象に残った トーク セッションをご紹介させていただきます。 メモリ最適化を究める! iOS アプリ開発 における5つの重要なポイント fortee.jp speakerdeck.com 概要 当課メンバーの発表 昨今は機種性能向上により、ほとんど意識する機会が減ったアプリメモリ管理ですが、改めてそのテクニックを紹介 感想 そこまで意識しないでいいととはいえ、このようなハードに近い領域を前提知識として知っているかどうかでクオリティに差が出る事を再認識した セッション自体ではないが5分という枠の中で、終わりに近づくと サイリウム を振って合図するなど会場の一体感が伝わるようなルーキーズLTの雰囲気が楽しかった 登壇の様子 詳解UIWindow fortee.jp speakerdeck.com 概要 UIWindowについて、UIScreen、UIWindowScene、UIViewとの関係と各クラスの役割、またこれらのクラスが動作するときの細かい挙動を解説 感想 基礎的な内容だが、開発者として知っておいた方がいいセッションと感じた 開発で触れることのあるUIWindowと関連するクラスについて、どういった概念で作られたものなのかわかりやすい図とともに解説しているところが良かった 画面要素の表示順序が設定される仕様、全画面表示にしたとき特有の仕様など知っておいた方がいいことやSwiftUIからウィンドウサイズを取得する場合など学びの多いセッションだった 座談会 「Strict ConcurrencyとSwift 6が開く新時代: 私たちはどう生きるか?」 fortee.jp speakerdeck.com 概要 Swift 6におけるStrict Concurrencyの導入が、ソフトウェア開発にどのような影響を与えるかについて、座談会形式で議論 感想 Data raceとRace conditionの違いについて図で説明されていて分かり易かった Data IsorationについてIsoration Domainごとの具体的なコード事例など交えながら説明があり分かり易かった Concurrencyへの移行を始めるのにおすすめのレイヤーとData raceの原因ごとの具体的な手法について言及されており学びが多かった ゼロから始める iOS セキュリティ ~ OWASP Mobile Top10から学ぶ 脆弱性 対策 fortee.jp speakerdeck.com 概要 モバイル開発を行うにあたって、よく遭遇するセキュリティリスクを例に、その内容と対策を紹介 感想 モバイル アプリ開発 におけるセキュリティの重要性を改めて認識できた。特に、クライアント側の端末で動作するアプリにおいて、センシティブな情報(パスワードや個人情報など)の取り扱いには、細心の注意が求められることが強調されていた点が印象的だった アプリごとに作成された サンドボックス 領域へのアクセスも決して不可能ではないという点、リリースビルドであってもコード解析は可能であるという事実から、セキュリティ診断を行う際に Apple の仕組みに頼り切った判断は危険だと認識できた これらの点から、そもそもセンシティブなデータはアプリ側に置かない方が良いという結論に自然と至った。できるだけクライアント側ではなく、サーバー側でデータを管理し、必要に応じて最低限の情報のみを端末に保存するというアプローチが、より安全なのだと強く思った iOS アプリらしさを紐解く fortee.jp 概要 iOS アプリのデザインにおける「 iOS らしさ」とは何かというテーマについて、Human Interface Guidelinesや Apple 純正アプリ等から分析した結果について紹介 感想 デザインがユーザへ与える情報量は多く、適切なアニメーションやUIの採用がユーザー体験の向上に与える影響は大きいと感じた Apple における「直感的」というワードは切っても切れないもので、現実世界の挙動を模倣したデザインの採用もその役割を担っていると感じた ハーフモーダルを引っ張って項目を探すという動作は、引き出しから物を探す動作に似ているというように、現実世界の動作と照らし合わせてみることは「直感的」な使用感につながるデザインを選定するヒントになりそうだと感じた Kotlin Multiplatformで SaaS 大規模アプリの生産性を向上させる技術的意思決定と導入効果を最大化するための取り組み fortee.jp 概要 Kotlin Multiplatform(以降KMP)導入までの意思決定と導入する際の取り組みを紹介 感想 私自身が Android アプリエンジニアのためKMPを学習する際ハードルとして意識していなかった Android ではお馴染みのGradleなどのツールやライブラリやKotlin学習などを iOS エンジニアがしっかりキャッチアップできるような取り組みがなされているのが印象的だった 学習コスト以外では、 Objective-C 変換される点はSwift変換がロードマップ上にはあるそうなので、解消されることを期待 ここで紹介した以外にも、本当に興味が惹かれるセッションばかりで、技術的モチベーションの刺激にもなりました。 登壇メンバーも終わった後の解放感がすごかったと言っていたので、登壇者の方々は当日まで入念に準備を重ね、重責に耐えて挑まれたものと思います。 登壇者の皆様、本当にお疲れ様でした&ありがとうございました! さいごに 以上、3日間に渡る「iOSDC Japan 2024」の模様をお伝えしましたがいかがだったでしょうか。 iOSDC自体はこれまでも断片的には楽しませていただいていましたが、今年度はメンバーも登壇し初の現地参加ということでまた特別な体験でした。 リモートでは得られない現地の熱気や交流を通じて、チームとしてもお互いに更に理解を深めたり、 トーク セッションを受けて早くも創作意欲が湧き上がったりと有意義な経験を得る事ができました。 そして最後にはなりますが運営いただいたスタッフの皆様、登壇者の皆様、参加者の皆様、本当にお疲れ様でした。 チームでの集合写真
アバター
はじめに 復習:PGlite pg-gateway pg-gatewayとPGliteを起動してSQLクライアントから接続する まとめ はじめに こんにちは、エンジニア2年目のTKDSです! 前回 はPGliteの概要・使い方・速度実験について記事にしました。 今回はさらに、PGliteへの SQL クライアントからの接続を可能とするpg- gateway について紹介し、活用例について示します。 復習:PGlite PGliteは、 PostgreSQL をWebAssembly(WASM)に コンパイル した軽量なデータベースエンジンです。 これにより、ブラウザ、Node.js、Bun、DenoなどでPostgresの機能を利用でき、開発者はローカルやサーバーレス環境でデータベース操作を行うことが可能です。 PGliteは、インメモリデータベースや ファイルシステム (Node.jsやBun)、IndexedDB(ブラウザ)での永続化をサポートします。 pg- gateway TypeScript library that implements the Postgres wire protocol from the server-side. It provides APIs you can hook into to handle authentication requests, queries, and other client messages yourself. 翻訳:サーバーサイドでPostgresのワイヤー プロトコル を実装するTypeScriptライブラリです。このライブラリは、認証リク エス ト、クエリ、およびその他のクライアントメッセージを自分で処理するための API を提供します。 簡単にいうとこのライブラリは、データベースとやりとりするための仕組みをサーバー側で実現するものです。 これによって、簡単にPGliteへ外部のクライアントから接続できるようにしてくれます。 pg- gateway とPGliteを起動して SQL クライアントから接続する まずはpg- gateway を使えるようにします。 # クローンする git clone https://github.com/supabase-community/pg-gateway.git # ビルドの設定があるディレクトリに移動 cd pg-gateway/packages/pg-gateway/ # 必要な依存関係のインストール npm install # ビルド npm run build # PGlite+pg-gateway用のディレクトリを作る # 元いたディレクトリに戻る cd - # ディレクトリの作成 mkdir -p pglite-with-gateway/lib cd pglite-with-gateway/lib # ビルド成果物のコピー cp ../../pg-gateway/packages/pg-gateway/dist/index.js ./ cp ../../pg-gateway/packages/pg-gateway/dist/index.mjs ./ cp ../../pg-gateway/packages/pg-gateway/dist/index.d.ts ./ # プロジェクトルートで初期化 npm init 生成されたpackage. json の中身を以下のように書き換えてください。 { " name ": " pglite-with-gateway ", " version ": " 1.0.0 ", " description ": " A project integrating PGlite with pg-gateway ", " main ": " src/app.js ", " directories ": { " lib ": " lib " } , " scripts ": { " start ": " node src/app.js " } , " author ": "", " license ": "", " dependencies ": { " pg-gateway ": " file:./lib/index.js " , } , " type ": " module " } PGliteのインストール npm install @electric-sql/pglite # dotenvのインストール npm install dotenv # pg-protocolのインストール npm install pg-protocol 準備が整ったので、コードを準備して起動していきます。 pg-gatewayのREADME を参考にコードを書きます。 "use strict" ; import net from "node:net" ; import dotenv from "dotenv" ; import { PGlite } from "@electric-sql/pglite" ; import { PostgresConnection } from "../lib/index.mjs" ; // 環境変数読み込み dotenv . config () ; // PGliteのインスタンス作成 const pg = new PGlite () ; // 平文パスワードでの認証処理 async function validateUserCredentials ( credentials ) { const { user , password } = credentials ; const validUser = process . env . DB_USER ; const validPassword = process . env . DB_PASSWORD ; // ユーザー名とパスワードが一致するか確認 return user === validUser && password === validPassword ; } // クライアントメッセージの処理 async function handleClientMessage ( data , isAuthenticated , connection ) { if ( ! isAuthenticated ) { return false ; } try { const [[ _ , responseData ]] = await db . execProtocol ( data ) ; connection . sendData ( responseData ) ; } catch ( err ) { console . error ( "Error processing message:" , err ) ; connection . sendError ( err ) ; connection . sendReadyForQuery () ; } return true ; } // クライアント接続処理 function handleClientConnection ( socket ) { const connection = new PostgresConnection ( socket , { serverVersion : "16.3 (PGlite 0.2.0)" , authMode : "cleartextPassword" , // 平文パスワード認証 validateCredentials : validateUserCredentials , onStartup : async () => { await db . waitReady ; return false ; } , onMessage : ( data , { isAuthenticated }) => handleClientMessage ( data , isAuthenticated , connection ) , }) ; socket . on ( "end" , () => { console . log ( "Client disconnected" ) ; }) ; socket . on ( "error" , ( err ) => { console . error ( "Socket error:" , err ) ; }) ; } // サーバーの起動 function startServer () { const server = net . createServer ( handleClientConnection ) ; server . listen ( 5432 , () => { console . log ( "Server listening on port 5432" ) ; }) ; server . on ( "error" , ( err ) => { console . error ( "Server error:" , err ) ; }) ; } // サーバーを開始 startServer () ; pg-protocol関連でインポートできないエラーがでる場合があります。 エラーメッセージを確認し、node_modules内のファイルを書き換えてください。 作業が完了したら起動します。 npm start 別のターミナルを開いて接続します。 # psqlがない場合はインストールする sudo apt install -y postgresql-client # 接続 psql -h localhost -U postgres 以下のように繋がります。 これで、 SQL クライアントからPGliteにアクセスすることが可能になりました! まとめ pg- gateway を動かすまでについて解説しました。 情報が少なく、動かせるようになるまで苦労しました。 現時点で実用するには少し厳しいかなと感じました。これからに期待ですね! (実はpg- gateway を使ってGoからクエリ実行しようとしてできず、諦めました...。ログインができるのですがpg- gateway 側で送信されたクエリを実行できず?) ここまで読んでいただきありがとうございました!
アバター
はじめに 対象読者 TL;DR OpenAPI Specificationとは OASを導入することの何が嬉しい? 1. プロダクトごとにAPI仕様書を記述するツールやフォーマットがバラバラでスイッチングコストがかかる 2. 記述量が増えると動作が重くなる 3. API仕様変更の伝達漏れの多発 導入までの課題 1. OASの調査に時間をかけすぎた 2. OASのデメリット全てに対応策を講じようとしてしまったこと 導入して1年、開発環境は改善されたのか? おわりに はじめに ラク スフロントエンド開発2課の斉藤です。 ラク スの開発するプロダクトである楽楽明細、楽楽電子保存、楽楽請求では OpenAPI Specification (以下 OAS )を採用した開発を行っています。 今でこそ OAS を活用した開発を行うことができていますが、導入にあたっては様々な苦労がありました。 そこで今回は 何故 OAS を導入したのか 導入にあたってどのような課題があったのか 導入して実際に効果はあったのか を紹介したいと思います。 対象読者 OAS の導入を検討している人 OAS の導入に周りから賛同を得られない人 OAS 導入の効果が知りたい人 TL;DR 時間がない方に向けて結論から書きます。 従来の API 仕様書の閲覧パフォーマンスやコミュニケーションの齟齬による課題を解決したくて OAS を導入した。 導入にあたっては ステークホルダー の不安を ヒアリ ングし、ケアをすることで合意を得る事ができた。 OAS 導入後、開発者の満足度は高く、 工数 削減の効果があった。またAIと組み合わせる事で生産性がさらに向上する副次効果もあった。 OpenAPI Specificationとは OAS とはRESTful API を定義するための標準仕様であり、もともとはSwaggerと呼ばれていました。 *1 JSON または YAML 形式で記述され、 API のエンドポイント、HTTPメソッド、パラメータ、レスポンス、エラーハンドリング、などを定義することができます。 例えば以下は YAML 形式で記述された OAS の例です。 openapi : 3.0.2 servers : - url : /v3 info : description : |- This is a sample Pet Store Server based on the OpenAPI 3.0 specification. tags : - name : pet description : Everything about your Pets externalDocs : description : Find out more url : 'http://swagger.io' paths : /pet : post : tags : - pet summary : Add a new pet to the store description : Add a new pet to the store operationId : addPet responses : '200' : description : Successful operation content : application/json : schema : $ref : '#/components/schemas/Pet' '405' : description : Invalid input requestBody : description : Create a new pet in the store required : true content : application/json : schema : $ref : '#/components/schemas/Pet' これをSwagger UIのようなツールを用いて表示すると、以下のようにシンプルなUIで API 仕様を確認することができます。 公式がサンプルを用意 しているので、こちらを参照するとより具体的な使用イメージが掴めると思います。 OAS を導入することの何が嬉しい? OAS を導入する前、プロダクト開発チームは API 仕様書について以下の課題を抱えていました。 1. プロダクトごとに API 仕様書を記述するツールやフォーマットがバラバラでスイッチングコストがかかる 例えばあるプロダクトでは API 仕様書の記述に スプレッドシート 、他のプロダクトでは Google Docs 、といったようにそれぞれが異なるツールを用いていました。 記述のフォーマットも統一されておらず、複数のプロダクトを横断的に開発するチームにとっては記述ルールの学習コストが無視できないものになっていました。 2. 記述量が増えると動作が重くなる これは Google Docs を採用しているプロダクトで顕著だったのですが、 API のエンドポイントが増えるにつれ動作がカクカクしてしまい、閲覧するにも一苦労という状況が生まれていました。 これに対してはドキュメントを分割するなどの対策が取れますが、複数ファイルを参照しながら開発するのは良い体験とは言えませんでした。 API 仕様は何度も繰り返し参照するドキュメントなので、閲覧時のパフォーマンスは早急に改善したいポイントでした。 3. API 仕様変更の伝達漏れの多発 開発する中で API 仕様の変更はつきものです。(...ですよね?) 大きな変更は滅多にありませんが、軽微な変更、例えばプロパティ名をより適切な 命名 に変更したり、エラーパターンを追加したりといったことはあります。 そういった変更の共有漏れが頻発し、疎通テストで初めて発覚して慌てて修正するといった状況が多くありました。 コードの修正は開発工程の初期であるほど低コストで済みます。 修正が起きた都度、チーム内で変更が共有されている状況を作る方法を模索するも最適解が出ない状態でした。 これらの課題を全て解決したいと考えたとき、 OAS が選択肢として挙がりました。 OAS を用いると 仕様の記述フォーマットが規定されているため、チーム内で共通言語を用いた横断的な開発ができる Swagger UIのようなツールを用いれば多量の API 仕様を1つのHTMLで高いパフォーマンスで閲覧できる OAS からI/Fの型を自動生成することで型レベルで伝達漏れを防ぐことができる といったメリットがあり、自分たちの抱える課題を一挙に解決するできるのでは?という期待から、導入検討に進むことになりました。 導入までの課題 OAS を使えば課題解決できるヤッター導入しま〜す!あとよろしく、で通ったら苦労しません。 私たちはチームで仕事をしているので、 ステークホルダー と合意形成をする必要があります。 また、弊社が規定する ラクスリーダーシッププリンシプル という行動指針に 全体最適 視点を持つ というものがあります。 この指針に照らし合わせ、 OAS 導入が 全体最適 に寄与するという仮説をチームから納得してもらう必要がありました。 そこで各々のプロダクトを担当するバックエンドエンジニアと会議を行い、 OAS の概要と導入を検討していることを伝えました。 中にはぜひ導入したいというエンジニアもいれば、いきなり変えるのには不安がある、といった意見もありました。 さらに深掘って、導入にあたっての疑問点や不安に思っていることを ヒアリ ングすると以下の意見が挙がりました。 OAS 導入のメリットは理解できたが、開発フローがどのように変わるかイメージできない OAS 導入によって自分が行うタスクがどう変わるのかイメージしづらい OAS はフォーマットが規定されているため、学習コストが気になる そこで1, 2に関しては OAS 導入の前後で変わることをスライドを用いて説明することでイメージを掴んで頂きました。 また3に関しては勉強会を開催すること、 スプレッドシート で書かれた既存の API を OAS に書き換え、記入例を示すことで対応しました。 その甲斐あってか最終的には導入を提案した3つのプロダクト全てにおいて、合意を得ることができました。 合意形成がうまくいったポイントとしては 相手が不安に思っていることを ヒアリ ングし、その不安は杞憂である、もしくは対応策があることを根拠を持って答えることができた点 かと思っています。 と、さらっとスマートに事が運んだかのように書いていますが、 最終的に合意形成に至るまでに3ヶ月くらいかかっています。 理由としては OAS の調査に時間をかけすぎたこと OAS のデメリット全てに対応策を講じようとしてしまったこと が挙げられます。 1. OAS の調査に時間をかけすぎた OAS の調査にあたり公式ドキュメントを読み込んでいたのですが、覚えるべき事が膨大でOpenAPIを書けるようになるまでにはかなりの時間がかかるのでは?と考えるようになっていきました。 フロントエンドエンジニアだけで完結するならまだ良かったのですが、いずれはバックエンドチームにもOpenAPIを書いてもらうようにしたかったので、学習コストを理由に導入を断られてしまう不安がありました。 そこで Stoplight Studio や Apicurio Studio といった GUI でOpenAPIを記述できるようなサービスを使えば学習コストを抑えられそうと思い至り、さらにそちらの調査にも時間を割いてしまいました。 結論から書くと、現在これらのツールは使用していません。 OAS を導入した今言えることは、そもそもOpenAPIの学習コストは高く無いということです。 OpenAPIは様々な API 仕様記述のフォーマットを用意していますが、使用するのはその中の一部であり、公式が用意しているドキュメントを真似ればすぐに書けるようになります。 また弊社では Github Copilotを全社的に導入しており、Copilotは OAS の推論がとても得意なので、知識が浅いうちでも強力なサポートを得る事ができます。 したがって、学習コストを下げるために GUI ツールを導入するというのはコストと効果が見合っていないと判断しました。 実際、バックエンドに対して不安を ヒアリ ングしたときに学習コストの懸念は挙がったのですが、先述したようにちょっとした勉強会の開催と記入例の提示で納得していただけました。 ドキュメントを読んだ印象だけで学習コストが高いと決めつけ、あれもこれもと調査に時間を使ったのはもったいなかったです。 2. OAS のデメリット全てに対応策を講じようとしてしまったこと OAS を調査していく中で スプレッドシート や Google Docs にはできてOpenAPIにはできないことがいくつかある事がわかりました。 例えば スプレッドシート や Google Docs はドキュメント同士をリンクすることができたり、記述した内容に対するコメント等ができますが、OpenAPIではできません。 そこで、OpenAPIの description をうまく活用する事でどうにかデメリットを吸収できないかと思索していました。 結局今は description の記述ルールなどは特に設けずに運用しています。 ドキュメント同士のリンクなどはできれば便利ですが、必須な機能ではありません。 これを無理やり実現しようとして運用コストが高くなっては本末転倒です。 新しい手法を導入する事でメリットとデメリットの両方が生じるのは当然です。 生じるデメリットが本来解決したかった課題の大きな障害となるかどうかという視点で、対応の要否を最初から取捨選択しておくべきでした。 実際このようなデメリットが存在することを伝えつつ OAS 導入をチームに提案しましたが、すんなり受け入れてもらえました。 振り返ると、2つの失敗の共通点は 思い込み だったと思います。 学習コストが高いのではないか? デメリットに対する完璧な対応策を考えておくべきではないか? これらに対処しなければ合意をもらえないのではないか? このような思い込みを根拠にした意思決定が、多くの時間をかけてしまった原因だったように思います。 次に同じような課題に直面した際は ある程度調査したら実際に手を動かしてシミュレーションしてみる 早い段階でチームに相談しデメリットが許容できるものか認識を擦り合わせておく ことで思い込みによる無駄を避けるように行動していきたいと思います。 導入して1年、開発環境は改善されたのか? OAS を導入してから約1年経った現在(2024/08)は以下の流れで開発を行っています。 フロントエンドエンジニアがOpenAPIで API 要求仕様を記述しプルリク エス トを出す バックエンドエンジニアが API 要求仕様のレビューを行い、 API 仕様を確定させる OpenAPIから型やコードを自動生成する(フロントエンドは openapi-generator を使用) 生成した型をパッケージ化しプライベート レジストリ にpublish npm installで生成した型をインストールしI/Fを実装 フロントエンドもバックエンドもOpenAPIから自動生成した型やコードを使用しているので、疎通テストのバグが大幅に減少し 工数 削減となりました。 また自動生成した型と Github Copilotを組み合わせて、モックデータを推論できるという副次効果の恩恵にもあずかっています。 もちろん当初挙げていた課題も解決する事ができ、開発体験も改善されました。 さらに今回エンジニアに向けて OAS を導入して実際にどう感じているか、アンケートを取ってみたので結果を紹介したいと思います。 回答者の属性: OAS 導入後、OpenAPIを参照もしくは記述したことがあるエンジニア 有効回答数:9件 Q: OpenAPIを使った開発において、改善が必要だと感じた点や課題を教えてください。 A: 実装過程の後半でSwaggerの修正に少しハードルを感じていますので、FE/BE共に修正が必要なら早急に相談し、すぐ修正するコミュニケーションや雰囲気をお互いで作っていきたいと思っています。 Q: その他ご意見ご感想などあれば記述してください。 A: 導入当時、OpenAPIを導入したい経緯や課題は理解できたが、既存の 開発プロセス のどこで何をすればよいのかはよくわからなかった。今でも正しく理解できているか微妙。 全体的に高い満足度であり、少なくとも定性的には OAS 導入の効果はあったと言えそうです。 ただ、 OAS の導入プロセスについては不満と回答した方はいないものの、他の項目と比べると満足度が低めです。 自由記述の回答にもある通り、「 開発プロセス のどこで何をすればよいのかはよくわからなかった。」と意見を頂いており、スライドによる説明だけでは伝わりづらかった部分があったと考えられます。 小さくプロトタイプの リポジトリ を作って、 OAS 導入後の 開発プロセス のシミュレーションを行うなどすればより理解して貰いやすかったのかなと思います。 おわりに 本記事では OAS 導入に至った経緯から導入までの課題、その後の効果まで紹介しました。 導入までには数々の障害があり、至らない部分も多くありましたがなんとか開発フローに組み込む事ができました。 全体としては高い満足度となり、当初の課題も解決できたため導入してよかったと感じています。 今後さらなる 開発プロセス の改善に取り組む際には、今回の反省点を活かし、より効率的に、より多くの ステークホルダー に納得していただけるよう進めていきたいです。 *1 : 曖昧な情報です。おそらくOpenAPI2系まではSwagger, 3系からは OAS と呼ばれています。
アバター