TECH PLAY

電通総研

電通総研 の技術ブログ

822

こんにちは、X イノベーション 本部の 米久 保です。 こちらは、 電通 総研テックブログ アドベントカレンダー 2024の12月10日の記事です。 はじめに 認知負荷 認知負荷理論 ソフトウェア設計と認知負荷理論 認知バイアス エラー まとめ 参考文献リスト はじめに ITエンジニア同士で会話するときに、「メンタルモデル」や「認知負荷」などの 認知科学 に由来する用語をよく耳にするようになりました。ソフトウェア開発は結局のところ人間によって行われる社会的な営みなので、人間の心のクセ、つまり認知特性に注目することはその活動をより良いものにする上で重要です。 デザインの領域では人間中心デザイン(Human-centered design, HCD)に代表されるように、人間の認知特性を考慮に入れたアプローチが主流となっており、ユーザーのニーズ、能力、行動に合わせたデザインを行います。 ソフトウェアの品質は外部品質と内部品質とに分かれます。外部品質は性能や使い勝手のようにユーザーが利用時に認識できるもので、内部品質は保守のしやすさのようにユーザーには見えないものです。実行時の実体としてのソフトウェアは、UIを通してその存在を知覚します。ソフトウェアの利用者に対して提供するUIとUXは、デザイナーが中心となりユーザーのニーズを満たすようにデザインします。 さて、ソフトウェアの物理的な実体である ソースコード のユーザーは誰でしょうか。それを書いたり読んだり変更したりする開発者ですね。 内部品質はソフトウェアが素早くかつ持続的に価値を提供するために非常に重要 ですが、 ソースコード を日々取り扱うユーザーである開発者に焦点を当てて考える必要があるでしょう。 そのためには人間の認知特性を理解した上で、ソフトウェア 開発プロセス や個々のアクティビティをデザインする必要があります。この記事では、「認知負荷」「 認知バイアス 」「エラー」を題材に、ソフトウェア開発活動の中でも特に設計にどう活用できるかを考察します。 認知負荷 認知負荷理論 認知負荷理論は、オーストラリアの 教育心理学 者、ジョン・スウェラー氏によって1980年代に提供されたものです。脳内の情報処理を行う作業場所、ワーキングメモリに対してかかる負荷のことを認知負荷と呼びます。ワーキングメモリの容量は大きくないため、認知負荷が高すぎるとオーバーフローを引き起こしてしまいます。ワーキングメモリをいかに効率に使うかが重要です。 認知負荷理論において、認知負荷は3つに分類されます(参考文献1,2)。 分類 説明 課題内在性負荷 対象そのものが本質的に持つ複雑さによる認知負荷 課題外在性負荷 対象とは直接関係しない、外的要因による認知負荷 学習関連負荷 学習のための認知活動で発生する負荷 課題内在性負荷は、対象の本質的な複雑さに由来するものなので、その総量を減らすことは基本的にできません。「分割して統治せよ(Divide and conquer)」に従い、一度に取り扱う範囲を小さくすることは可能でしょう。 課題外在性負荷は、本来不必要な複雑さが持ち込まれたことによる負荷であり、ノイズと言えます。可能な限り除去するべきです。 学習関連負荷は対象を理解し、知識を活用して問題解決のための推論を行っていく上で適切な認知負荷と言えます。この負荷に割り当てるワーキングメモリが不足すると、「脳がパンクしてフリーズ」してしまうのです。 ソフトウェア設計と認知負荷理論 ソフトウェアが解決すべき問題は、たいてい複雑です。複雑なものを複雑なまま取り扱うのは大変なので、分割して小さくすることが大切です。 ただし、やみくもに分割すればいいというわけではありません。分割の仕方を間違えると、要素同士が複雑に絡まりあい、全体として「complicated」な構造になってしまいます。要素の数は多く多層的であっても、一貫性のある「complex」な構造を目指して分割する必要があります。 そのような構造化を行うためには、モジュールや コンポーネント に割り当てる責務を明確にした上で、それを実現するために必要な関連性の高いデータや操作を一箇所に集めた「高凝集」な設計が大切になります。そして、他の責務を担うモジュールや コンポーネント とのやり取りは明確に定義されたインターフェースを介した「 疎結合 」な設計とし、開発者が一度に取り扱う関心事を限定すべきです。 関心事の分離により、一度に取り扱う課題内在性負荷を適切なサイズにコン トロール できます。では課題外在性負荷についてはどうでしょうか。負荷を軽減するために考慮すべき設計原則やプ ラク ティスをいくつか挙げます。 方針と詳細の分離 インターフェースをうまく使い、方針と詳細を分離すること、依存性の向きを詳細から方針側へと向けることは重要です。データベース製品や物理的なテーブル構造、O/Rマッパーの実装制約といったテク ノロ ジー の詳細に関する知識が、 ビジネスロジック に入りこまないようにするべきです。 適切なネーミング 関数名や変数名は一貫性があり、明確に意味を読み取れるネーミングを心がけましょう。プロジェクトで定められた規約に沿うことも重要です。一貫性のないネーミングはノイズとなり、読み手に混乱を与えます。 抽象度の統一 publicメソッド、そこから呼ばれるprivateメソッド、さらにその先のprivateメソッド、と構造化する際は各メソッド内に記述する処理の抽象度をそろえることが大事です。異なる抽象度の処理が混じっていると、それに気を取られて認知負荷が高まってしまいます。 開発者にかかる認知負荷をできる限り低減することが重要です。 認知バイアス 認知バイアス とは思考の偏りを表す心理学の用語で、この存在によって人間はしばしば非合理な選択や判断をしてしまいます。近年注目されている 行動経済学 は、 認知バイアス に基づく人間の合理的でない行動が経済活動や社会現象に与える影響を研究する学問です。 認知バイアス によるトラップは日常生活のさまざまな場面に潜んでいますが、ソフトウェア開発においても例外ではありません。 ある仕様を満たすソフトウェアを実装するとしましょう。皆さんは、コードを書き始める前にどの程度設計を行いますか? 20年以上前に UML が流行した当初、詳細なクラス図やシーケンス図、ステートチャート図などを作成することが多くの現場で推奨されていました。コーディング前に事前に完全な設計を行うことをBDUF( Big Design Up Front )と呼びます。 物事は想定通りには運ばないものです。実装を進めるにつれ、考慮漏れ、エッジケースなどさまざまな問題が発見されます。その場しのぎの継ぎ接ぎの対応を積み重ねていくと、設計はどんどん歪んでいきます。 リファクタリング の必要性は感じるものの、納期のプレッシャーに負けてそのままコミットしてしまった、という経験は誰しもあるのではないでしょうか。 このような現象には、どのような 認知バイアス が影響しているでしょうか(参考文献 3)。 計画錯誤 過去に失敗をしていたとしても、今回はうまくいくだろうという楽観主義によって、甘い計画を立ててしまうバイアスを計画錯誤と言います。今回のケースでは、事前に設計をしたのだからうまく実装が進められるだろう、と楽観的に考えてしまうことです。 確証バイアス 自分の信念や仮説を支持する情報ばかりに注目し、逆の証拠を軽視したり無視したりしてしまうのが確証バイアスです。事前設計の不完全さを示す兆候があってもそれを無視し、軌道修正することなく実装を進めていってしまいます。 サンクコスト効果 このまま続けたら損を出すことがわかっているのに、これまで注ぎ込んだ労力や費用を考えるとやめることができない現象をサンクコスト効果と呼びます。設計のまずさに気づいてはいるが、今さら引き返すことができないという状態です。 このような 認知バイアス のトラップを避け、設計をうまく進めるにはどうしたらよいでしょうか。 まず、事前に完全な設計をできるという考えを捨てることです。ベテランほど、解くべき問題に対する完成形がある程度イメージできてしまうので、それに 固執 しがちです。しかし、それはあくまで仮説としての設計と捉えましょう。 また、 テスト駆動開発 (TDD)のプ ラク ティスも役立つでしょう。シンプルなテストケースから始めて、オンデマンドで漸進的に設計を進めるので、途中の軌道修正も容易です。Red - Green - Refactor のサイクルで頻繁に リファクタリング の機会が訪れるため、サンクコストからも解放されます。 エラー 人間はエラー(誤り)を起こします。D.A.ノーマン博士は、人間がエラーを起こす原因を理解しその原因が少なくなるようなデザインをすること、生じたエラーの発見と訂正が容易となるデザインをすることの重要性を説いています(参考文献 4)。また、エラーを以下のように分類しています。 エラー ミステーク:間違ったゴールまたはプラン形成による、不適切な行為 ルールベース:誤った規則に従ってしまう 知識ベース:誤った知識や不完全な知識により問題を間違って捉えてしまう 記憶ラプス:忘却によりゴール設定やプラン設定を誤ってしまう スリップ:意図とは異なる行為をしてしまうこと 行為ベース:行為を間違えてしまう 記憶ラプス:行為を忘れてしまう デザイン上の工夫としては、たとえば以下の方法が挙げられています。 制約 物理的な制約によってユーザーが行える操作に制限を加え、エラーを起こりにくくする。 アンドゥー システムにおいてアンドゥー(undo)コマンドを提供し、行った操作を元に戻せるようにする。 さて、ソフトウェア開発に目を移すと、 JSTQB の シラバス には以下のように書かれています(参考文献 5)。 人間はエラー(誤り)を犯す。そのエラーが ソースコード や他の関連する作業成果物の欠陥(フォールトまたはバグ)となる。 ソフトウェア開発においても、人間のエラーの防止、発見、訂正を行うための仕組みが重要と言えるでしょう。具体例としては以下が挙げられます。 リンタ(Linter) ESLintのようなリンタを導入することで、プログラム上の誤りを早期に発見し訂正できます。構文エラーの他にも、未使用の変数など将来のエラーにつながる問題点を事前に発見できます。 テスト駆動開発 Red - Green - Refactor のサイクルで小さな振る舞いを少しずつ実装していくため、誤った実装をした瞬間にそれを検出し、訂正できます。 契約による設計(Design by Contract, DbC ) 契約による設計は、 コンポーネント の提供者とクライアントとの間で、双方が満たすべき条件を明確に表明するという設計手法です。具体的には、事前条件、事後条件、不変条件を明確に定義し、それが満たされない場合には処理を中止します。 他の具体例を見てみましょう。以下のTypeScriptのサンプルコードでは、 Project オブジェクトを生成しています。 const departmentId: number = 1 ; const managerUserId: number = 2 ; // of(departmentId: number, managerUserId: number, projectName: string): Project // 引数の順番を間違えてしまっている! const project = Project.of(managerUserId, departmentId, 'Sample Project' ); of メソッドの引数には、本来「部署ID」「PMのユーザーID」の順番に指定する必要があるのですが、その順番を間違えてしまっています。どちらのIDも number 型であるため、 コンパイル 時にこの誤りは検出できません。 筆者は過去に実際の開発プロジェクトにおいて、このような誤りを見たことがあります。不幸なことに、開発者がテストで用いた部署とユーザーとがどちらも同じID値であったために欠陥検出ができずに、後工程まで持ち越されてしまいました。(これは、テストデータ設計においても誤り防止の観点が必要であることを示しています)。 このような誤りは、型チェックにより検出をしたいものです。 number のようなプリミティブ型を直接使うのではなく、 ドメイン プリミティブ型を導入しましょう。 const departmentId = new DepartmentId( 1 ); const managerUserId = new UserId( 2 ); // of(departmentId: DepartmentId, managerUserId: ManagerUserId, projectName: string): Project // 以下はコンパイルエラー const project = Project.of(managerUserId, departmentId, 'Sample Project' ); ※脇道に逸れてしまいますが、TypeScriptの型は構造の一致によって判定されるため、単純に id をプロパティに持つクラスを定義しただけでは上記のような型チェックをかけることができません。ブランド型という実装テクニックを使って、 DepartmentId と UserId が異なる型と判定されるようにする必要があります。 export class DepartmentId { private _departmentIdBrand !: never ; constructor ( public id : number ) {} } export class UserId { private _userIdBrand !: never ; constructor ( public id : number ) {} } アンダースコアのついたプロパティはダミーであり実際に使用されることはありません(そのため never 型で定義します)。このプロパティの存在によって構造に差異が生じ、異なる型と見なされるわけです。 このように、人間が起こしてしまうエラーに対して、仕組みとして対処できないか検討してみるとよいでしょう。 まとめ 人間の認知の仕組みに注目し、開発者をユーザーと捉えて人間中心の設計を行うことは、開発者体験の向上に繋がります。開発者体験は内部品質の向上に寄与し、ひいてはソフトウェアが顧客やユーザーに提供する価値が増大するのではないでしょうか。 参考文献リスト 『 認知負荷および認知負荷理論 (Cognitive Load Theory) をもう少し正確に理解するための心理学研究・知見の紹介 』(Zenn記事) 『 「快適な」学習のために〜認知負荷理論入門 』(note記事) 『 イラストでサクッとわかる!認知バイアス 誰もが陥る思考の落とし穴 』(池田まさみ、森 津太子、高比良美詠子、宮本康司 プレジデント社) 『 誰のためのデザイン? 増補・改訂版 認知科学者のデザイン原論 』(D.A.ノーマン、 新曜社 ) 『 テスト技術者資格制度 Foundation Level シラバス 』( JSTQB認定テスト技術者資格 認定委員会) 執筆: @tyonekubo 、レビュー: @kobayashi.hinami ( Shodo で執筆されました )
アバター
これは 電通総研 アドベントカレンダー 2024 の6日目の記事です。 はじめに 造語/隠語/謎用語とは? 実物たち ライトなもの ガッチャンコ グレーアウト ブランク 穴をあける 打鍵 暗号化 ~感 道なり 行って来い 正式用語だが注意を要するもの マイクロサービス 手順・ガイド 初見殺し 入れポン出しポン ガサーっと持ってくる 無理矢理突っ込む 謎の強調 いまいま ほぼほぼ フルフル すぐすぐ 終わりに はじめに みなさんこんにちは。 電通 総研 金融ソリューション事業部 エンジニアリングオフィスの水野です。 今回は、 システム開発 において使用される不思議な言葉たちをご紹介します。 もしかしたら弊社固有ワーディングかもしれませんが、「そんなのあるんだ」と緩く捉えていただければ幸いです。 造語/隠語/謎用語とは? 同音異義語 や、世間一般での使われ方とは大きく異なる単語、言い回したちです。 意味が分かりにくいのもそうですが、設計・実装作業に支障をきたすレベルの認識齟齬を生むこともあり、相当に侮れません。私はその手の用語が出てきたらまず疑ってかかり、詳細を聞き出すことを心がけています。 実物たち 早速実物たちを紹介します。 あくまで使われることがあるというだけで、普段のコミュニケーションで日常的に使用している訳ではないことをお伝えしておきます。 ライトなもの ワード自体短く、説明も軽量なグループです。 注意が必要な用語は ブランク ですが、昨今聞くことは減ってきたのでまず大丈夫だと思われます。 ガッチャンコ 大抵は集合演算の結合です。つまりJOIN。理由は不明ですが、内部結合を指すことが大半です。 「ガッチャンコする」という動詞で使うことが多いです。 グレーアウト UI部品を非活性にするという意味です。 Webページの場合は CSS を適用するなど実装方法はいくつかありますが、disabledにするということですね。 例えばボタンだったら、クリックやSubmitなどのアクションを受け付けなくしつつ、見た目も灰色など、反応しなそうなUIに変えることです。 認知負荷は高くなく、認識違いも発生しにくいですが、是非普通に「非活性化」と言っていただきたいです。 尚、 活性化 を ホワイトイン とは言いません(少なくとも私の周辺では)。 ブランク Nullと文字列型における空文字を区別しない使い方で、是非ともやめていただきたいです。 口語でもブランクブランク連呼されることがありますが、大体は入力値無しのことを言っています。 「要件定義や基本設計では意識しないで良いのでは?」という話はあるのですが、であれば「値無し」で良いです。 汎用機時代バリバリの方は、スペースや半角スペースと言うこともあります。固定長時代の名残り? 昔、設計書に スペース と書いてあったのでvarchar型のDBカラムにスペースを設定したら、バグって且つ設計した人に怒られました。 穴をあける 閉じたネットワークで、特定の プロトコル /エンドポイント( IPアドレス or ドメイン 、ポート番号) だけインバウンドを許容するという意味です。特定の宛先だけアウトバウンド通信を許容する際にも使用され、 穴あけ という名詞形もあります。 パブリッククラウド 上のアプリケーションでは頻繁に使われる印象です。 打鍵 テストケースをただひたすらに実施することです。 モンキー試験と呼ばれる、とにかく何でもかんでも入力する体を張ったケース消化の意で使う流派もありますが、私の周辺では粛々とケースをこなす意味で使っています。 語源としては、タイプライターの鍵盤を叩くであったり、銀行業務の打鍵(システムに諸々入力する)であったりと諸説あるそうですが、何にせよテストケース実施にそれっぽい単語を割り当てただけです。 暗号化 ハッシュ関数 を適用して ハッシュ値 を得ているケースの誤用です。頻出ではなく、本当に稀です。 新規に作る場合はアーキテクトの裁量で処理方式を決めれば良いのですが、既存システムで 実装済 みの場合には注意を要します。 「パスワードを暗号化している」と聞いたものの、実際はパスワードから得た ハッシュ値 を突き合わせていただけだったというのは、過去数回ありました。 ~感 いろいろな名詞と組み合わせて使います。 スケジュール感 や 費用感 、 コスト感 (費用感と同じ)、 期限感 などです。 これはかなり分かりやすいメッセージで、「この内容で合意したわけではないです。後で変わることもありえますし、責任は負えません」と言う意味が込められています。実際、決裁権も裁量もないのかもしれません。 であれば、 仮スケジュール や 想定スケジュール 、 概算費用 で良いのではないでしょうか。~感を付けるのは、更に確度が低く自信がない、なんらかの不安めいた気持ちのアピールなのかもしれません。 「大まかに捉えたいのです」と言うなら、やはり想定スケジュールが適しているでしょう。もっと粗い粒度で知りたいのだ等ありそうですが、そのあたりを汲み取るための労力が無意味なので、想定スケジュールで良いです。 スケジュール 、 工数 で会話したいです。感と言われても……感です。 ちなみに、スケジュールかんについては、 スケジュール観 が正しい漢字かもしれません。数回見たことがあります。 感・・・・感。 道なり 「道なりのスケジュールで」という使い方が多いです。 「道なりに進む」とは、曲がったりせずまっすぐ進むと言う意味なので、想像通り何も条件を変更せずに真っすぐ進んだ場合という意味です。 オンデマンドの割り込みが無い前提、且つ稼働を増やさずに今までの生産性を保った場合のスケジュール が近しい表現でしょうか。とは言え、具体的な期日や従前のスケジュールと一切変更がないかは確認すべきです。 道なり と言うと、 アントニオ猪木 氏の引退スピーチである、 「この道を行けばどうなるものか、(中略)迷わず行けよ。行けばわかるさ。」 が思い出されます。このように、 「不安はあるが新しい一歩を踏み出そう。迷わず行こう、行けばスケジュールが分かるよ。」 的な意味合いなのかもしれません。 ちなみに、上記の猪木氏の言葉は商標登録(文字商標)されています。 行って来い 金融業界では普通に使われます。売りと買いで相殺して、差引で金額の差が出ないことです。 例えば、「影響調査漏れで 工数 増ですが、類似機能の実装を効率化したので、行って来いで同じ 工数 です」のような使い方をします。 正式用語だが注意を要するもの マイクロサービス 本来のマイクロサービス アーキテクチャ でないケースがあります。これは、私の狭い観測範囲だけかもしれません。 API エンドポイントを持つコンテナは複数ありつつ、 RDB が中央に一つというパターンが多いです。 例えば以下のような構成で、これはテーブル変更が発生すると全てのサービスが止まるし、データベースがSPOFになります。マイクロサービスの良さを殺し、デメリットを強調していると言っても過言ではないでしょう。 API 毎に トランザクション 境界があると、結果整合性なり補償 トランザクション なりが必要になってきますが、このケースは大体最後に呼ぶ API だけで トランザクション が完結しているので、表立って問題にはならないです(それもおかしい)。 無理矢理コンテナ分けてみました系が多く、モジュラー モノリス で API エンドポイントを複数持たせる方が良いことも多いです。 サービスベースアーキテクチャ が最も近いので、そのように呼んで欲しいです。 手順・ガイド マイクロサービスと同じように一般的な用語なのですが、 どこまで求められているか が人によってバラバラなのが手ごわいポイントです。 そのドキュメントを見て手順に従えば、誰でもモノが作れる レベルが期待されることもあります。 手順通りにやれば、プログラミングスキルがなくても実装できるというのなら、自動生成など別のアプローチを選択すべきです。 フレームワーク やライブラリの使い方では、 GitHub や公式ページに記載されている内容を求められるケースもあり、マニュアルを読んでくださいという気持ちになります。ガイド提供側とされる側には大きな前提知識の差があるので、最初Draftを作って粒度を確認した方が良いでしょう。 書き過ぎても実装のアップデートに追従していくのは大変だし、そのうちドキュメントとの乖離が発生するので、コンセプトや設計指針など、なるべく普遍的な部分に留めたさがあります。 しかし、「ガイドが無い(あるいは薄い)から実装効率が悪かった」と言われることもあり、バランスが難しいです。 初見殺し 難度が高く、初見では意味不明なグループです。 暗黙の アーキテクチャ 特性が潜んでいたり、非機能要件のリスクが隠れていたりと、注意を要するのもポイントです。 ミステリアスアンニュイワーディングに慣れ親しんだ歴戦の猛者であっても、うっかり足元をすくわれかねない危険性の高さを孕んでいます。 入れポン出しポン 意味するところは 「データの更新も選択も単純で簡単、UIも簡便」 です。 暗黙的に、難易度が低くて 工数 がかからず、リスクも低いというメッセージがあります。画面とテーブルが1対1で紐づいている、マスターメンテナンス画面などでよく使われる印象です。 仮に上述の画面であれば正確に表現すべきで、例えば この顧客メンテナンス画面は、テーブルと1対1且つ画面項目とテーブル項目が完全に紐づいており、型や属性も同じです。 更に、月に1回程度しか使わない上に、例えバグで止まっても手動投入でシステム運用が回るワークアラウンドがあります。 SQLも単一テーブルへの挿入・更新・削除のみ、選択は1テーブルからで、述語は2, 3項目のフィルタ条件があるのみです。 データ量は最大100件程度、既存システムからのデータ移行もありません。 など、具体的に言う方が良いです。蓋を開けてみたら、選択時は他のテーブル含め非常に複雑なクエリが要る、データ量が大量などあるかもしれません。ある一項目だけ、取得時に超難儀な計算をやっていて、それは共通 コンポーネント が無いと実装出来ないなどあるかもしれません。または、1画面1テーブルで超単純だが、秒間 20,000ユーザのリク エス トを100ミリ秒以内に捌く必要があるかもしれません。 「かもしれない」 のですが、入れポン出しポンという用語で真実が分からないのは誰も幸せでは無いです。プロジェクトの近しいメンバーと、公式でない緩い トーク で共通認識の下で使うのは良いですが、公式の説明の場では避けるのが賢明です。 ガサーっと持ってくる 専らデータベースからデータを選択する際に用いられます。 「ガサっと」や「バサっと」など変形バージョンもあり、なかなかにバリエーションは多彩です。 意味は、「大量のデータを複雑な述語を伴わずに抽出する」 という表現が近しいです。 RDB を用いている場合、 SQL が単純だとしても、大量のデータを選択するのでパフォーマンスや アプリケーションサーバ のコンピューティングリソースが問題になることがあります。 特にパフォーマンスが顕著で、具体的な集合演算は何か、1レコードのサイズはどのくらいか、実際何行くらいを抽出するのかを具体的に確認することを推奨します。「ガサーっと持ってくるだけ」 と言いつつ、述語に関数を使っていたり、実は結合をしていたり、重い集合演算のケースもあります。 うっかり放置していると後で痛い目に合うので、この表現が出たときには一歩踏み込んで内容を確認しましょう。 無理矢理突っ込む これも亜流や派生形はありますが、「 ビジネスロジック でデータを加工して永続化する(大抵は挿入)」 という意味です。 無理矢理 を付ける意味は大抵無いのですが、業務ロジックを強引に適用する(数値を丸めないといけなかったり、デコードが必要だったり、演算が必要だったり)みたいなニュアンスの時に付与すると理解しています。 「突っ込む」もレベルは高いのですが、これは SQL のINSERT文など、データストアへの追記決め打ちでOKです。 謎の強調 これはIT業界固有ではないかもしれません。同じ言葉を重ねて意味を強調しているグループです。 いまいま 「いまいま」単体だとjust nowというだけなのですが、他の言葉を修飾しているケースで問題が顕在化します。 「いまいま必要ない」と言った場合、例えば以下の意味のどれかを、コンテキストや背景から判断しないといけません。 必要だと思うが、今は作る計画はない。且つ、いつ頃作るかも不明 言ってはみたものの未来永劫必要ない、きっと 次の基盤更改のタイミング (3年や5年)までは必要ない 向こう数年は必要ない 向こう1年は必要ない 向こう数か月は必要ない あたりです。 「それが何なのですか?」という話ですが、5か6なら近い将来を見越して アーキテクチャ やデータモデルに拡張性を持たせるべきかもしれません。 1.は突っ込んだ ヒアリ ングが必要かもしれません。「この瞬間は不要」という意味なのですが、であれば判明している期限やタイミングの把握に努めましょう。決まっていないなら、決まっていないことが分かれば良いです。 3.であれば、数年後の飯のタネになる仕込みや、別ソリューションの提案が可能かもしれません。 うっかり口癖で「いまいま~」はお控えいただきたいです。 ほぼほぼ 「ほぼ」が仮に8割方みたいな確率だとすると、「ほぼほぼ」は9割9分9厘くらいの確率なのでしょうか。 「可能性としてはまず有り得ないが、システムに絶対はないので、超微少な確率を表現した。ただし、リスクは皆無なのでバッファは不要」 みたいなケースで使えそうです。 ただ、そこまで分かっているなら、普通に 言語化 したほうがきっと良いです。 フルフル 「フルフルで アサイ ンしています」などで聞きます。 Full (=100%) なのですが、これが120%になっているとかでしょうか? つまり、残業を見込んでいるということで、稼働時間は2割増しみたいな話かもしれません。 フルと同じ意味で「フルフルで稼働」 というなら、普通に「フル稼働」で良いのではと思います。 すぐすぐ ASAP みたいな意味と捉えており、「一刻も早く」の最上位形です。 「すぐなんです!! 本当にすぐ、今すぐ!!!」みたいな、何らかの気合い的なやつを込めた魂の叫びを表したいのだろうと思っています。 終わりに 今回は様々な摩訶不思議な用語の紹介でした。 これらの用語を組み合わせた応用バージョンもあり、例えば 「こちらは入れポン出しポンなので、エースのA君を高難度の本機能にフルフルでアテンドすれば、行って来いで道なりのスケジュール感です」 などの合体奥義です。 全ての表現に対し、厳密な解釈を可能にさせることは過剰です。その塩梅は、それこそ空気を読む世界です。 「どこまで厳密な表現を使うか」は一様の基準を持ち得ないので、「どの用語や言い回しを使ってはならないか」というDeny Listを作る方が有効だと思います。設計書など、一定の記述レベルが求められる際にご検討ください。 ここまでお読みいただき本当にありがとうございました。 私たちは同じチームで働いてくれる仲間を大募集しています!たくさんのご応募をお待ちしています。 データエンジニア システムアーキテクト 執筆: @mizuno.kazuhiro 、レビュー: @handa.kenta ( Shodo で執筆されました )
アバター
STEP1:ライブラリのインストール STEP2:APIキーの設定 STEP3:データセットのダウンロード STEP4:和訳処理 STEP5:トレーニングデータの作成 STEP6:ファイルのアップロード STEP7:ファインチューニングジョブの開始 STEP8:検証 ケース0:「あなたは何が得意ですか?どんな振る舞いをしますか?」 ケース1:「仕事でのプレッシャーが大きく、ストレスがたまり何をしても楽しめません。どうすれば良いでしょうか?」 ケース2:「人前で話すときに緊張してしまい、自分に自信が持てません。克服する方法を教えてください。」 ケース3:「恋人との関係に悩んでいて、彼女の機嫌が悪いです。どう接していいか分からなくなっています。」 検証結果について考察 注意事項 反省点 さいごに こんにちは。コミュニケーションIT事業部 ITソリューション部の英です。 普段はWebアプリや スマホ アプリの案件などを担当しています。あと、趣味でAIを勉強しています。 皆さんいかがお過ごしでしょうか。しばらく育休を取っていたので久々の執筆です。 久々の執筆が Advent Calendar 2024 です。よろしくお願いいたします。 さて、タイトルにもある通り、今回はAIを使ってバーチャルカウンセラーを作りましょう。 ユーザーからの深刻な悩み相談に対して、AIが心理カウンセラーとして共感したりアド バイス をしたりします。 本検証では、 counsel-chat デー タセット を利用しました。このデー タセット は、CounselChat.com の相談者と認定カウンセラーによる回答から成る高品質な オープンソース のカウンセリングデー タセット です。 バーチャルカウンセラーとしての振る舞いを学習させるにはちょうど良さそうですね。 作業の全体の流れはこんな感じです。 データの取得 ノイズの除去 ChatGPTで自然な日本語に和訳 和訳したデー タセット でト レーニン グデータを作成 ChatGPTでファインチューニング デモアプリに組み込む 会話してみる 最初からデー タセット が綺麗なので、前処理はシンプルです。 工夫したところと言えば、和訳処理にChatGPTを使ったところでしょうか。 他の 機械翻訳 サービスも試したのですが、やはりChatGPTの和訳精度がダントツに良いです。 また、自然な日本語でファインチューニングしないとAIの回答が不自然な日本語になってしまいます。 日本語対応のAIチャットを作るうえで、実はこれが鍵だったりします。 直訳を学習データにすると、AIがカタコトになります。 作成したモデルをチャットアプリに組み込んで、実際にカウンセリングを受けてみましょう。 STEP1:ライブラリのインストール !pip install openai pandas datasets STEP2: API キーの設定 API キーは事前に発行しておいてください。 環境変数 に設定します。 import os import openai import random import pandas as pd from datasets import load_dataset # OpenAI APIキーの設定 os.environ['OPENAI_API_KEY'] = 'sk-(ご自身で発行したAPIキー)' client = openai STEP3:デー タセット のダウンロード デー タセット をダウンロードして、先頭行を出力してみます。 事前に確認したところ、questionTextとanswerTextには中身が空のデータが存在したので、ここで除去しておきます。 また、和訳処理とト レーニン グコストを削減するためにデー タセット から50%をサンプリングします。 # CounselChatデータセットのロード dataset = load_dataset("nbertagnolli/counsel-chat") train_data = dataset['train'] # 有効なエントリのみをフィルタリング valid_data = [entry for entry in train_data if entry["questionText"] is not None and entry["answerText"] is not None] # データ量を50%に縮小(コスト削減のため) reduced_filtered_data = random.sample(valid_data, int(len(valid_data) * 0.5)) # reduced_filtered_dataの先頭の1行を表示 print(reduced_filtered_data[0]) デー タセット は以下の構成であることが分かりました。 カラム名 説明 questionID 質問の一意の識別子 questionTitle 質問のタイトル stringlengths_questionTitle questionTitleの文字数 questionText 質問の本文 stringlengths_questionText questionTextの文字数 questionLink 質問へのリンクURL stringlengths_questionLink questionLinkの文字数 topic 質問のトピック stringlengths_therapistInfo therapistInfoの文字数 therapistURL セラピストのプロフィールURL stringlengths_therapistURL therapistURLの文字数 answerText 回答のテキスト stringlengths_answerText answerTextの文字数 upvotes 質問に対するアップボート数 views 質問の閲覧数 STEP4:和訳処理 2024年11月時点ではGPT-4o mini(gpt-4o-mini)が最適でしょう。 以下の通り、プロンプト+英語の原文を渡して翻訳データを作成します。 ト レーニン グコストを抑えるために、長文は300文字以内に要約して トーク ン数を削減します。 # ChatGPT APIを使って日本語に翻訳する関数 def translate_to_japanese(text): response = client.chat.completions.create( model="gpt-4o-mini", #これを読んでいる読者の時代で最も最適なモデルを選択してください messages=[ {"role": "system", "content": "あなたはプロの翻訳家です。次の英文をとても自然で流暢な日本語に翻訳してください。もし、文章が長くなってしまう場合には全角300文字以内に要約してください。"}, {"role": "user", "content": text} ], max_tokens=500, temperature=0.6 ) return response.choices[0].message.content # 和訳処理 translated_data = [] total_entries = len(reduced_filtered_data) for index, entry in enumerate(reduced_filtered_data): question_text = entry['questionText'] answer_text = entry['answerText'] # 翻訳の進捗を表示 print(f"Processing entry {index + 1} of {total_entries}...") # ChatGPT APIを使って和訳 translated_question = translate_to_japanese(question_text) translated_answer = translate_to_japanese(answer_text) # 翻訳結果を表示 print(f"Translated question: {translated_question}") print(f"Translated answer: {translated_answer}") # 和訳データを保存 translated_data.append({ 'questionText': translated_question, 'answerText': translated_answer }) # 各エントリの翻訳が完了したことを表示 print(f"Entry {index + 1} translated successfully.") print("-" * 50) # 区切り線を表示 # 全てのエントリの翻訳が完了 print("All entries have been translated successfully.") STEP5:ト レーニン グデータの作成 Fine-turningに与える学習データを作成します。 userからの相談内容に対して、assistantが回答するやり取りをmessagesに含めて、jsonlファイルに加工します。 目視での確認用に csv ファイルにも落としておきます。 # CSV用のデータに変換 import json df = pd.DataFrame(translated_data) df.to_csv("translated_fine_tune_data.csv", index=False) # JSONLファイルに変換して保存 output_path = "translated_fine_tune_data.jsonl" with open(output_path, "w") as f: for entry in translated_data: messages = [ {"role": "user", "content": entry["questionText"]}, {"role": "assistant", "content": entry["answerText"]} ] json.dump({"messages": messages}, f) f.write("\n") print(f"和訳されたデータが {output_path} に保存されました。") STEP6:ファイルのアップロード 作成したファイルをOpenAIのサーバーにアップロードします。 from pathlib import Path # ファイルをアップロード response = client.files.create( file=Path("translated_fine_tune_data.jsonl"), purpose="fine-tune" ) file_id = response.id print(f"Uploaded file ID: {file_id}") STEP7:ファインチューニングジョブの開始 # ファインチューニングジョブの作成 response = client.fine_tuning.jobs.create( model="gpt-4o-mini-2024-07-18", #これを読んでいる読者の時代で最も最適なモデルを選択してください training_file="file-(STEP6で出力されたファイルID)" ) fine_tune_id = response.id print(f"Fine-tune ID: {fine_tune_id}") 最初にト レーニン グファイルのバリデーションチェックが走り、ファイルに問題がなければ自動的にト レーニン グに移行します。ト レーニン グが完了すると以下のような表示になります。(Succeeded) メールでも以下の通知メールが自動送信されます。 STEP8:検証 FlutterFlowで作ったデモアプリに組み込んでみます。 ベースモデル と ファインチューニングモデル に同じ相談をして振る舞いの違いを確認しましょう。 以下のようにモデルIDを埋め込みます。 相談内容は以下の3つで試します。 「仕事でのプレッシャーが大きく、ストレスがたまり何をしても楽しめません。どうすれば良いでしょうか?」 「人前で話すときに緊張してしまい、自分に自信が持てません。克服する方法を教えてください。」 「恋人との関係に悩んでいて、彼女の機嫌が悪いです。どう接していいか分からなくなっています。」 ケース0:「あなたは何が得意ですか?どんな振る舞いをしますか?」 まずはジャブです。相手の出方を伺いましょう。 よかった。ちゃんとセラピストでした。 ファインチューニングの内容が反映されていることが期待できそうですね。 では、さっそく比較検証に入りましょう。 ケース1:「仕事でのプレッシャーが大きく、ストレスがたまり何をしても楽しめません。どうすれば良いでしょうか?」 ケース2:「人前で話すときに緊張してしまい、自分に自信が持てません。克服する方法を教えてください。」 ケース3:「恋人との関係に悩んでいて、彼女の機嫌が悪いです。どう接していいか分からなくなっています。」 検証結果について考察 ファインチューニングモデルでは セラピー 、 セラピスト 、 フラストレーション など学習データに含まれる単語を駆使して回答している ファインチューニングモデルの方が 温かさ を感じる。ベースモデルは 冷たさ を感じる。ベースモデルは「○○しましょう。」で終わっていることが多く、ファインチューニングモデルは「応援しています!」や「頑張ってください!」のような 相談者を励ますような内容 が含まれる傾向にあった。心理カウンセラーとしての 振る舞い をAIが模倣できていると感じる。 ファインチューニングモデルの方が 自分と向き合う系のコメント が多かった。 ※すべて個人の感想です 注意事項 実際の開発案件での利用について :日本の 臨床心理士 や 公認心理師 と米国のLicensed Clinical Psychologist(ライセンス取得 臨床心理士 )では資格の基準が異なります。つまり、価値観の基準が違います。日本人向けの心理カウンセラーをAIで実現したい場合は、日本国内の心理カウンセラーと密に連携して、日本独自の 心理的 ・文化的背景を反映させたカウンセラーAIシステムを設計する必要があります。単に米国の方法論をそのまま適用するのではなく、日本人の価値観や行動様式を深く理解し、日本人ユーザーに最適化されたサービスを提供するのがよいでしょう。 MITライセンスについて :学習データに使用したcounsel-chatはMITライセンスで管理されています。開発で利用する際には、ライセンスの規約に従ってください。具体的には、複製、改変、配布、商業利用が可能ですが、 著作権 表示と免責条項を残す必要があります。詳細については右記のリンクをご確認ください。 counsel-chat MIT License Copyright (c) 2020 nbertagnolli Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @misc{bertagnolli2020counsel, title={Counsel chat: Bootstrapping high-quality therapy data}, author={Bertagnolli, Nicolas}, year={2020}, publisher={Towards Data Science. https://towardsdatascience. com/counsel-chat~…} } 反省点 翻訳処理の際に人名や組織名、URLを除去すべきだった。せっかくChatGPTを翻訳に使うのであれば、フィルタリングを施して、学習データをもっとクリーンにしてあげるべきでした。検証中に何度か人名(セラピストの氏名)を喋ることがあって焦りました。 プロンプトにも気を配るべきだった。最終的な振る舞いの決定はプロンプトで調整できます。今回の記事では解説しませんが、もっとポップなAIに仕上げることも可能だったりします。例えばこのバーチャルカウンセラーを二頭身のかわいいキャ ラク ターとしてサービス化する場合、現在の喋り口調は丁寧すぎて、受け手はギャップを感じてしまいます。ファインチューニングとプロンプトの調整のバランスまで時間をかけて検証するべきでした。 さいごに さて、今回は 電通 総研Advent Calendar 2024として記事を書きました。 他のかたも面白い記事をたくさん書いているので、興味があれば覗いてみてください。 これからも AWS ×AI関連の検証記事をたくさん書いていきます。 ↓ のスターを押していただけると嬉しいです。励みになります。 最後まで読んでいただき、ありがとうございました。 コミュニケーションIT事業部では一緒に働いてくださる仲間を募集中です。以下のリンクからお願いします。 私たちは一緒に働いてくれる仲間を募集しています! 中途採用-コミュニケーションIT事業部 新卒採用-コミュニケーションIT事業部 執筆: 英 良治 (@hanabusa.ryoji) 、レビュー: @kobayashi.hinami ( Shodo で執筆されました )
アバター
こんにちは。X(クロス) イノベーション 本部 クラウド イノベーション センターの柴田です。この記事では Rego の Linter である Regal を紹介します。 1 この記事は 電通総研 Advent Calendar 2024 の 5 日目の投稿です。前日の記事は井手さんの「入社 3 年目の業務内容紹介」でした。 Open Policy Agent / Rego とは? Regal とは? Regal を実行する Lint を実行する ローカルで実行する インストールする 実行する CI で実行する エディタと組み合わせて実行する コードを自動修正する ルール 組み込みルール カスタムルール Regal を設定する 設定ファイル 格納場所 サンプル 設定ファイルの書き方 rules ignores capabilities project デフォルトの設定値 ルールを抑制する inline directive CLI フラグ 設定ファイル プロジェクトルート カスタムルールを実装する カスタムルールの種類 雛形を作成する サンプルコード ファイル単位で検査する 複数のファイルをまとめて検査する テストコード カスタムルールの書き方 格納場所 パッケージ メタデータ description (必須) related_resources (任意) schema (任意) ルール report aggregate aggregate_report Regal が提供する主な補助関数 result.fail(metadata, details) result.location(x) result.aggregate(chain, aggregate_data) regal.parse_module(filename, policy) テストを実行する おわりに 参考資料 Open Policy Agent / Rego とは? Open Policy Agent (OPA) と Rego の概要については以下の記事をご参照ください。 2 Policy as Code を実現する Open Policy Agent / Rego の紹介 - 電通総研 テックブログ Regal とは? Regal は Styra 社が開発している Rego の Linter です。 3 Regal を使用して ベストプ ラク ティスに反したコード よくある間違い、バグ、非効率的な処理を含むコード プロジェクト独自のコーディング規約に反したコード などを 機械的 に発見することで Rego コードの品質や可読性を向上できます。 Regal を実行する Lint を実行する ローカルで実行する インストールする 以下の 3 つの方法があります。 パッケージマネージャーを使ってインストールする。 4 GitHub の release asset をダウンロード&インストールする。 Docker を使う。 具体的なインストール手順はここでは省略します。詳しくは以下の公式ドキュメントをご参照ください。 Download Regal | Styra Documentation Packaging | Styra Documentation 実行する 以下のような Rego の ソースコード が policy/authz.rego にあるとします。 package authz import rego.v1 default allow = false allow if { isEmployee "developer" in input.user.roles } isEmployee if regex.match("@acmecorp\\.com$", input.user.email) 以下のコマンドで Lint を実行します。 5 regal lint policy/ するとルールに違反している箇所が表示されます。 Rule: opa-fmt Description: File should be formatted with `opa fmt` Category: style Location: policy/authz.rego:1:1 Text: package authz Documentation: https://docs.styra.com/regal/rules/style/opa-fmt Rule: directory-package-mismatch Description: Directory structure should mirror package Category: idiomatic Location: policy/authz.rego:1:9 Text: package authz Documentation: https://docs.styra.com/regal/rules/idiomatic/directory-package-mismatch Rule: non-raw-regex-pattern Description: Use raw strings for regex patterns Category: idiomatic Location: policy/authz.rego:12:27 Text: isEmployee if regex.match("@acmecorp\\.com$", input.user.email) Documentation: https://docs.styra.com/regal/rules/idiomatic/non-raw-regex-pattern Rule: use-assignment-operator Description: Prefer := over = for assignment Category: style Location: policy/authz.rego:5:15 Text: default allow = false Documentation: https://docs.styra.com/regal/rules/style/use-assignment-operator Rule: prefer-snake-case Description: Prefer snake_case for names Category: style Location: policy/authz.rego:12:1 Text: isEmployee if regex.match("@acmecorp\\.com$", input.user.email) Documentation: https://docs.styra.com/regal/rules/style/prefer-snake-case 1 file linted. 5 violations found. Hint: 2/5 violations can be automatically fixed (directory-package-mismatch, use-assignment-operator) Run regal fix --help for more details. CI で実行する CI で Regal を実行することもできます。例えば GitHub Actions であれば StyraInc/setup-regal action を使って以下のようなワークフローを設定できます。 name : Regal Lint on : pull_request : jobs : lint-rego : runs-on : ubuntu-latest steps : - uses : actions/checkout@v4 - uses : StyraInc/setup-regal@v1 with : # For production workflows, use a specific version, like v0.22.0 version : latest - name : Lint run : regal lint --format=github ./policy 詳しくは以下の公式ドキュメントをご参照ください。 Using Regal in your build pipeline | Styra Documentation エディタと組み合わせて実行する Regal は Language Server および Debug Adapter の機能を提供します。普段使っているエディタと Regal を連携させることで Linter からの素早いフィードバック コード補完 マウスオーバー時の ツールチップ の表示 定義への移動 などの恩恵を受けることが可能です。 本記事ではこれらの詳細は扱いません。詳しくは以下の公式ドキュメントをご参照ください。 Editor support | Styra Documentation Language Server | Styra Documentation Debug Adapter | Styra Documentation コードを自動修正する Regal は以下のルールに関してコードを自動的に修正できます。 opa-fmt use-rego-v1 use-assignment-operator no-whitespace-comment directory-package-mismatch 先ほどのサンプルコード policy/authz.rego を修正してみましょう。以下のコマンドでコードを自動的に修正します。 6 なお --dry-run フラグを設定して dry run することもできます。 regal fix policy/ 2 fixes applied: In project root: /home/ubuntu/projects/regal/policy authz.rego -> authz/authz.rego: - directory-package-mismatch - use-rego-v1 サンプルコードがルールに従って以下のように修正されました。 7 directory-package-mismatch に従ってファイルが policy/authz.rego から policy/authz/authz.rego へ移動されました。 opa-fmt と use-assignment-operator に従ってファイルの中身が以下のように修正されました。 package authz import rego.v1 -default allow = false +default allow := false allow if { - isEmployee - "developer" in input.user.roles + isEmployee + "developer" in input.user.roles } isEmployee if regex.match("@acmecorp\\.com$", input.user.email) 詳しくは以下の公式ドキュメントをご参照ください。 Fixing Violations | Styra Documentation ルール 組み込みルール Regal にはデフォルトで複数のルールが組み込まれています。 組み込みルールは以下の 7 つのカテゴリに分類されています。custom カテゴリ以外のルールはデフォルトで有効です。 ^6 bus : 一般的な間違い、 潜在的 なバグ、非効率的な書き方に関するルール。 idiomatic : 慣用的な書き方に関する imports : インポートに関するルール。 performance : パフォーマンスに関するルール。 style : スタイルに関するルール( Rego Style Guide )。 testing : テストに関するルール。 custom : ニーズに合わせてカスタマイズすべきルール。 具体的なルールの内容は以下の公式ドキュメントをご参照ください。 Rules | Styra Documentation カスタムルール 独自のルールを定義することもできます。詳しくは後ほど説明します。 Regal を設定する 設定ファイル 格納場所 Regal は設定ファイルを以下のように探索します。 カレント ディレクト リからプロジェクトルートへトラバースしつつファイル .regal/config.yaml を探します。最初に見つかったファイルを設定ファイルとして参照します。 --config-file フラグにファイルパスが指定されている場合はそれを参照します。 サンプル rules : style : todo-comment : # don't report on todo comments level : ignore line-length : # custom rule configuration max-line-length : 100 # warn on too long lines, but don't fail level : warning opa-fmt : # not needed as error is the default, but # being explicit won't hurt level : error # files can be ignored for any individual rule # in this example, test files are ignored ignore : files : - "*_test.rego" custom : # custom rule configuration naming-convention : level : error conventions : # ensure all package names start with "acmecorp" or "system" - pattern : '^acmecorp\.[a-z_\.]+$|^system\.[a-z_\.]+$' targets : - package capabilities : from : # optionally configure Regal to target a specific version of OPA # this will disable rules that has dependencies to e.g. built-in # functions or features not supported by the given version # # if not provided, Regal will use the capabilities of the latest # version of OPA available at the time of the Regal release engine : opa version : v0.58.0 ignore : # files can be excluded from all lint rules according to glob-patterns files : - file1.rego - "*_tmp.rego" project : roots : # declares the 'main' and 'lib/jwt' directories as project roots - main - lib/jwt 設定ファイルの書き方 rules rules には各ルールに関する設定を記述します。主な設定項目を以下に示します。 キー 説明 rules.default.level すべてのルールのデフォルトの level を指定します。 rules.<category>.default.level あるカテゴリのデフォルトの level を指定します。 rules.<category>.<rule>.level あるルールの level を指定します。 rules.<category>.<rule>.ignore.files あるルールの適用対象除外とするファイルを指定します。 level には以下の値を指定できます。 error : 違反を表示して lint コマンドをゼロ以外の終了コードで終了します。 warning : 違反を表示して lint コマンドをゼロの終了コードで終了します。 ignore : ルールを無効化します。 ルールによっては上記に加えて固有の設定項目があります。 詳しくは以下の公式ドキュメントに記載された各ルールの説明文をご参照ください。 Rules | Styra Documentation ignores ignores にはすべてのルールの適用対象外とするファイルを指定します。 capabilities capabilities には OPA のランタイムバージョンなどを指定します。 指定したランタイムバージョンでは利用できない機能や関数に依存したルールは無効化されます。 8 主な設定項目を以下に示します。 キー 説明 capabilities.from OPA のランタイムバージョンを指定します。このバージョンでは利用できない機能や関数に依存したルールは無効化されます。[^8]指定しない場合は Regal がリリースされた時の最新の OPA のランタイムバージョンが使用されます。 capabilities.plus 利用できる機能や関数を追加で指定します。 capabilities.minus 利用できない機能や関数を追加で指定します。 詳しくは以下の公式ドキュメントをご参照ください。 Capabilities | Styra Documentation project プロジェクトのルート ディレクト リを指定します。詳しくは後ほど説明します。 デフォルトの設定値 ユーザが設定ファイルで明示的に値を設定していない設定項目については以下の値が使用されます。 data.yaml ルールを抑制する Regal のルールがプロジェクトに適さない場合はそのルールを無効化できます。ルールを無効化する方法は以下の 3 種類があります。 inline directive ソースコード に以下のようなコメントを記述することで、 ソースコード の特定の箇所に対する特定のルールの適用を無効化できます。 # regal ignore:<rule> 利用例は以下のとおりです。 package policy import rego.v1 # regal ignore:prefer-snake-case camelCase := "yes" list_users contains user if { # regal ignore:avoid-get-and-list-prefix some user in data.db.users # ... } CLI フラグ 以下のフラグで指定したルールを有効化または無効化できます。 --enable , --disable : 指定したルールを有効化または無効化します。 --enable-category , --disable-category : 指定したカテゴリのルールを有効化または無効化します。 --enable-all , --disable-all : すべてのルールを有効化または無効化します。 また指定したファイルを無視することもできます。 --ignore-files : 指定したファイルを無視します。 設定ファイル 指定したルールを無効化します。 rules : style : prefer-snake-case : level : ignore 指定したカテゴリのルールを無効化します。 rules : style : default : level : ignore すべてのルールを無効化します。 rules : default : level : ignore 指定したファイルに対して指定したルールを無効化します。 rules : style : line-length : level : error ignore : files : - "*_test.rego" - "scratch.rego" 指定したファイルに対してすべてのルールを無効化します。 ignore : files : - file1.rego - "*_tmp.rego" プロジェクトルート Regal は以下の ディレクト リをプロジェクトルートとして認識します。 設定ファイルの .project.roots で指定された ディレクト リ .manifest ファイルが存在する ディレクト リ .regal ディレクト リが存在する ディレクト リ カレント ディレクト リ 一部のルール(例えば directory-package-mismatch )を正しく評価するためにはプロジェクトルートを正しく設定する必要があります。 もしプロジェクトルートが通常と異なる場合はプロジェクトルートを明示的に設定しておきましょう。 詳しくは以下の公式ドキュメントをご参照ください。 Project Roots | Styra Documentation カスタムルールを実装する カスタムルールの種類 カスタムルールには以下の 2 種類の実装方法があります。 ファイル単位で検査する方法 複数のファイルをまとめて検査する方法 ファイル単位ではルール違反の有無を判断できない場合は後者の実装方法を採用します。 雛形を作成する regal new rule コマンドを実行します。 regal new rule --category <category> --name <rule> すると Regal はカスタムルールの ソースコード の雛形を以下に作成します。 .regal/rules/custom/regal/rules/<category>/<rule>/<rule>.rego .regal/rules/custom/regal/rules/<category>/<rule>/<rule>_test.rego サンプルコード ファイル単位で検査する 例えば各ファイルの package が acme.corp system.log のいずれかで始まっていることを検査するカスタムルールは以下のようになります。 # METADATA # description: All packages must use "acme.corp" base name # related_resources: # - description: documentation # ref: https://www.acmecorp.example.org/docs/regal/package # schemas: # - input: schema.regal.ast package custom.regal.rules.naming["acme-corp-package"] import rego.v1 import data.regal.result report contains violation if { not acme_corp_package not system_log_package violation := result.fail(rego.metadata.chain(), result.location(input["package"].path[1])) } acme_corp_package if { input["package"].path[1].value == "acme" input["package"].path[2].value == "corp" } system_log_package if { input["package"].path[1].value == "system" input["package"].path[2].value == "log" } 複数のファイルをまとめて検査する 例えば default allow := false のように 名前が allow デフォルト値が false なルールがプロジェクト全体で 1 つ以上存在することを検査するカスタムルールは以下のようになります。 # METADATA # description: | # There must be at least one boolean rule named `allow`, and it must # have a default value of `false` # related_resources: # - description: documentation # ref: https://www.acmecorp.example.org/docs/regal/aggregate-allow # schemas: # - input: schema.regal.ast package custom.regal.rules.organizational["at-least-one-allow"] import rego.v1 import data.regal.ast import data.regal.result aggregate contains entry if { # ast.rules is input.rules with functions filtered out some rule in ast.rules # search for rule named allow ast.ref_to_string(rule.head.ref) == "allow" # make sure it's a default assignment # ideally we'll want more than that, but the *requirement* is only # that such a rule exists... rule["default"] == true # ...and that it defaults to false rule.head.value.type == "boolean" rule.head.value.value == false # if found, collect the result into our aggregate collection # we don't really need the location here, but showing for demonstration entry := result.aggregate(rego.metadata.chain(), {"package": input["package"]}) # optional metadata here } # METADATA # description: | # This is called once all aggregates have been collected. Note the use of a # different schema here for type checking, as the input is no longer the AST # of a Rego policy, but our collected data. # schemas: # - input: schema.regal.aggregate aggregate_report contains violation if { # input.aggregate contains only the entries collected by *this* aggregate rule, # so you don't need to worry about counting entries from other sources here! count(input.aggregate) == 0 # no aggregated data found, so we'll report a violation # another rule may of course want to make use of the data collected in the aggregation violation := result.fail(rego.metadata.chain(), {"message": "At least one rule named `allow` must exist, and it must have a default value of `false`"}) } テストコード 例えば先ほどの custom.regal.rules.naming["acme-corp-package"] パッケージをテストするテストコードは以下のようになります。 package custom.regal.rules.naming["acme-corp-package_test"] import rego.v1 import data.custom.regal.rules.naming["acme-corp-package"] as rule test_acme_corp_package_allowed if { module := regal.parse_module("example.rego", "package acme.corp.foo") r := rule.report with input as module count(r) == 0 } test_system_log_package_allowed if { module := regal.parse_module("example.rego", "package system.log.foo") r := rule.report with input as module count(r) == 0 } test_foo_bar_baz_package_not_allowed if { module := regal.parse_module("example.rego", "package foo.bar.baz") r := rule.report with input as module r == {{ "category": "naming", "description": "All packages must use \"acme.corp\" base name", "level": "error", "location": { "col": 9, "end": { "col": 12, "row": 1, }, "file": "example.rego", "row": 1, "text": "package foo.bar.baz", }, "related_resources": [{ "description": "documentation", "ref": "https://www.acmecorp.example.org/docs/regal/package", }], "title": "acme-corp-package", }} } カスタムルールの書き方 格納場所 カスタムルールの ソースコード は .regal/rules 配下に格納します。特別な要件がなければ regal new rule コマンドに倣って以下のパスに格納するのがよいでしょう。 .regal/rules/custom/regal/rules/<category>/<rule>/<rule>.rego もし regal/rules 以外の場所に格納する場合は regal の実行時に --rules フラグでパスを指定します。 パッケージ カスタムルールのパッケージは以下の 命名規則 に従う必要があります。 custom.regal.rules.<category>.<rule> メタデータ メタデータ については以下の公式ドキュメントをご参照ください。 Open Policy Agent | Policy Language | Metadata description (必須) カスタムルールの概要を記述します。 description : All packages must use "acme.corp" base name related_resources (任意) カスタムルールのドキュメントの URL を記載します。 description を documentation にしないと regal lint の実行結果には表示されません。 related_resources : - description : documentation ref : https://www.acmecorp.example.org/docs/regal/package schema (任意) スキーマ については以下の公式ドキュメントをご参照ください。 Open Policy Agent | Policy Language | Schema Regal では以下の スキーマ が提供されています。 schema.regal.ast : report , aggregate ルールの input の スキーマ schema.regal.aggregate : aggregate_report ルールの input の スキーマ 詳しくは後ほど説明します。 schemas : - input : schema.regal.ast ルール 実装方法ごとに必要なルールを実装します。 ファイル単位で検査する場合は以下のルールが必要です。 report 複数のファイルをまとめて検査する場合は以下のルールが必要です。 aggregate aggregate_report report ファイル単位でカスタムルールの検査を行います。 report contains violation if { # 1. ファイル単位でカスタムルールの検査を行う。 # ... # 2. 違反が発見された場合は report の要素に result.fail が生成するオブジェクトを加える。 violation := result.fail(rego.metadata.chain(), result.location(obj)) } input には各ファイルの Rego コードの抽象 構文木 を Regal 用に最適化したものが格納されます。 スキーマ は schema.regal.ast です。具体的な内容は以下のコマンドで確認できます。 regal parse <検査対象ファイル> ルール違反が発見された場合は report ルールの要素に result.fail 関数が生成するオブジェクトを加えます。 aggregate 各ファイルからデータを収集します。 aggregate contains entry if { # 1. 各ファイルからデータを収集する。 # ... # 2. aggregate の要素に result.aggregate が生成するオブジェクトを加える。 entry := result.aggregate(rego.metadata.chain(), {...}) } input は report ルールと同じです。 必要に応じて aggregate ルールの要素に result.aggregate 関数が生成するオブジェクトを加えます。このデータは後述する aggregate_report ルールに渡されます。 aggregate_report aggregate ルールの結果をもとにカスタムルールの検査を行います。 aggregate_report contains violation if { # 1. aggregate の結果に対してカスタムルールの検査を行う。 # ... # 2. 違反が発見された場合は aggregate_report の要素に result.fail が生成するオブジェクトを加える。 violation := result.fail(rego.metadata.chain(), {...}) } input の スキーマ は schema.regal.aggregate です。 input.aggregate には aggregate ルールの結果が配列として格納されます。 ルール違反が発見された場合は aggregate_report ルールの要素に result.fail 関数が生成するオブジェクトを加えます。 Regal が提供する主な補助関数 Regal が提供する補助関数のうち主に利用するものを以下に紹介します。 result.fail(metadata, details) # METADATA # description: | # helper function to call when building the "return value" for the `report` in any linter rule — # recommendation being that both built-in rules and custom rules use this in favor of building the # result by hand # scope: document fail(metadata, details) := ... report , aggregate_report ルールの要素となるオブジェクトを生成します。第一引数 metadata には rego.metadata.chain() を、第二引数 details には result.location が生成するオブジェクトを指定します。 result.location(x) # METADATA # description: | # returns a "normalized" location object from the location value found in the AST. # new code should most often use one of the ranged_ location functions instea, as # that will also include an `"end"` location attribute # scope: document location(x) := ... fail の第二引数に渡すオブジェクトを生成します。第一引数 x には input のうちルール違反が発見された要素を指定します。 result.aggregate(chain, aggregate_data) # METADATA # description: | # The result.aggregate function works similarly to `result.fail`, but instead of producing # a violation returns an entry to be aggregated for later evaluation. This is useful in # aggregate rules (and only in aggregate rules) as it provides a uniform format for # aggregate data entries. Example return value: # # { # "rule": { # "category": "testing", # "title": "aggregation", # }, # "aggregate_source": { # "file": "policy.rego", # "package_path": ["a", "b", "c"], # }, # "aggregate_data": { # "foo": "bar", # "baz": [1, 2, 3], # }, # } # aggregate(chain, aggregate_data) := ... aggregate ルールの要素となるオブジェクトを生成します。第一引数 chain には rego.metadata.chain を、第二引数 aggregate_data には任意のオブジェクトを指定します。 regal.parse_module(filename, policy) Rego コードの抽象 構文木 を Regal 用に最適化したものを返します。第一引数 filename にはファイル名、第二引数 policy には Rego コードを指定します。 この補助関数は主にテストで使用します。この補助関数の戻り値に対してカスタムルールが期待した結果を生成するかテストします。 rule.report == want with input as regal.parse_module(filename, policy) テストを実行する カスタムルールのテストコードを評価するには以下のコマンドを実行します。 regal test <path> カスタムルールおよびそのテストコードは Regal が提供するライブラリ data.regal.* や スキーマ schema.regal.ast を利用しています。そのため opa test コマンドではテストを実行できません。 おわりに この記事では Rego の Linter である Regal を紹介しました。 個人的にはプロジェクトで Rego を採用する際は Regal も一緒に導入することを強く推奨します。Rego は事例が少なく、実装経験が豊富なエンジニアはあまり多くありません。Regal を導入することで Rego の経験の浅いエンジニアでもベストプ ラク ティスに則ったコードを書くことができます。 私自身、 OPA / Rego を使って Kubernetes の マニフェスト ファイルや Terraform の構成ファイルに対するポリシーを書くことがあるのですが、今までは経験が浅く我流で Rego コードを書いていたため以下のような課題がありました。 よくある間違い、バグ、非効率的な処理を含むコードを誤って書いてしまう。 他のメンバーにとって可読性の低いコードを書いてしまう。 現在はプロジェクトに Regal を導入してベストプ ラク ティスやコーディング規約への準拠を強制することで Rego コードの品質や可読性に関するこれらの問題を改善できています。 最後までお読みいただき、ありがとうございました。 参考資料 Regal | Styra Documentation 私たちは一緒に働いてくれる仲間を募集しています! クラウドアーキテクト 執筆: @shibata.takao 、レビュー: Ishizawa Kento (@kent) ( Shodo で執筆されました ) この記事では Regal v0.28.0 を使用します。 ↩ 3 年前に書かれた記事のため記載内容の一部は古くなっています(特に文法など)。最新の情報は 公式ドキュメント をご参照ください。 ↩ Regal は β 版のため仕様が予告なく変更される可能性があります。 ↩ 公式ドキュメントでは Homebrew , asdf , pkgsrc , Nix , mason.vim が紹介されています。 ↩ Regal は Rego コードが構文的に正しく コンパイル 可能であることを前提としています。そのため regal lint コマンドの実行前に opa check --strict コマンドで Rego コードが構文的に正しく コンパイル 可能か検証することが推奨されています。詳しくは OPA Check and Strict Mode | Styra Documentation をご参照ください。 ↩ コードの自動修正を実行する際は、何か問題が発生した場合に簡単に変更を元に戻せるよう、Git などの VCS を使って変更をコミットまたはスタッシュしておくことを推奨します。 ↩ regal fix コマンドの実行結果を見ると directory-package-mismatch , use-rego-v1 の 2 つに関する修正が行われたと出力されていますが、実際には directory-package-mismatch , opa-fmt , use-assignment-operator の 3 つに関する修正が行われています。なぜこうなっているかは不明です。 ↩ ルールが capabilities に応じて有効化または無効化されるように実装されている必要があります。 ↩
アバター
こんにちは、 電通 総研IT、文系出身 新卒3年目の井手です。 普段は、金融機関の ポータルサイト の保守を担当しています。 この記事では、私の業務内容や1週間の過ごし方など、日々の働き方についてわかりやすくご紹介します。 IT企業への就職をお考えの学生の皆さんや、 電通 総研ITにご関心をお持ちの方の参考になれば幸いです。 自己紹介 私は文系学部の出身で、学生時代には公共政策やITについて幅広く学んでいました。 そのため開発経験がないままIT企業に入社しました。 そんな私がIT企業を志すきっかけとなったのは、学生時代の研究室での活動を通じて、 ITの持つ可能性の広さに触れたことです。 ITを活用することで、作業の効率化が進み、 データを活用して過去の経験を次に生かすことができると実感しました。 仕事内容 ここからは、自分がどのような内容の仕事をしているかご紹介します。 仕事内容を紹介するにあたり3つの視点でお伝えします。 まず1つ目は、使用しているツールについてです。 私が担当する案件では、ローコード開発ツールを用いてアプリケーションの開発を行っています。 ローコード開発とは、最小限のコードと ドラッグ&ドロップ 操作やテンプレートを活用することで、 効率的にアプリケーションを構築する手法です。 具体的には「 Salesforce 」を使用し、企業と顧客をつなぐ クラウド 型の顧客管理( CRM )や営業支援( SFA )を 実装しています。このアプリケーションでは、営業活動や マーケティング 、問い合わせ対応など、 さまざまな場面で顧客情報を一元管理できるため、開発未経験の私でも柔軟かつ効率的に開発と保守を行えています。 2つ目は、携わっているプロジェクトについてです。 現在、私は金融機関向けの ポータルサイト の保守プロジェクトに参画しています。 このプロジェクトは、顧客である金融機関のエンドユーザー(金融機関の顧客)の利便性と満足度の向上を目指しており、同時に金融機関の業務効率化と収益性の向上も視野に入れています。 3つ目は、私の役割についてです。 私は作業担当者として、依頼されたタスクを実施しています。 このプロジェクトは 電通 総研と私の所属する 電通 総研ITの協業で進めており、 電通 総研の保守PM(プロジェクトマネージャー)や自社の上長の指示に基づいて作業を行っています。 以下に、1週間のスケジュールをご紹介します。 配属からこれまでの流れ 入社後の半年間は、 電通 グループや 電通 総研グループの同期と交流しながら、研修を受ける期間でした。 研修内容は、開発に必要な基礎知識やビジネスマナーといった、業務に必要な基本的なスキルの習得が中心です。 1年目後半には、 OJT 研修が始まり、現場で先輩社員と一緒に業務を実践しながら必要なスキルを身につけます。 この研修では、個々のスキルや成長スピードに応じたサポートが行われます。 2年目の4月から正式に現場に配属され、私はまず、金融機関向け ポータルサイト の開発チームに参加しました。 ここで、特定機能の開発において実装からテスト工程までを経験しました。 その後、現在の金融機関向け ポータルサイト の保守チームに異動し、現在もそこで業務を続けています。 保守チームでは、既存システムの細かな機能の修正や定期的なバージョンアップといった業務を担当しています。 現在の働き方は、週1回の出社で、残業は月に7時間程度となっています。 入社前後のギャップについて ここでは、入社前に抱いていたイメージと入社後の実際のギャップについてご紹介します。 結論から言うと、私は良い意味でのギャップを感じています。 まず、入社前に抱いていた「 電通 総研ITは研修が手厚い会社」というイメージです。 面接の際、開発経験がないことへの不安を伝えたところ、研修期間が十分確保されており、 開発経験がない状態で入社した先輩社員も多いと説明がありました。 実際に研修を受けた感想としては、期待以上に手厚く、 結果的に1年間も研修を受けることができ、不安をしっかり解消することができました。 次に、入社前は「 電通 総研ITは技術者集団で、少し堅い会社」というイメージもありました。 これは、 電通 総研ITのホームページで大手企業との実績を見たことがきっかけで、 「大手との実績が多い=堅い会社」という印象を持っていたためです。 しかし、実際には 電通 総研ITは技術力に裏打ちされた堅実な会社でありつつも、活気にあふれた面も多くあります。 たとえば、自由に参加できるサークル活動や、年に1度の全社員が参加するイベントがあり、 普段の業務で接点がない先輩方とも交流できる場が設けられています。 こうした機会を通じて、風通しがよく、活気ある社風だと実感しています。 私自身もサークル活動に参加し、スポーツを通じてさまざまな社員と交流を深めています。 このような活動のおかげで、仕事以外の面でも充実した関係を築けていると感じています。 最後に 就職活動中の皆さんの中には、私と同じくIT系の専攻ではないけれど、 電通 総研ITに興味を持っている方もいるかもしれません。 この会社は未経験者から経験者まで、それぞれのスキルや適性に応じた働き方ができる環境が整っています。 私の働き方の紹介が、皆さんの将来を考える際の一助になれば嬉しく思います。 興味を持ってくださった方は、ぜひ以下の採用ページもご覧いただき、応募をご検討ください。 https://www.it.dentsusoken.com/recruit 執筆: @ide.wakana 、レビュー: @kinjo.ryuki ( Shodo で執筆されました )
アバター
はいどーもー! コミュニケーションIT事業部の宮澤響です! 本記事は 電通総研 Advent Calendar 2024 2日目の記事です! 記念すべき1日目である昨日の記事は、小林日菜美さんの「 【Salesforce認定アソシエイト試験】知識0から1ヶ月で合格した話 」でした! こちらは単なる学習方法や受験方法の紹介記事ではなく、試験前後に小林さんが実際に見舞われた(誰にでも起こり得そうな)トラブルとその回避方法についても分かりやすくまとまっている記事ですので、同試験を受験予定の方もそうでない方も、ぜひご一読ください! ということで、本記事では、 Power Automate を用いて、Backlogで特定の条件のチケットが起票・更新されたときにだけSlackに通知する方法をご紹介します! はじめに まずやってみる SlackへのPower Platform Connectorsの追加 Power Automateワークフローの作成 BacklogへのWebhookの追加 Power Automateワークフローの修正 実行結果 おまけ(Teamsへの通知) おわりに はじめに ああ…Backlogで特定の条件のチケットが起票・更新されたときにだけ通知がほしい…! そう思ったこと、ありませんか? ありますよね? 私はあります! ですが、以下の公式ドキュメントに記載されている方法では、対象チケットの条件を指定することができず、プロジェクト内のあらゆるチケットの起票・更新が通知されてしまいます。 BacklogのSlack連携 BacklogのMicrosoft Teams連携 そのため、例えば「自分が担当者に設定されたチケット」や「優先度が高のチケット」のみを対象としたいケースであっても、Backlogの公式連携機能では実現できません。 とはいえ、上記のようなケースは少なくないと考えています。 そこで、今回は、Power Automateを利用して、上記のようなケースへの対応策をご紹介します。 まずやってみる 大まかな実現方針は以下のとおりです。 最終的に、 Backlog -> Power Automate -> Slack の処理フローを実現します。 Backlog Webhookを利用して、BacklogからPower Automateにチケット情報を送信する Power Automateのワークフローで条件分岐を設定することで、特定の条件のチケット情報のみをフィルタリングする Power Platform Connectorsを利用して、Power AutomateからSlackにメッセージを送信する なお、以降の説明は、設定の都合上、上記3項目の逆順で記載します。 SlackへのPower Platform Connectorsの追加 まずはSlackのチャンネルにPower Platform Connectorsを追加します。 (私自身は「チャネル」表記派ですが、Slackは「チャンネル」表記、Power AutomateやTeamsは「チャネル」表記のようですので、本記事ではそれらに合わせて表記します。) Power Platform Connectorsとは、簡単に言えば、Power Automateをはじめとする Microsoft 社のローコードツールと、Slackなどの外部アプリケーションとを連携させるためのツールです。 なお、 ワークスペース にPower Platform Connectorsがインストールされていない場合は、 Slack ワークスペースにアプリを追加する を参考に、事前にインストールする必要があります。 Power Platform Connectorsの追加 チャンネル右上の「︙」から「チャンネル詳細を開く」を押下します。 「インテグレーション」タブにある「アプリを追加する」を押下します。 「 Microsoft Power Platform Connectors」を探し、「追加」を押下します。 Power Automateワークフローの作成 次に、Power Automateでワークフローを作成します。 なお、このステップではワークフローの大枠を作成するのみであり、詳細な条件などは後続のステップで作成します。 トリガーの追加 「要求」コネクタの「HTTP 要求の受信時」というトリガーを追加します。 少々見つけにくいトリガーなのですが、「HTTP」などと検索すればヒットするかなと思います。 設定が必要なパラメーターは以下のとおりです。 フローをトリガーできるユーザー: 誰でも ※ここでは 誰でも を選択していますが、必要に応じて、セキュリティを考慮したアクセス制限を行うことを推奨します。 アクションの追加 「Slack」コネクタの「メッセージの投稿 (V2)」というアクションを追加します。 なお、対象となるSlack ワークスペース に対して、これまでに一度もPower Automateを連携させたことがない場合には、こちらのアクションを設定する際に、併せて「接続」も新規作成します。(参考: Power Automate での接続の管理 ) 設定が必要なパラメーターは以下のとおりです。 チャネル名:通知を送信したいチャンネル(プライベートチャンネルの場合はカスタム値を入力) メッセージ テキスト:任意(例: チケットきたでー。 ) ワークフローの保存 ここまでの設定で、ワークフローを一旦保存します。 すると、このタイミングで「HTTP 要求の受信時」トリガーの名称が何故か「manual」に変化し、「HTTP URL」に値が設定されます。 「HTTP URL」は後続のステップで利用しますので、「URLのコピー」ボタンでコピーしておいてください。 ワークフローの有効化 「フローの管理」画面に戻り、保存したワークフローを有効化します。 画面上部の「オンにする」ボタンを押下します。 BacklogへのWebhookの追加 続いて、Backlog側の設定を行います。 Webhookの追加 対象となるBacklogプロジェクトの「プロジェクト設定」から「インテグレーション」を選択し、「Webhook」の「設定」ボタンを押下します。 「Webhookを追加する」ボタンを押下します。 Webhookの設定値を入力します。 今回は、以下のように設定します。 Webhook名:任意(例: 宮澤テスト ) Webhook URL:先ほどコピーした「HTTP URL」 通知するイベント: 課題の追加 、 課題の更新 デフォルト(「課題の追加」が選択された状態)のまま、実行テスト欄の「実行」ボタンを押下します。 ダイアログが表示されるので、「OK」ボタンを押下します。 ここまでの設定に不備がなければ、Slackの指定したチャンネルに以下のような通知が送信されるはずです。 「Webhookを追加する」ボタンを押下します。 リク エス ト スキーマ の取得 Webhook一覧に戻り、「送信履歴」タブを押下します。 先ほど実行ボタンを押下した時刻の項目の「すべて表示」を押下します。 最下行の JSON (リク エス ト)をコピーします。 Power Automateワークフローの修正 再びPower Automate側に戻ってきます。 リク エス ト スキーマ の生成 「manual」(トリガー)の「要求本文の JSON スキーマ 」の「サンプルの ペイロード を使用して スキーマ を生成する」を押下し、先ほどコピーした JSON を貼り付けます。 「完了」ボタンを押下します。 すると、「要求本文の JSON スキーマ 」が自動で生成されます。 後続のステップで担当者のユーザーIDを利用するため、 assignee の {} 内に以下の JSON を挿入します。 " type ": " object ", " properties ": { " userId ": { " type ": " string " } } 条件の指定 ここでは、「自分が担当者に設定されていること」を条件としたいと思います。 「manual」と「メッセージの投稿 (V2)」の間に、「Control」コネクタの「条件」というアクションを追加します。 そのまま検索してもヒットしない場合には、ランタイムを「組み込み」に絞った状態で検索するとヒットしやすいかなと思います。 設定が必要なパラメーターは以下のとおりです。 Condition expression:(後続のステップで詳しく説明します。) 左側の「値を選択してください」にカーソルを合わせた際に表示される雷マークのボタンを押下します。 「See more」を押下します。 assignee や category の上にある userId を押下します。 userId は複数存在するため、上記位置の userId を選択するようにしてください。 右側の「値を選択してください」欄に、自分のBacklogのユーザーIDを入力します。 なお、ユーザーIDはBacklogの個人設定画面から確認可能です。 設定内容を確認します。 ミスなく設定できていれば、以下のような状態となっているはずです。 特に、Code viewの7行目が @triggerBody()?['content']?['assignee']?['userId'] となっているかを確認しておいてください。 (異なる userId を選択してしまった場合にはこちらの値が異なって表示されているかと思います。) 「メッセージの投稿 (V2)」を「True」ブロックの中に移動します。 これで全ての設定は完了です! 実行結果 自分を担当者に設定したチケットを起票したところ、無事に通知が届きました! なお、 スクリーンショット などは省略しますが、具体的な通知条件の一例については以下のとおりです。 (通知するイベント: 課題をまとめて更新 については、リク エス ト スキーマ の形式が大きく異なるため、ここまでの設定では対応できていません。) 条件 通知の有無 「担当者:自分」のチケットを起票した場合 あり 「担当者:自分以外」のチケットを起票した場合 なし 「担当者:自分」のチケットの内容(詳細、種別、状態、など)を更新した場合 あり 「担当者:自分以外」のチケットの内容(詳細、種別、状態、など)を更新した場合 なし 「担当者:自分」のチケットを「担当者:自分以外」に更新した場合 なし 「担当者:自分以外」のチケットを「担当者:自分」に更新した場合 あり おまけ(Teamsへの通知) 「 Microsoft Teams」コネクタの「チャットまたはチャネルでメッセージを投稿する」というアクションを利用することで、Teamsに通知を送ることも可能です。 おわりに 本記事では、Power Automateを用いて、Backlogで特定の条件のチケットが起票・更新されたときにだけSlackに通知する方法をご紹介しました。 工夫した点、というほどでもないですが、ポイントとしては、 Power Automateワークフローの修正 のところで assignee の情報を追記したように、フィルタリングに利用したい条件に応じてリク エス ト スキーマ を修正する点が挙げられるかなと思います。 なお、私自身も、現在携わっている案件において、実際にこちらの方法を個人的に利用しています。 (以下のようにメンションとリンクを付与した上で通知させています。) (余談ですが語尾は「ぇー」「しー」「でー」「えふー」「じぇー」「ぉー」「ゅー」「わい」の中からランダムに選択されます。) さて、 電通 総研 Advent Calendar 2024 3日目となる明日の記事は、井手稚菜さんの「 電通 総研IT 文系出身 新卒3年目社員の働き方紹介」です! お楽しみに! 最後までお読みいただき、本当にありがとうございました! 私たちは同じ事業部で共に働いていただける仲間を募集しています! みなさまのご応募、お待ちしています! 株式会社 電通総研 新卒採用サイト <電通×IT>電通グループ基幹システムプロジェクトマネージャー <電通×IT>顧客DX案件プロジェクトマネージャー 政府・自治体向けシステム構築におけるプロジェクトマネージャー/リーダー デジタルマーケティング領域におけるプロジェクトマネージャー/リーダー 新規事業開発領域におけるプロジェクトマネージャー/リーダー エンタープライズ向けDX推進リーダー/エンジニア◆電通グループ協業◆提案活動~開発・運用まで <電通×IT>クラウドアーキテクト <電通×IT>アプリケーションアーキテクト 執筆: @miyazawa.hibiki 、レビュー: @nakamura.toshihiro ( Shodo で執筆されました )
アバター
こんにちは!HCM事業部の小林です。 本記事は 電通総研 Advent Calendar 2024 初日の記事となります。 今回は「 Salesforce 」という言葉しか知らなかった筆者が、1か月勉強して Salesforce 認定アソシエイト試験に合格した話です。勉強方法や必要な勉強時間、役に立った過去問などを紹介します。 実は試験を申し込んだ当初は何も分かっておらず、試験当日も100%の力を発揮することができませんでした。 同じように迷う方が少しでも減るように、自分の体験をもとに申込方法と受験の注意点を詳細にお伝えします。 これから受験する人はぜひ最後までご覧いただきたいです。 Salesforce認定アソシエイト試験とは? 試験の勉強方法 Trailmix(トレイルミックス)を進める 過去問を2周する 単語帳をつくる 試験の勉強時間 試験の申込方法 試験直前までにやるべき準備 ①コンピューターの技術要件を確認する ②環境のテストをする ③Respondus Lockdown Browserをインストールする ④生体認証プロファイルを作成する ①~④が試験開始時間の24時間前に完了しなかった場合 準備が必要なかったこと 試験後にあったトラブル 試験結果 おわりに Salesforce 認定アソシエイト試験とは? ひとことで言うと、 Salesforce の資格の中で一番初心者向けの資格 です。 試験の概要は以下のとおりです。 ・試験時間 :70分 ・問題形式 :多肢選択/複数選択方式の40問 ・合格点  :62%以上(32問以上正解で合格) ・受験料  :10,000 円(税抜) ・受験会場 :指定の試験会場または自宅 ・出題範囲 : Salesforce エコシステム(32%)        ナビゲーション(28%)        データモデル(25%)        レポートと ダッシュ ボード(15%) ・受験対象者: Salesforce の実務経験が0〜6ヶ月の人 (※2024年11月現在の情報です。最新情報は Salesforce 認定アソシエイト受験ガイド をご確認ください。) この試験は Salesforce の試験で唯一、 再受験が無料 でできます!たとえ不合格になっても再チャレンジしやすいのが魅力です。 試験の勉強方法 筆者が実施した勉強方法は主に3つです。 Trailmix( トレイルミックス )を進める Trailmixは、 Salesforce の学習サイト「Trailhead」の機能の1つで、いくつかのコンテンツを集めてつくるカリキュラムのことです。アソシエイト勉強用のTrailmixが用意されているので、それを最後まで取り組みました。 利用するには Salesforce のアカウント登録が必要です。 https://trailhead.salesforce.com/ja/users/strailhead/trailmixes/prepare-for-your-salesforce-certified-associate-credential 過去問を2周する noteで過去問を100問掲載している記事を見つけたので問題を2周しました。Trailmixだとあまり出てこなかった単語についても知ることができたのでやってよかったです。 単語帳をつくる Trailmixや過去問を進めていて分からなかった単語は スプレッドシート に記入しました。試験が近づいてきたら単語を隠しながら勉強していました。 試験の勉強時間 試験勉強に費やした1か月間はだいたいこのようなスケジュールでした。 期間 勉強期間 試験1か月前~2週間前 1~2時間 試験1週間前 2~3時間 直前の土日 5~6時間 もともと Salesforce に触ったことがある人や勉強に時間が取れる人は、これより少ない勉強時間でも合格できる気がします。 試験の申込方法 受験方法は、会場に行って試験を受ける「オフライン受験」と自宅から受ける「オンライン受験」があります。 筆者はオンライン受験で申し込みましたが、ここで注意が必要です。 試験の予約にはWebassessorというサイトを利用するのですが、本当は日本語のアカウントで登録すべきところを英語のアカウントで登録していました。 その結果、試験では問題文が全て英語になってしまい、英語が大の苦手な筆者は一度絶望しかけました。試験中にダメ元で日本語にできないか聞いてみましたが無理でした。 もしこの記事を読んでいる時点ですでに英語のアカウントで登録してしまって、キャンセル期限が過ぎている人は気合で頑張りましょう。 後から調べてみると、日本語のアカウントを登録する画面のURLにはsalesforcejpと書いてあることが分かりました。これから登録する人はまずURLを確認してください。 この先もオンライン試験で起こった/起こりうるトラブルを書いていますが、このようなトラブルが怖い人は試験会場での受験を推奨します、、 試験直前までにやるべき準備 オンライン受験を選択した方はいくつか事前準備が必要です。 ①コンピューターの技術要件を確認する パソコンの空き容量や管理者権限、ブラウザのバージョンなどの条件を満たさないと受験できません。 詳しくは Salesforce 公式のオンライン監督試験ガイドをご確認ください。 Mac OS 版 Windows OS 版 ②環境のテストをする 試験ではマイクとウェブカメラの両方が同時に機能する環境が必要です。以下のサイトで確認できます。 https://www.kryterion.com/systemcheck/ ③Respondus Lockdown Browserをインストールする Respondus Lockdown Browserは、試験中にブラウザや他のソフトウェアにアクセスできなくするツールです。 試験で使うPCの管理者権限がない場合、インストールできない可能性があります。インストールする前に確認しておきましょう。 また、公式サイトには「Respondus Lockdown Browser のダウンロードが未完了の場合は、ポップアップウインドウが表示され、ダウンロードが必要であることが分かります。」と書いてありましたが、筆者のPCはダウンロードが完了している場合でもポップアップは消えませんでした。 同じ事象で困っている人の参考になれば幸いです。 ④生体認証プロファイルを作成する 顔認証をして本人確認をするステップです。 画面の指示に従いながら何回か写真を撮ります。撮影中は眼鏡を外すようにしてください。 「We have successfully created your biometric profile (バイオトリックプロファイルの作成に成功しました)」の表示がされたら完了です。 ①~④が試験開始時間の24時間前に完了しなかった場合 これらの準備に時間がかかって試験に間に合わなそうなときや体調不良のときは、試験開始時間の24時間前までならスケジュールの変更・キャンセルが可能です。それ以降の場合は費用が発生するのでご注意ください。 準備が必要なかったこと 前に Salesforce の試験を受けたことがある人に準備することを聞いたものの、結局必要なかったことを紹介します。 眼鏡を外す 以前は眼鏡をしていると外すように指示があったみたいですが、今回は眼鏡をしながら受験をしても大丈夫でした。 身分証明のためのパスポートを用意する 以前は試験前の事前チェックとして、試験官に身分証明書を提示する工程がありましたが、結局身分証明書を提示することはありませんでした。 試験を受ける部屋から物をなくす 以前は受験場所に物がないことを証明するためにカメラで見せなければならなかったようで、知人はお風呂やトイレで受験していました。 ただ現在は、試験官と話すこともなく周囲の確認もありませんでした。 セキュリティソフトをオフにする 事前にオフにせず試験日を迎えましたが、試験直前にオフにしますか?というポップアップが出たのでオフにしてから試験に進みました。 試験後にあったトラブル Salesforce の試験は終了後すぐに結果が表示されるはずですが、試験結果を見てみると試験を受けていないことになっていました。 自分の不手際で試験の説明も全て英語だったことから、自分のミスなのか分からず問い合わせることにしました。 返信が来ましたが、日本の Salesforce 窓口に問い合わせていたみたいで、 アメリ カ本部に問い合わせるよう案内が来ました。 丁寧に問い合わせ方法をご説明いただき、 アメリ カ本部に問い合わせたところ、試験データの送信中にトラブルがあったとのこと。トラブルを修正して試験結果を反映させてくれました! 試験結果 本当にいろいろとありましたが無事に合格し、初めて Salesforce の資格を持つことができました! メールには各分野の正答率も書いてありました。分からない英単語がたくさんあった中でこのくらいとれていればまあまあなのでは?と思っています。 <メールの一部> おわりに いろいろとトラブル続きの受験になってしまいましたが、この際 Salesforce で頻繁に使われる英語くらいは勉強してみようと思うようになりました。 ただ筆者としては試験前後のトラブルは誰にも起こってほしくないので、この記事を読んでから試験に申し込む方は必ず「日本語のアカウント」で申し込んでください。 そしてもし試験後に受験結果がこなくても諦めないでお問い合わせを送ってください。 今後も Salesforce を勉強して使いこなせるようになりたいと思っているので、次回は アドミニストレーター 試験を受験したいです。(もちろん日本語で) 筆者が所属する事業部では様々な 中途採用 のポジションを募集しています! 職種ごとの詳しい募集要項は以下のリンクからご覧ください。 私たちは一緒に働いてくれる仲間を募集しています! 新卒採用ページ 【オープンポジション】自社パッケージ製品の導入プロジェクトマネージャ/リーダ 統合HCMソリューション導入におけるクラウドチームリーダー (東京)統合HCMソリューション 導入プロジェクトマネージャー/リーダー (名古屋)統合HCMソリューション 導入プロジェクトマネージャー/リーダー (大阪)統合HCMソリューション  導入プロジェクトマネージャー/リーダー 執筆: @kobayashi.hinami 、レビュー: @kinjo.ryuki ( Shodo で執筆されました )
アバター
こんにちは、XI本部プロダクト イノベーション センターの瀧川亮弘です。 現在行っているWebサイトの運用において、ヘッドレス CMS の導入を検討しています。 本記事では、ヘッドレス CMS の選定で調査したことを共有します。 ヘッドレス CMS とは ヘッドレス CMS とは、フロントエンドを持たない、 CMS (コンテンツ管理システム)のことです。 ここで言うコンテンツとは、ウェブサイトやアプリで使用される、テキスト、画像、動画、音声、ドキュメントなどのデジタルデータを指します。 WordPress のような従来型の CMS では、コンテンツの管理と表示が一体化しています。 管理画面からフロントエンド含めてオールインワンでウェブサイト構築が行えるという利便性がある一方、フロントエンドの柔軟性に欠けるという問題があります。 そこで登場するのが ヘッドレス CMS です。 ヘッドレス CMS は、コンテンツの管理に特化し、コンテンツの表示(フロントエンド)は API を通じて外部に任せます。 これには以下のメリットがあります。 フロントエンドの技術やデザインの柔軟性が向上する。 コンテンツを一元管理し、複数のプラットフォーム(ウェブ、モバイルアプリ、 デジタルサイネージ など)に効率的に配信できる。 上記の理由より、ヘッドレス CMS は近年とても注目されています。 アーキテクチャ 現在、運用しているWebサイトの構成図です。 黄色の部分がヘッドレス CMS を導入することで追加となる部分です。 現在、画像やテキストなどのコンテンツは、 ソースコード と一緒に GitHub で管理しています。 ヘッドレス CMS を導入することで、コンテンツの管理を GUI 上で行えるようにします。 これによりヘッドレス CMS の サブスクリプション コストや運用の手間はかかるようになりますが、エンジニアでなくても画像の差し替えなどが容易に行えるようになります。 技術選定 上記のような静的サイトを高速で配信する構成を Jamstack と呼びます。 Jamstackのコミュニティが公開している、 CMS の満足度とシェアに関するレポートを参考にしました。 縦軸に満足度、横軸にシェアを取るグラフに各種 CMS がプロットされています。 https://jamstack.org/survey/2022/#content-management-systems 満足度の高さ、シェアの高さより、 5. Strapi 6. Sanity について、さらに深く調査することとしました。上図の赤枠で囲っている CMS です。 他の CMS を候補から外した理由については、 ネガティブキャンペーン になってしまうため、ここでは割愛します。 Strapi と Sanity StrapiとSanityについて、実際に触って調査を進めました。 共通の強み 両者に共通する強みは以下のとおりです。 シェアが高く、かつコミュニティも活発なため、今後も継続的な機能改修やサポートが期待できる。 プラグイン のエコシステムが整備されており、機能の拡張性が高い。 多言語対応の言語数に制限がない。(グローバル展開の要件があり、特に重要視) 違いの比較 両者の違いを比較表にまとめます。 Strapi Sanity 強み - 完全に オープンソース の CMS であり、セルフ ホスティング が可能なため、インフラ環境の自由度が高い。 - まずは、PaaS(Strapi Cloud)として利用し、インフラ要件が複雑化してきた場合、セルフ ホスティング に切り替えるという運用も可能。 - UIのデザイン性が高く使いやすい。ドキュメントも見やすい。 - ライブコラボレーション機能により、 Google Docs のように複数ユーザーで同時編集が可能。 - コストを低く抑えられる。 弱み - セルフ ホスティング の場合、インフラの構築・運用の手間がかかる。 - PaaSの場合、Strapiアプリケーション管理用の GitHub またはGitLabの利用が必須。 - UIのデザイン性に劣る。ドキュメントもキャプチャなどが少なく、ややわかりづらい。(個人の感想です) ホスティング PaaS、またはセルフ ホスティング https://strapi.io/integrations/aws SaaS ※Sanity Studio(フロント部分)のみセルフ ホスティング することも可能。 https://www.sanity.io/docs/deployment リリース年 2016年 2017年 国 フランス アメリ カ 管理画面のUI また、一概には言えませんが、傾向としてSanityの方がコストは抑えられそうです。 StrapiだとTeam($499/month)プランからサポートされる、複数環境やスケジューリング機能ですが、Sanityだと Growth ($15/month)プランからサポートされています。 コンテンツ管理ユーザーの人数制限もSanityの方が緩いです。 逆にバックアップ機能は、StrapiだとPro($99/month)プランからですが、SanityだとEnterpriseプランからといったこともあるため、要件によってはStrapiの方がコストを抑えられる可能性もあります。 結論 StrapiもSanityも非常にイケているサービスだと感じました。 要件と照らし合わせ、さらに技術選定の検討を進めます。 最後までご覧いただきありがとうございました。 私たちは一緒に働いてくれる仲間を募集しています! 株式会社 電通総研 新卒採用サイト 執筆: @takigawa.akihiro 、レビュー: Ishizawa Kento (@kent) ( Shodo で執筆されました )
アバター
こんにちは、 電通 総研IT第2ビジネスユニット19の奥村です。 現在はOutSystemsというローコード開発プラットフォームを使って、製造系企業の システム開発 を担当しています。 ※ローコード開発とは、「必要最小限の ソースコード 開発でソフトウェア・ アプリ開発 を行う手法」のことです。 この記事では、入社してから現在までの仕事内容についてざっくりと説明します。 この記事が、IT業界に興味のある方の参考になれば幸いです。 自己紹介 2022年に新卒入社して3年目になります。 大学では経済学を専攻していて、ITやプログラミングといったものとは無縁でした。 私がIT業界を目指した理由は、手に職をつけたい、仕事の成果を形として見たいと考えていたからです。(実際にプログラミングして形になると嬉しいです) いろいろ探した結果、IT業界にたどり着きました。 そのため、IT知識ゼロで入社しました。 入社後 入社後は4月~9月の間、ビジネス研修とプログラミング研修を受けます。 ビジネス研修では社会人として必要なスキルを学び、プログラミング研修では基礎の基礎から始まり最終的には Java という言語を使ってシステムを開発する演習を行いました。 IT知識ゼロだったため最初は正直、ついていくのに必死でしたが講師の方や同期の人に質問したりしながら何とかついていきました。 後半になるとある程度、一人でプログラミングできるようになるので安心してください。 配属後 研修後は、OutSystemsを使って開発を行う部署に配属になりました。(ローコード開発に興味があったので希望を出していました) 配属後はまず、OutSystemsの認定資格の取得を目標に学習しました。 OutSystemsの公式HPにト レーニン グが用意されているので、動画やドキュメントを活用してOutSystemsの基本的な使い方を身につけます。大体1ヶ月ほど学習することで認定資格を取得することが出来ます。(やはりローコード開発なだけあり、 Java よりも実装が簡単でIT経験ゼロの身からすると、とてもやりやすかったです) そして、認定資格取得後は実際の業務に参加します。 業務について 現在は製造系企業の費用や予算、人員などを入力する生産管理システムのアプリを開発しています。 システムを利用されるお客様の利益を最大化するうえで、生産管理は非常に重要なシステムの位置づけとなります。 このプロジェクトではお客様の要望として Excel のような操作感を実現する必要があり、OutsystemsのForge(フォージ)のDataGrid(データグリッド)を使用しました。 ※Forge(フォージ)とは、OutSystems上で公開されている共通部品のようなもので、誰でも使用可能です。 Forgeを有効活用することでさらに開発効率や品質向上が期待できます。 DataGridを使用することで、一から実装しなくても表上で入力や編集、並べ替えなどの機能を使えるようになり、素早く実装を行うことができました。Forgeを使っての実装はOutSystemsならではだと思いました。 ↓DataGridを使用した画面です。データを入れただけでこのような見た目になります。(すごく便利です) また、規模の小さい アプリ開発 を一人で担当する機会があったのですが、数週間で実装しお客様に実際に使用していただくことができ、ローコード開発特有のスピード感を改めて感じました。 最後に 今回は入社してからの仕事内容についてざっくりと書きました。 現在は比較的簡単な機能を実装していますが、今後はより複雑な機能にも挑戦していきたいと思います。 Outsystemsは一般的なプログラミング開発と比べると、プログラミング量も少なく簡単に システム開発 ができますが Outsystems特有の知識や論理的に考える ロジカルシンキング などの学習が必要になります。( ロジカルシンキング はまだまだ課題です、、、) ですが、考えたものが形になるまでが早く、実装していて楽しいのが魅力だと思います。 私はIT知識ゼロで入社しましたが、研修を通して知識をつけ、少しずつできることを広げていきました。 働く上で楽しいと思えるのが一番成長できると思います。 最後までお読みいただきありがとうございます。 採用ページ 執筆: @okumura.seiya 、レビュー: @nagamatsu.yuji ( Shodo で執筆されました )
アバター
こんにちは、コーポレート本部 サイバーセキュリティ推進部 セキュアシステムデザイングループの福山です。 脆弱性 が日々報告される中、迅速かつ適切な対応を行うためには、効果的な トリアージ が欠かせません。 今回は、 脆弱性 対応を行う組織向けに、効率的な対応プロセスの進め方についてご紹介します。 はじめに FutureVulsについて SSVCを活用したリスク評価の概要 FutureVulsによるリスク評価 I. 事前準備 リスク評価対象とするサンプルシステムの概要 資産の登録 SSVCの設定 Exposure(インターネット露出レベル) Human Impact(攻撃された際の業務影響) 対応期限の設定 II. スキャンの実施から対応方針を決めるまで STEP1: スキャン STEP2: トリアージ SSVCによる評価 STEP3:調査・対応判断 まとめ はじめに 2024年7月、 IPA より「 脆弱性 対応におけるリスク評価手法のまとめ」が公開されました。 下記に公開資料のPDFと資料のポイントが掲載されています。 https://www.ipa.go.jp/jinzai/ics/core_human_resource/final_project/2024/risk-assessment-methods.html まずリスク評価とは、「脅威」「 脆弱性 」「資産」の3要素を考慮して実施し、その結果をもとに優先度をつけることが推奨とされています。 脆弱性 対応におけるリスク評価も同様で、リスクの3要素を加味しつつ、運用負荷も考慮したリスク評価が望ましいです。 上記資料では、SSVC(Stakeholder-Specific Vulnerability Categorization)を活用したリスク評価手法が有効とされています。 そこで本記事では、SSVCを活用したリスク評価をツールを用いて実現する流れをご説明します。 FutureVulsについて 今回は 脆弱性 管理ツールFutureVulsを使ってみたいと思います。 FutureVulsは、 OSS 脆弱性 スキャナのVulsをベースに、 脆弱性 管理を実施できる機能を備えた クラウド サービスです。 参考: https://vuls.biz/ FutureVulsのような 脆弱性 管理ツールを導入することで得られるメリットは大きく次の3つです。 脆弱性 情報の収集を手動で行うことによるチェック漏れや、 脆弱性 対応への対応漏れを防止できる。 脆弱性 情報を一元管理できる。 脆弱性 管理における一連の作業( 脆弱性 のレポート、対応判断等)を自動化することで作業負担を軽減できる。 3の「対応判断」を自動化する機能としてSSVCがあり、リスク評価で活用します。 SSVCを活用したリスク評価の概要 IPA によるとSSVCを活用したリスク評価は、下図の通りとなっています。 本当に対応が必要な 脆弱性 を抽出し、対応優先度を決定します。 SSVC を活用したリスク評価例の概要は、図 2-3 の通りである。 引用元:「 脆弱性対応におけるリスク評価手法のまとめ 」(p.29) 0次評価では、緊急性の高い即時対応を求められる S ランク相当の 脆弱性 情報を評価する。 0次評価の概要は、図 2-4 のとおり。 引用元:「 脆弱性対応におけるリスク評価手法のまとめ 」(p.31) SSVCの具体的な出力結果とランクの対応としては、図2-6のとおりである。 ImmediateがSランク、Out-of-cycleがAランク、ScheduledがBランク、DeferがCランク判定となる。 引用元:「 脆弱性対応におけるリスク評価手法のまとめ 」(p.33) ここでは各用語について説明します。 用語 説明 KEV KEV(Known Exploited Vulnerabilities catalog)は、米国サイバーセキュリティ・インフラセキュリティ庁( CISA )が公開している既知の悪用された 脆弱性 カタログのこと。KEVには、実際に悪用されたことが確認された 脆弱性 の情報が集められており、 脆弱性 が最初に発見された時期や、どのように悪用されているかなどの詳細が含まれている。 JPCERT/CC 注意喚起 JPCERTコーディネーションセンター ( JPCERT/CC )によって、日本国内における深刻かつ影響範囲の広い 脆弱性 などに関する情報が発信される。 CVSS CVSS(Common Vulnerability Scoring System) は、 脆弱性 の深刻度 を評価するための標準的なスコアリングシステム。本記事ではCVSS Base Scoreについて取り上げる。以下のとおり、スコアの範囲によって深刻度が定められている。 ・緊急: 9.0~10.0 ・重要: 7.0~8.9 ・警告: 4.0~6.9 ・注意: 0.1~3.9 ・なし: 0.0 EPSS EPSS(Exploit Prediction Scoring System)とは、Firstが提唱したもので、 脆弱性 が悪用される可能性 を示す指標。次の2つの情報を提供しており、本記事ではEPSS Probabilityについて取り上げる。 ①EPSS Probability: EPSSスコアのことで、今後30日以内に 脆弱性 が悪用される確率 ②EPSS Percentile: 脆弱性 全体の中で、悪用される可能性がどの程度高いかを示す順位(上位何%に位置するか) SSVC SSVCは 脆弱性 の対応優先度 を決めるための指標のことで、4つの入力を基に、緊急度を4段階評価で出力する仕組み。 【入力】  (1)Exploitation: 攻撃コードの公開有無や悪用レベル  (2)Exposure: インターネット露出レベル  (3)Utility Automatable: 攻撃の自動化  (4)Human Impact: 攻撃された際の業務影響 【出力】 「Immediate」: 全リソースを集中し必要に応じて組織の通常業務を停止して可能な限り迅速に対応する 「Out_of_cycle」: 通常よりも迅速に行動し、計画外の機会に緩和策または修復策を実施する 「Scheduled」: 定期メンテナンス時に対応する 「Differ」: 現時点では対応しない 評価の流れについて、細かく図に落とし込んでみました。 IPA によるSSVCを活用したリスク評価では、下図のように0次評価と1次評価は独立しています。 なお、SSVCは「脅威」「 脆弱性 」「資産」の3要素が全て考慮されています。 0次評価=脅威( CISA KEV、 JPCERT/CC 注意喚起) 1次評価=脅威(EPSS) × 脆弱性 (CVSS) 2次評価=脅威 × 脆弱性 × 資産(SSVC) ここまで IPA が提唱する評価手法を紹介しました。 これから紹介するFutureVulsのようなツールを用いることで、SSVCによる評価を自動算出できれば、リスクの3要素全てが網羅されたSSVC一本でのリスク評価が実現できると捉えています。 FutureVulsによるリスク評価 FutureVulsを運用する上で発生する作業には、「各システムの管理者が行う作業」と「組織のFutureVuls管理者が行う作業」の2種類があります。 各システムの管理者:実際に 脆弱性 対応を実施するプロジェクトチームのこと 組織のFutureVuls管理者:CSIRTなど組織の 脆弱性 管理を主導するチームのこと 後述の作業が発生する場面においては、上記のどちらが対応する作業かを色を分けて示しています。 I. 事前準備 今回は、サンプルシステムとして AWS 上の仮想Webシステムを想定して評価を行います。 リスク評価対象とするサンプルシステムの概要 外部のユーザーが利用する簡易Web受付サイト AWS 上に構築されている小規模なシステムで、 OSS を利用したWeb3層構造を想定。 各サーバは全てEC2 インスタンス であるため、OS以上はユーザ側でメンテナンスが発生する。 Webサーバの前段でALB等による認証を行わない。 わざと 脆弱性 が検出されるように、2年ほど前にリリースされた古いソフトウェアバージョンで構成(※実際には攻撃者によって 脆弱性 を突かれる可能性があるため、利用を避けるべきバージョン)。 システム構成 ソフトウェア構成 - Webサーバ - NGINX 1.23.2 - OpenSSL 3.0.6 - APサーバ - Python 3.11.0 - Flask 2.2.2 - uWSGI 2.0.21 - OpenSSL 3.0.6 - DBサーバ - MySQL 8.0.31 - OpenSSL 3.0.6 資産の登録 スキャン方法については、「 CPEスキャン 」という擬似サーバ上にソフトウェアを CPE 形式で登録し、 脆弱性 スキャンできる便利な機能があります。 CPE スキャンで実際のシステムにスキャナを導入する必要はありませんので、ちょっとした検証をする際に役に立ちます。 登録方法としては下図のように、ベンダー名やソフトウェア名を入力すると CPE の候補が表示されるため、登録したい CPE を選択し、バージョン情報を選択するだけで完了します。 ただし、OSの 脆弱性 も検出したいといった場合には、実際にサーバを構築し、 OSS をソースからインストールした上で、「 スキャナ 」をインストールする必要がありますので注意が必要です。 なおDBサーバについては、マネージドサービスであるRDSを例にあげると、「マイナーバージョンの自動アップグレード」を有効化している場合には自動パッチ適用が行われるため、スキャン対象から除外して問題ないと考えます。 参考: https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/USER_UpgradeDBInstance.Upgrading.html#USER_UpgradeDBInstance.Upgrading.AutoMinorVersionUpgrades 今回はEC2 インスタンス に MySQL をインストールしており、ユーザー側でパッチ適用が必要なため、スキャン対象とします。 SSVCの設定 Exploitaion(攻撃コードの公開有無や悪用レベル)とUtility Automatable(攻撃の自動化)は自動出力されるため、Exposure(インターネット露出レベル)、Human Impact(攻撃された際の業務影響)の2つを手動で設定します。 Exposure(インターネット露出レベル) Exposureについては、技術的な判断が必要です。 設定基準については、FutureVulsの記事を参考にしました。 SSVCのExposureとは、「対象システムがインターネットに露出しているレベル」です。対象システムのインターネット露出度に応じて以下の3段階の中から選択します。説明欄には決定のための具体例を記載しています。 引用元:「 インターネット露出サーバの自動特定とSSVC Exposure設定ガイド 」 Webサーバ :前段でALB等による認証はしておらず、インターネットから直接アクセス可能なため、「Open」と判断します。 APサーバ:パブリックIPを保持しておらず、一見controlledと判断してしまいそうになります。 しかしながら実質的な IPアドレス 制限がなく、インターネットからのアクセス経路があるため、こちらも「Open」とします。 DBサーバ:APサーバからのみアクセス可能であり、インターネットに直接面していないため、「Controlled」と判断します。 Human Impact(攻撃された際の業務影響) Human Impactの設定基準については、 IPA の記事を参考にしました。 「Human Impact」 影響の大きさとして、安全性の影響と業務遂行への影響の両面から評価する。安全性の影響としては、「None / Minor / Major / Hazardous / Catastrophic」の五段階で評価する(表C-5)。業務遂行への影響としては、「None / Degraded / Crippled / MEF Failure / Mission Failure」の五段階で評価する(表C-6)。最終的に、「HumanImpact」は安全性の影響と業務遂行への影響の評価を組み合わせて、決定木の選択項目として「Low / Medium / High / Very High」の4種類から評価される(表C-7)。 引用元:「 脆弱性対応におけるリスク評価手法のまとめ 」(p.93 - p.95) 脆弱性 の種類によってはWeb/APサーバの 脆弱性 を突かれることによって、DBに保存されている機密情報が漏洩するケースも考えられます。 よってHuman Impactについてはシステム単位で検討することにします。 安全性の影響:機密情報が漏洩した場合、集団に対する精神的または 心理的 な損害が発生する恐れがあるため、「Major」とします。 業務遂行への影響:機密情報が漏洩した場合、サービスの重要度によっては、複数または全てのミッションに障害を及ぼし、組織のミッションが果たせなくなる可能性があります。今回のWeb受付システムの場合では、組織のミッション達成が低下するレベルの影響と判断し、「MEF Failure」としておきます。 Human Impact:Major × MEF Failure = High SSVCの入力値をまとめると以下の通りとなりました。 サーバ名 Exposure Human Impact Webサーバ Open High APサーバ Open High DBサーバ Controlled High ここでSSVCの ロール設定 という機能を使うことで、サーバ別にSSVCの設定を作成することができます。 ロールを作成し、各サーバに紐づけることによって設定が完了します。 対応期限の設定 FutureVulsに登録されている全グループの設定を管理する「オーガニゼーション設定」と呼ばれる画面では、SSVCのレベルに応じた対応期限を設定できます。 参考: https://help.vuls.biz/manual/csirt_option/ssvc/config/#%E5%AF%BE%E5%BF%9C%E6%9C%9F%E9%99%90 対応期限については IPA の資料に目安の記載がありますが、ここは組織のポリシーに応じて設定してください。 引用元:「 脆弱性対応におけるリスク評価手法のまとめ 」(p.61) II. スキャンの実施から対応方針を決めるまで STEP1: スキャン CPE スキャンでは日次で自動スキャンされますが、ソフトウェア登録後すぐに実行したい場合は、「手動スキャン」を実行することで即時スキャンが可能です。 STEP2: トリアージ 脆弱性 対応における トリアージ とは「対応判断」のことです。 検出された 脆弱性 に対して重要度・緊急度を見極め、許容するものの選別や優先順位の決定などを行います。 SSVCによる評価 スキャン後、「 脆弱性 」タブを開くと、 脆弱性 の検出結果を確認できます。 「重要な未対応」タブの中に、SSVC Out_of_cycleと判断された 脆弱性 が表示されました。 脆弱性 としては4件、NGINX、OpenSSL、 Python の 脆弱性 が検出されているようで、この4件は計画外対応を行う必要があります。 SSVCの算出根拠も確認できます。 一方、SSVC Scheduledの 脆弱性 は「その他の未対応」に分類されました。 ここからは、「重要な未対応」タブに含まれるOut_of_cycle以上の 脆弱性 の調査・対応判断を行います。 STEP3:調査・対応判断 対応優先度が最も高い「Immediate」として検出されたNGINXの 脆弱性 から見ていきます。 まずはタスクのステータスを「INVESTIGATING」に変更し、調査中であることを明示します。 FutureVulsでは 脆弱性 が検出されると、サーバごとに 脆弱性 単位で「 タスク 」が作成され、ステータスを管理します(チケットに近いイメージです)。 続いて「詳細」タブにて、 脆弱性 の詳細情報を確認します。 該当システムに対してどの程度リスクがあるか、といった観点で確認すると良いと思います。 以下、一例として確認する項目をピックアップしました。 「サマリ」:攻撃を受けた場合に想定される影響、各機関が評価したCVSSスコアの一覧 「CVSS」:ネットワークから攻撃可能か等 「攻撃コード」:Exploit-DBや GitHub 上での攻撃コード・実証コードの公開有無 「緩和策」: Red Hat , Microsoft のデータソースにおける緩和策・回避策の有無 参考: https://help.vuls.biz/manual/cve/# 詳細タブ 「トピック」タブでは、 脆弱性 の調査結果やコメントの共有を行います。 参考: https://help.vuls.biz/manual/topic/ 例えば下記のような内容は 機械的 に収集できないため、トピックを利用して情報共有する使い方がおすすめです。 攻撃の成立条件 CVE-2023-44487への対策として、 AWS の基盤自体に緩和策が適用されているといった情報 参考: https://aws.amazon.com/jp/security/security-bulletins/AWS-2023-011/ NGINX自体の緩和策(下記リンク先の「Steps for Mitigating Attack Exposure」参照) 参考: https://www.nginx.com/blog/http-2-rapid-reset-attack-impacting-f5-nginx-products/ 「タスク×サーバ」タブで、どのサーバに 脆弱性 が存在するか確認します。 「タスク詳細」では、対応期限が表示されます。 これは、事前に「オーガニゼーション設定」で設定したSSVCのレベルに応じた「対応期限」が自動的に設定されます。 この対応期限に間に合うように対応予定日を決め、入力後、ステータスを「ONGOING」に変更します。 以上で、NGINXの 脆弱性 調査・対応判断が完了しました。 同様の流れで、OpenSSL、 Python の 脆弱性 についても調査・対応判断を行います。 以上で、「重要な未対応」に関する一連の調査・対応判断の作業が完了し、実際の 脆弱性 対応(事前のテスト、本番パッチ適用等)に移る準備が整いました。 残りの「その他の未対応」については定期メンテナンス実施時に対応するとします。 まとめ 脆弱性 管理ツールFutureVulsを用いて、SSVCによる トリアージ を試してみました。 今回の例では77件のうち、4件の 脆弱性 に対して優先度を上げて対応する結果となりました。 今回は3つのサーバで構成された単一のシステムでしたが、これが複数の環境が混在するシステムとなった場合には、この評価手法はより効果を発揮すると考えられます。 脆弱性 対応において、 IPA が提唱する0次評価・1次評価を導入することで運用負荷を削減し、FutureVulsのようなツールがある場合には2次評価のみで完結するため、より効率化できると言えます。 また、ツールを用いることで 脆弱性 情報の収集、調査、判断の自動化のメリットが得られるため、改めてツールの必要性を実感しました。 以上、最後までお読みいただきありがとうございました。 私たちは共に働いていただける仲間を募集しています! みなさまのご応募、お待ちしています! 株式会社 電通総研 新卒採用サイト 執筆: @fukuyama.kenta 、レビュー: @kou.kinyo ( Shodo で執筆されました )
アバター
こんにちは、 電通 総研の金子大地です。 この1年、所属するコミュニケーションIT事業部において、「若手プロジェクトマネージャー(以降「PM」)の育成活動」を行ってきました。その「活動内容」(前編)と「コンテンツ概要」(後編)を学生さん向けに紹介します。 多くの学生さんは、「PM」という言葉を聞いたことがあっても、具体的な仕事内容までは想像できないと思います。また、PMはプロジェクトチーム(多ければ50名以上)の責任者として推進役を担いますが、「そんなことが自分にできるんだろうか」と不安になりませんか。 電通 総研には、PMとしてのチャレンジの舞台と、先輩社員をはじめとするサポート体制があります。この記事が、学生のみなさんの「PM」という仕事への理解のとっかかりとなり、不安を軽減し、 電通 総研でPMをやってみたいかも!と興味を持つきっかけになるとよいなと思います。 また、社会人の方で、 電通 総研に興味を持っている方にも読んでいただきたいので、ぜひお付き合いください。 1. はじめに 2. 電通総研におけるPM育成活動 2-1. 会社全体でのPM育成の取組み 2-2. 現場におけるPM育成活動 3. 私が行った活動の内容 3-1. 私がなぜPM育成活動をしたのか 3-2. PMとしての暗黙知の資料化 3-3. 若手PMへの改善提案 おわりに 1. はじめに プロジェクトとは PMBOK (Project Management Body Of Knowledge)の定義では、「独自のプロダクト、サービス、所産を創造するために実施する有期的な業務」です。つまり、この世にひとつのアウトプットを生み出す、明確な開始・終了のある活動が「プロジェクト」です。世の中には様々なプロジェクトがありますが、本記事では「 システム開発 プロジェクト」を扱います。 プロジェクトの成功とは プロジェクトの成功は、古くからIron Triangle(鉄の三角形)と呼ばれる「Q/品質・C/コスト・D/納期」の達成具合で判断されてきました。その後、「QCD」だけでなくプロジェクトの活動や成果に関与する ステークホルダー の満足度で評価すべきという意見が増え、さらに近年では価値ある成果を提供したかが重視されるようになりました。何をもって「プロジェクト成功」とするかは、議論の対象になるものなのですね。 私はプロジェクトの価値を高めるために、 トレードオフ の関係にある「QCD」のちょうどいいバランスをとって完遂し、関わったお客様・プロジェクトメンバーが満足している(また一緒に仕事したいと思ってもらえる)、という状況を達成する必要があると考えています。 PMとは PMはプロジェクトチームを率いてプロジェクト目標を達成する責任を負っているので、「プロジェクト成功のために何をしたらいいかを考えて行動し続けること」が求められます。抽象的ながらこれが本質だと思っていますが、もう少し補足すると、PMは「プロジェクトの全てを自分事化して向き合い、プロジェクト特性をふまえた計画を立ててコン トロール しつつ、状況変化に対する柔軟な対応」が求められます。 2. 電通 総研におけるPM育成活動 2-1. 会社全体でのPM育成の取組み まずは、 電通 総研の会社としての取組みをご紹介します。 キャリアプラン の提示 電通 総研では、現場配属されてすぐにPMを任されることはありません(少なくとも私は見たことがありません)。「業務 スペシャ リスト」をしっかり経験してからPMを目指すなど、個人の希望・特性を考慮して段階的にPMになることを会社として推進しています。 ※ こちらのページの[キャリアステップ] をご参照ください ※ 以下にリンク先の図を引用しつつ、キャリアの「例」を追記しています。あくまで「例」なので、その点はご注意ください(この通りにキャリアを歩むことが約束されているわけでも、これが正解というわけでもありません)。 育成プログラムの提供 キャリアを積むためには、適切なスキルの獲得が必要です。 電通 総研では、スキル獲得のために多数の研修を提供しており、社費で受講できます。また、資格も社費で取得できます。 PM関連の研修だけでも2024年に26講座を提供しており、延べ638名の社員が申込んでいます。また、PM関連の資格では、PMIが提供している「 PMP (Project Management Professional)」、および IPA ( 情報処理推進機構 )が提供している「プロジェクトマネージャ試験」などを対象に、資格試験の対策・受験、資格維持に関わる費用を会社が負担しています。 ※ こちらのページの[教育体系] をご参照ください プロジェクト実践時の支援 上記で獲得したスキルを実際のプロジェクトで実践できるように、「標準 開発プロセス の提供」と「プロジェクト管理の支援」をしています。標準 開発プロセス (i*yes:アイズ)は CMMI 、ISO9001を参照して作られており、プロジェクトマネジメントを含めた開発の手順を定義しています。「プロジェクト管理の支援」は、提案・計画時などの主要な マイルストーン で、プロジェクト外部のメンバーがプロジェクトリスク等を確認します(RB:レビューボード)。 ※ こちらのページ をご参照ください 2-2. 現場におけるPM育成活動 電通 総研には、組織的な仕組みが用意されていることをご理解いただけましたか。 ですが、やはりこれだけでPMを「実践」するには不安が残るヒトも多いことでしょう。知識を習得しただけで優秀なPMになれるわけではありません。例えば「 PMP 」では、あらゆることを考慮し尽くしたプロジェクトマネジメントを学びますが、実際のプロジェクトで全ての領域を全力で実践すると、お客様の考える予算・期間に収まりません。また、プロジェクト実践時に支援してもらえると言っても、実際にプロジェクトを主体的に動かしていくのは自分自身です。 IPA でもPM育成においては「研修」だけでなく、「 OJT 」や「メンタリング」の重要性を説いています。 そこで、 電通 総研では従前から、 OJT に加えて「メンタリング」として、技術の現場組織のアチコチで「実践的なPMノウハウ」を共有してきました。簡単に言うと、「プロジェクト管理の体系的な知識を、実際のプロジェクトにはこうやって適用する」ということを学べる活動です。業務の傍ら「PM塾」と称して先輩からシリーズもので教わったり、部会発表で若手が自身の学びを共有して先輩に突っ込んでもらったりと、学習する文化があります。私もこうした活動の一端を担った形でして、それをご紹介します。 ※ 補足:プロジェクト特性に応じたプロジェクトマネジメント 各プロジェクトには様々な特性があります。小規模プロジェクトなら力業(ちからわざ)で何とかなることも、大規模プロジェクトではそうもいかず、より計画的に進める必要があります。人命・お金に関わるシステムの場合、そうでないシステムよりもイチ段高い品質が求められます。逆に、初期リリースの品質は ”そこそこ” でいいから、とにかく早期に利用開始したい、と要求をいただくこともあります。 したがって、 PMP 等で知識を得つつも、目の前のプロジェクトでは、予算・期間の制約やお客様の求める優先事項を考慮して「ちょうどいいバランス」でマネジメントする必要があります。そして、一概には言えませんが、それぞれの事業部におけるプロジェクトには似通った特色があるため(進め方が近い/共通する製品を扱う等)、各事業部内でPM育成活動が行われることは、理に適っている面もあります。 3. 私が行った活動の内容 3-1. 私がなぜPM育成活動をしたのか 若手PMは、先輩社員のサポートを受けながらPM経験を重ね、やがて独り立ちします。ですが、簡単には独り立ちできません。「一般知識(研修・資格等)」だけでPM遂行はできず、かといって経験できるプロジェクト数はさほど多くありません(感覚的には、プロジェクト1件あたりの開発期間は6ヶ月~2年くらいが多いです)。 したがって、一般知識と実プロジェクトとは別途、「メンタリング」に主眼を置いた学びの場を提供することで、PMとしての独り立ちを支援したいと考えました。「どう考えて行動するのか」といった本質的な理解を重視しつつ、「実プロジェクトで利用できるテンプレート」も提供し、役立つ活動になることを目指しています。 3-2. PMとしての 暗黙知 の資料化 PMP や研修では学べない「実践的なPMノウハウ」、特に「 暗黙知 の 言語化 」を意識して資料化し、所属組織(コミュニケーションIT事業部)に展開しました。コンテンツ概要は、[後編]でご紹介します。 現時点で展開済の資料( パワポ )が「計800ページ超」とボリューミーなので、週イチで社内のコミュニティに解説メルマガを投稿して、資料を読まなくても概略を理解できるようにしました(なお、それでもなかなか読まれないことを見越して、次項[3-3]の取組みをしています)。 ちなみに、別事業部から「PM経験が浅い 中途採用 者に学んでもらいたい」とお話があったり、グループ会社の方から「社内の人材育成に活用したい」とお声が掛かったりして、所属組織を超えて資料提供をしています。思わぬ反響もあるのだな、と嬉しい誤算でした。 3-3. 若手PMへの改善提案 若手PMが直近で担当したプロジェクトについて、私を含むメンバーが一緒に「振返り」をして、今後に向けた改善対応を考える、というものです。若手PMの「上長(マネージャー)」にも参加してもらうことで、ディスカッション後の改善活動を継続的にフォローしてもらっています。なお、「若手PM」と書いてはいますが、実際の対象者は「社会人4年目~15年目」と、社会人歴で言うとベテランの人もいました。 具体的には以下の流れです。 若手PMに、特に「自分が課題と思っていること(うまくできていないこと等)」を書面で事前 ヒアリ ングし、「どうしたら改善できるか」を対面でディスカッションしました。例えば、「お客様に依頼した作業が頻繁に遅れて、プロジェクト全体が遅延しがち」という課題認識がある場合、「そもそも 電通 総研から分かりやすく依頼内容を伝えられているか」、「お客様に検討していただくために、 電通 総研から提供している情報は充分か」、「お客様の繁忙時期をスケジュールに反映できているか」等の実態を若手PMに説明してもらい、なぜお客様の回答が遅れるかの真因に対しての打ち手をディスカッションします。 ありがたいことにディスカッション後のアンケート回答(若手PM、その上長)は総じて満足度が高く、「他案件の進め方を知る機会となってよかった」、「計画書等のPM資料のテンプレートが役立ちそう」といったコメントが多く見られます。やはり、自分が経験できるプロジェクト数は多くないため、他プロジェクトの進め方を効率よく把握でき、自分流のPMスタイルをブラッシュアップできる場は貴重なのだと思いました。 また、「改善点だけでなく、よい点はよいと評価してもらえたことが自信につながった」というコメントもあり、「なるほど」と思いました。私自身も若手PMの時にはおっかなびっくり「これでいいのかな?」と迷いながらプロジェクトを進めていた記憶があります。確かに、先輩PMに認めてもらうと安心や自信につながるな、と思いました。 おわりに 電通 総研には、「PM」に必要なスキルを学ぶ環境、そして独り立ちを支援する環境があることをご理解いただけましたか。 次回の [後編] では、私が社内展開した「PMノウハウ」のコンテンツ概要を紹介します。またお会いしましょう! 電通 総研でPMをやってみたいと思った方は、ぜひ下記もご参照ください。 私たちは同じ事業部で共に働いていただける仲間を募集しています! みなさまのご応募、お待ちしています! 株式会社 電通総研 新卒採用サイト 株式会社 電通総研 キャリア採用サイト 執筆: @kaneko.taichi 、レビュー: @nakamura.toshihiro ( Shodo で執筆されました )
アバター
こんにちは。 電通 総研IT 重松です。 Azure クラウド サービスを使って、アプリケーション開発および アーキテクチャ 構築の業務を行っております。 この記事では、主な業務内容と直近で対応した.NET:Azure Functionsの開発についてご紹介します。 1.初めに 1-1. 自己紹介 2. 業務紹介(Azure Functionsの分離ワーカーモデルへの移行) 2-1. なぜ移行が必要か 2-2. Azure Functionsのモデルの違い 2-3. 移行にあたっての進め方 3. 課題対応(診断設定経由でのログ出力および保存方式においてログが欠落する) 3-1.事象 3-2.原因と回避方法 原因 回避策 補足 4.まとめ 5.終わりに 1.初めに 1-1. 自己紹介 まずは自己紹介をいたします。 私は、新卒で システムエンジニア としてキャリアをスタートし現在は6年目になります。 主に ITアーキテクト として .NET 系の技術 を活用しながら、 クラウド 上で システム開発 の業務に携わっています。 主な業務としては、次のような作業を行っています。 .NETバージョンアップ対応 システムの動作環境を最新の.NET フレームワーク に更新する作業です。 この対応では、まず現在使用している.NETのバージョンを確認し、最新バージョンのリリースノートを調べます。 次に、既存のコードや使用しているライブラリが新バージョンと互換性があるかをチェックし、テスト環境でのアプリケーションで正しく動作するか確認します。 テストが成功したら、本番環境に新しいバージョンを展開し、パフォーマンスを引き続き監視します。 バージョンアップにより、セキュリティの強化や新機能の利用が可能となり、より安全で効率的なアプリケーション運用のために取り組んでいます。 SQL チューニング データベースのクエリ( SQL 文)の性能を改善する作業です。 この対応では、まず無駄な処理を減らし、効率的にデータを取得するためにクエリの書き方を見直します。 次に、適切なインデックスを設定することでデータ検索の速度を向上させ、さらにデータベースがクエリをどのように実行するかを示す実行計画を分析して ボトルネック を特定します。 SQL チューニングは、データベースの 応答時間 を短縮し、全体的なシステムパフォーマンスを向上させるために重要な作業であり継続的に対応しています。 性能試験 システムが要求される性能基準を満たしているかを確認するためのテストです。 この試験では、 応答時間 や スループット 、負荷耐性に焦点を当てます。 具体的には、システムがユーザーのリク エス トにどれくらいの速さで応答するか、一定期間内に処理できる トランザクション の数、同時に多くのユーザーがアクセスした際の安定性を評価します。 性能試験は、システムが実運用で適切に動作することを保証し、 潜在的 な ボトルネック の解消に向けて取り組んでいます。 IaC(Infrastructure as Code)のメンテナンス インフラスト ラク チャをコードとして管理する手法で、その代表的なツールである Terraform を対象に行っています。 Terraformを使ったリソースの構築、コードのGit管理、Terraformやプロバイダーの定期的なバージョンアップ等の作業を実施しています。 これらを行うことで、インフラを安定して運用し、将来的な変更にも柔軟に対応できるように構築に取り組んでいます。 これらの業務を通じて、システムの安定性とパフォーマンスを追求しつつ、新しい技術にも積極的にチャレンジしています。 技術の進化が速いIT業界で、柔軟に対応できるエンジニアを目指して日々取り組んでいます。 2. 業務紹介(Azure Functionsの分離ワーカーモデルへの移行) ここからは、日々行っている業務の1例として、直近に対応した 「Azure Functionsの分離ワーカーモデルへの移行」 をご紹介いたします。 現在担当しているシステムでは、.NET6から.NET8へのバージョンアップ対応を行っております。 上記に伴って、Azure Functionsの実行モデル移行が必要になりました。 2-1. なぜ移行が必要か そもそも実行モデルの移行が必要になった経緯を説明します。 Azure Functionsのイン プロセスモデル が、2026年11月10日をもってサポートが終了することが発表されました。 イン プロセスモデル は継続して利用可能なものの、セキュリティアップデートや新機能の提供は受けられないことから Microsoft 社は、分離ワーカーモデルへの移行を推奨しています。 また、次期バージョン.NET9ではイン プロセスモデル は利用できず、分離ワーカーモデルへの移行が必須であるということから.NET 8に移行するこのタイミングで分離ワーカーモデルへの移行対応が必要になりました。 出典: .NET on Azure Functions – August 2023 roadmap update .NET on Azure Functions – August 2023 roadmap update Azure Functions インプロセス モデル のサポート終了について(追跡 ID FVN7-7PZ) 2-2. Azure Functionsのモデルの違い 次にそれぞれの実行モデルの特徴を以下に記載します。 イン プロセスモデル イン プロセスモデル では、Azure Functionsのランタイムとアプリケーションコードが同じプロセス内で実行されます。 このモデルの主な利点は、ランタイムと密接に統合されているため、パフォーマンスが高く、セットアップが比較的シンプルなことです。短い 応答時間 が求められるシンプルなアプリケーションに適しています。 ただし、ランタイムに依存するため、主にFunction Host側(画像 青枠 )のAzureアップデート等によりLanguage Worker側(アプリケーション)も影響を受けてしまうというデメリットがあります。 また、Function Host側にLanguage Worker側の アセンブリ .dll を読み込ませ、Function Host側 と一体となってコードを実行する仕組み上、.NET の最新バージョンを使いたい場合、Function Host側 が対応しない限りLanguage Worker側(アプリケーション)が利用できないといったデメリットもありました。 分離ワーカーモデル 一方で、分離ワーカーモデルでは、Azure Functionsのランタイムとアプリケーションコードが別々のプロセスとして実行されます。 これにより、Functions Host側に依存することなく、Language Worker側(アプリケーション)は アセンブリ の依存関係やバージョン管理が柔軟に行えるようになったことがメリットとして挙げられます。 しかし、Functions HostとLanguage Worker間における通信が新たに追加されたこと(画像 青線 )、Language Workerが独立したことによる仕様変更を理解しつつ、アプリケーション開発を行うことが重要となります。 分離されたワーカー モデルと Azure Functions 上の .NET のインプロセス モデルの違い 2-3. 移行にあたっての進め方 実際に移行するに当たりどのような作業をしているのかご説明します。 Microsoft 社から、移行に当たっての マイグレーション ガイドライン や実装/アプリケーション構築例などが、公式ドキュメントとして提供されています。 .NET アプリをインプロセス モデルから分離ワーカー モデルに移行する 分離ワーカー モデルで C# Azure Functions を実行するためのガイド 上記を指針として、以下のように各フェーズ毎に対応を行います。 前述に挙げた、 マイグレーション ガイドや実装例には記載されていない機能改修が多数確認されたため、実装~テストの工程は繰り返し行う必要があり、移行作業に時間を要しました。 また、 クラウド 上での システム開発 の特性として、ローカル環境で正常に動作していたものが、 クラウド サービス上では想定外の動作をする、といったことが頻繁に起こりえます。 こういったものを見落とさないためにも、上流の工程はもちろんのこと、テスト方針の決定やテスト実施を慎重かつ正確に行うことが重要になります。 3. 課題対応(診断設定経由でのログ出力および保存方式においてログが欠落する) ここからは、開発を行っていく過程で苦労した課題についてご紹介します。 3-1.事象 担当システムでは、複数のログ出力方式を導入しています。 その中の1つに、Azure提供機能の 診断設定 というものを使用してログ出力するという仕組みを採用しています。 Azure Monitor の診断設定 ログ出力までの経路は以下のようになっています。 ・Azure Functions → ILogger → 診断設定→ ストレージアカウント また、パフォーマンスの観点から、ILoggerの実行はバッファリングして 非同期 で行う仕組みとしていました。 分離ワーカーモデル移行後のアプリケーションで、上記の仕組みを動作させたところ、ログ欠落の事象が発生しました。 課題切り分けのため以下のようなアプローチを試みました。 非同期処理から同期処理への変更 ILoggerの実行を非同期方式から同期処理に変更したところ、ログの欠落は発生しないことを確認しました。 以下がサンプルコードになります。 同期処理によるログ出力(ログ欠落 なし ) public void Run([TimerTrigger( "0 */1 * * * *" )]TimerInfo myTimer, FunctionContext functionContext) { // 開始ログ Logger.Log(aaa, model.Header, "Message" ); await Task.Delay( 1000 ); // 1秒待機 // 終了ログ Logger.Log(bbb, model.Header, "Message" ); } 非同期によるログ出力(ログ欠落 あり ) public void Run([TimerTrigger( "0 */1 * * * *" )] TimerInfo myTimer, FunctionContext functionContext) { // 開始ログ Logger.Log(aaa, model.Header, "Message" ); // 業務処理実装(引数にMicrosoft.Extensions.Logging.Iloggerインスタンスを渡す) // 非同期で Run 呼び出し. Run 内で 1 秒待機中に、本関数内で終了ログが出力されて関数が終了する Run<BaseRequestModel>(myTimer, _logger, functionContext, false ); // 終了ログ Logger.Log(bbb, model.Header, "Message" ); } async Run< T >(xxx myTimer, ILogger logger, yyy functionContext, bool zzz) { logger.LogInformation( "ログA" ); await Task.Delay( 1000 ); // 1秒待機 logger.LogInformation( "ログB" ); } Application Insightsへのログ出力の場合の挙動 前述に挙げた通り、複数のログ出力方式を採用している中の1つにApplication Insightsへのログ出力があります。 こちらの挙動を確認したところ、ログの欠落は発生しないことが確認されました。 以上から、非同期実行と診断設定の出力機構に問題があると推測を立てました。 3-2.原因と回避方法 原因 調査したところ、分離ワーカーモデルでの診断設定によるログ記録までの処理の流れが関係していることが判明しました。 分離ワーカーモデルでは、ホストが実行されるFunctions Hostプロセスと、関数コードが実行されるLanguage Workerプロセスに分離されますが、 診断設定のログは、Language Worker からの関数実行終了後の応答を契機として Functions Host にて記録しているとのことです。(画像 赤線 の部分) 分離ワーカーモデルでは Functions Host と Language Worker のプロセスが分かれていることにより、 「非同期実行したILoggerによるログ出力処理の終了を待たずメインの関数処理を終了してしまうと、関数実行後に記録されるログが拾いきれなくなる」 というものでした。 この仕組みはイン プロセスモデル も同様であるものの、分離ワーカーモデルでプロセス間通信(画像 赤線 )が発生することによりログの欠落が顕在化した、と理解しています。 一方、Application Insights のログは、画像 青線 の通り、Language Worker から直接記録されるため、プロセス間の通信がない分、診断設定ログに比べてログ欠落が発生しなかったのでは、と推測しています。 バックグラウンド タスクが完了していることを確認する 回避策 原因により、サブスレッドの終了を待たずに、メイン関数の処理が終了してしまっていたことでログの欠落が発生していたため、メイン関数の処理にてサブスレッドの終了を監視する処理の追加を試みました。 以下がサンプルコードになります。 public void Run([TimerTrigger( "0 */1 * * * *" )] TimerInfo myTimer, FunctionContext functionContext) { // 開始ログ Logger.Log(aaa, model.Header, "Message" ); // 業務処理実装(引数にMicrosoft.Extensions.Logging.Iloggerインスタンスを渡す) // 非同期タスクを受け取る var task = Run<BaseRequestModel>(myTimer, _logger, functionContext, false ); //非同期処理のタスクをwaitさせる task.Wait(); // 終了ログ Logger.Log(bbb, model.Header, "Message" ); } async Run< T >(xxx myTimer, ILogger logger, yyy functionContext, bool zzz) { logger.LogInformation( "ログA" ); await Task.Delay( 1000 ); // 1秒待機 logger.LogInformation( "ログB" ); } これにより、ログの欠落が回避できることを確認しました。 補足 一方で、サブスレッドの実行終了を待機することでメインスレッド、サブスレッドの実行時間が延びることになります。 それにより、単位時間あたりの関数実行数に対してアクティブとなるスレッド数が増えることになるため スレッド数の上限や使用できるリソースの上限に達しないように注意が必要であると考えています。 4.まとめ マイグレーション ガイド/実装例に、明確に記載されていない内容から発生した課題となります。 しかし、分離ワーカーモデルの仕組みやスレッドの仕様を理解することで対応することが出来ました。 分離ワーカーモデルは日々改修アップデートがされている機能です。 それにより、課題なども多く発生してしまっている状況ですが、これまで培った技術および知識を活用することで課題解決につながると感じました。 5.終わりに 今回は ITアーキテクト の業務紹介と担当案件を1例として紹介いたしました。 難易度の高い業務ではあるものの、最新技術を活用し、複雑な課題を解決するスキルが求められるため、常に技術的な成長とチャレンジがある点が魅力だと感じています。 少しでも参考に、そして ITアーキテクト というものに興味を持っていただければ幸いです。 採用ページ 執筆: @shigematsu.shu 、レビュー: @yukio.kazama ( Shodo で執筆されました )
アバター
こんにちは、X イノベーション 本部の 米久 保です。 サンフランシスコで2024年10月29日から30日にかけて開催されたイベント GitHub Universe 2024 に合わせて、さまざまな新技術・新機能に関する リリース が10月29日に GitHub 社より発表されました。 とくに、 GitHub Copilotがマルチモデル対応しAnthropic社のClaude 3.5 Sonnetや Google 社のJemini 1.5 Proなど最新のLLMが使用可能となったこと、 自然言語 だけで動作可能なマイクロアプリを構築できるツール「 GitHub Spark」は SNS 上でも大きな話題となりました。 これらと比べると一見 インパク トは薄いものの、 VS Code の GitHub Copilotでマルチファイル編集を可能とする「 Copilot Edits 」はAIコーディング支援によって開発生産性を飛躍的に向上させることが可能な画期的な機能です。 (生成コードエディタ「Cursor」を使っている方には、「(Cursorの)Composerに相当する機能がいよいよ GitHub Copilotでも実装された」と言えば通じるでしょう)。 本記事では、Copilot Edits機能の活用例として人間とコード生成AIによるピンポンプログラミング( ペアプロ で テスト駆動開発 を行う手法)を題材とし、機能の使い方をご紹介します。なお当該機能は執筆時点でプレビュー版であり、一般公開となる時点ではUIや操作方法、機能が変更される可能性もありますのでご留意ください。 Copilot Editsの基本的な使い方 VS Code のCopilotメニューから[Open Copilot Edits]を選択すると、Copilot Editsのペインが表示されます。Copilot Editsでは、編集対象の複数のファイルをWorking Setという単位にまとめます。[Add Files...]よりファイルを選択してWorking Setに含めた上で、プロンプトを入力して指示を出しましょう(次の図の赤枠部分)。 図の例では、 each.js ファイル(エディタ上部)に空実装の each 関数が定義されており、 each.test.js ファイル(エディタ下部)には each 関数に対するテストケースが3件記述されています。 テスト駆動開発 で少しずつ実装を進めていくために、最初のシンプルなテストケースを除き、 skip を指定してテスト実行対象外としています。 ※言語は JavaScript 、テスティングライブラリはJest、実行環境はNode.jsを利用 コード提案の受け入れ チャットの応答を確認しましょう。Working Setのファイルのうち、修正提案があるものはボールド表示となっています。ファイル名をクリックするとエディタタブが開き、修正内容を確認できます。 差分をプレビュー表示できる ので、とてもわかりやすいですね。 提案内容を受け入れる場合は[Accept]ボタンを、破棄する場合は[Discard]ボタンをクリックします。コード断片をコピー&ペーストで貼り付けたり、カーソルを移動して挿入したりといった作業は不要なのでとても楽です。 注意すべき点が二つあります。 一つ目。個々のコード修正提案を受け入れ(または破棄)した後に[Done]ボタンが表示されますが、これをクリックするとWorking Setに対する編集作業が完了という扱いになってしまうので、最後の最後まで押さないようにしてください。 二つ目。コード修正提案の受け入れはメモリ上の操作であり、明示的に保存を行うまで確定されません。 今回の例のように テスト駆動開発 で進める場合、テストコードを実行して関数の動作を検証する必要があるため、忘れずに保存をしなくてはなりません。 ターミナルから npm run test コマンドを実行してテストを流すと、最初のテストケースがパスし、コード生成AIの提案した実装が正しいことを確認できました。 以下のステップを繰り返して実装を進めていきます。 次のテストケースの skip 属性を外してチャットで実装を指示 コード生成の修正提案を確認して受け入れ テストを実行 全てのテストケースがパスしたら実装完了です! 人間がテストコードを書き、コード生成AIがそれをパスするようなプロダクションコードを書くという一連のやり取り(ピンポンプログラミング)が実現できました。 Tips Copilot Edits機能を使って テスト駆動開発 を進める上で役立つTipsをいくつかご紹介しましょう。 エラーの原因特定 全てのテストケースが一発でパスするような、幸せな物語ばかりではありません。 無情にもテストが失敗し、エラーが吐かれたときにも、コード生成AIの力を借りてエラー原因の特定とコード修正を行うことが可能です。 その場合、チャット欄に #terminalLastCommand を付けてエラー調査を依頼すると、Copilotがターミナルの履歴を参照することで適切な回答をしやすくなります。( #terminalLastCommand はコンテキスト変数と呼ばれるものの一つで、ターミナルにおける直前の実行コマンドとその出力が格納されています)。 コードの説明、 リファクタリング テストをパスする「動作するコード」ができあがったら終わりではありません。「 動作するきれいなコード 」に仕上げる工程が必要です。 自分が書いたコードではなく他人(コード生成AI)が書いたコードですから、まずは実装を理解しなくてはなりません。コード生成AIに説明させましょう。 このとき、単に説明をさせるのではなく、「具体例を用いて処理過程も示すようにしてください」というプロンプトを添えるとよいでしょう。 改善すべき点が見つかった場合、 リファクタリング を指示しましょう。 その他のアップデート 2024年10月29日の GitHub Copilotアップデートには、他にも多くの新機能や機能改善が含まれます。詳しくは 公式ブログ記事 をご参照ください。 まとめ この記事では、 GitHub Copilot( VS Code 版)の新機能であるCopilot Editsを使った テスト駆動開発 をご紹介しました。 Copilot Editsのマルチファイル編集機能は、他にもさまざまな用途で活用できるでしょう。たとえば、メイン関数とメインから呼び出される関数を複数ファイルで構成し、適切に構造分割されたコードを生成させることが可能になります。 私は、コード生成AIに一発で大きなプログラムを生成させることは「ガチャ」だと考えています。プロダクション環境にデプロイするコードの生成を運任せにしてはいけません。コード生成AIが生成するコードの精度と内部品質を向上させる鍵は、 問題を小さく分割すること です。 この記事で紹介したテクニックやCopilot Editsの機能を使うことで、皆さまのコード生成AIライフが向上することを願っています。 コードサンプル 今回の テスト駆動開発 で扱ったサンプルコードを以下に掲載します。 なおこの題材は、以前私がCursor + Claude 3.5 Sonnetで試した内容です( 私の個人ブログ記事 を参照)。 テストコード(人間が作成): const { each } = require("../src/each"); describe("each関数のテスト", () => { test("入力が空の場合", () => { const mockCallback = jest.fn(); each``(mockCallback); expect(mockCallback).not.toHaveBeenCalled(); }); test("データ行の数だけコールバックが呼ばれ、引数にはそれぞれのデータが渡される(属性1つ)", () => { const mockCallback = jest.fn(); each` name ${"Alice"} ${"Bob"} ${"Charlie"} `(mockCallback); expect(mockCallback).toHaveBeenCalledTimes(3); expect(mockCallback).toHaveBeenNthCalledWith(1, { name: "Alice", }); expect(mockCallback).toHaveBeenNthCalledWith(2, { name: "Bob", }); expect(mockCallback).toHaveBeenNthCalledWith(3, { name: "Charlie", }); }); test("データ行の数だけコールバックが呼ばれ、引数にはそれぞれのデータが渡される", () => { const mockCallback = jest.fn(); each` name | age | isAdmin ${"Alice"} | ${25} | ${true} ${"Bob"} | ${30} | ${false} ${"Charlie"} | ${35} | ${true} `(mockCallback); expect(mockCallback).toHaveBeenCalledTimes(3); expect(mockCallback).toHaveBeenNthCalledWith(1, { name: "Alice", age: 25, isAdmin: true, }); expect(mockCallback).toHaveBeenNthCalledWith(2, { name: "Bob", age: 30, isAdmin: false, }); expect(mockCallback).toHaveBeenNthCalledWith(3, { name: "Charlie", age: 35, isAdmin: true, }); }); }); プロダクションコード(コード生成AIが生成): const _ = require('lodash'); function each(strings, ...values) { return (callback) => { const headers = strings[0].trim().split(/\s*\|\s*/); const rows = _.chunk(values, headers.length); _.each(rows, (row) => { const obj = _.zipObject(headers, row); callback(obj); }); }; } module.exports = { each, }; 私たちは共に働いていただける仲間を募集しています! みなさまのご応募、お待ちしています! 株式会社 電通総研 新卒採用サイト 執筆: @tyonekubo 、レビュー: @nagamatsu.yuji ( Shodo で執筆されました )
アバター
こんにちは、XI本部プロダクト イノベーション センターの瀧川亮弘です。 現在、Next.jsの Static Exports により、Webサイトの構築を行っています。 本記事ではStatic Exportsの i18n (多言語)対応の実装方法を紹介します。 Static ExportsはNext.jsのアプリケーションを静的コンテンツ(HTML/ JavaScript / CSS /Image)としてエクスポートできる機能です。 Nodeサーバーが不要なため、S3などで簡単に ホスティング できます。 React/Next.jsの コンポーネント ベース指向やルーティング機能などの恩恵を享受しつつ、インフラの運用コストは最小化できます。 リク エス トに対して、静的なHTMLを返すだけなのでパフォーマンスもよいです。 i18n 対応については公式サイトで説明がありますが、説明が簡略的で別途検討することが多かったため、本記事に実装を記載します。 https://nextjs.org/docs/app/building-your-application/routing/internationalization ライブラリの利用も考えましたが、自身で実装してもそれほど複雑ではなかったため、独自に実装することとしました。 例えばこちらのライブラリでは、 タイムゾーン や単位などの i18n 対応も可能なので、要件に応じてライブラリを利用するとよいでしょう。 https://next-intl-docs.vercel.app/ 目標(ビルド後のイメージ) ビルドすると以下のようなoutフォルダが生成されるように実装します。 en, jaといった ロケール ごとのフォルダが生成されます。 例えば、enフォルダ配下のindex.htmlは英語の文言が適用されます。 out ├─en │ ├─hello │ │ └─index.html │ └─index.html ├─ja │ ├─hello │ │ └─index.html │ └─index.html └─index.html outフォルダ配下をそのままサーバーにデプロイすれば、静的サイトを配信できます。 画面の役割とURLの関係です。 ・ホームページ(英語版): https ://[ ドメイン ]/en/index.html ・ハローページ(日本語版): https ://[ ドメイン ]/ja/hello/index.html ・ダミーページ(アクセスされた場合、いずれかの言語のホームページに強制遷移する): https ://[ ドメイン ]/index.html 実装方法 Next.jsのフォルダ構成は自由度が高いため、いくつか流派がありますが、今回はこのようなフォルダ構成とします。 ├─next.config.mjs ├─app │ ├─(root) │ │ ├─layout.tsx │ │ └─page.tsx │ └─[locale] │ ├─hello │ │ └─page.tsx │ ├─layout.tsx │ └─page.tsx ├─constants │ ├─messages │ │ ├─ja.ts │ │ └─en.ts │ └─i18n.ts ├─contexts │ └─i18nContext.tsx ├─hooks │ └─useI18nRouter.ts └─types └─i18n.ts 順に各ファイルの役割を説明します。 まず、Static Exportsを有効化するため、設定ファイルにオプション output: 'export’ trailingSlash: true を指定します。 next.config. mjs const nextConfig = { output: 'export’, trailingSlash: true, } module.exports = nextConfig まずは、画面に表示する文言などを ロケール ごとに定義します。 サポート対象とする ロケール に合わせて、en.tsやja.tsを作成します。 constants/messages/en.ts import { Messages } from '@/types/i18n' ; const messages: Messages = { hello : { title : 'english hello page' , greeting : ( name : string ) => `hello!, ${ name } ` ; } // 省略 } constants/messages/ja.ts import { Messages } from '@/types/i18n' ; const messages: Messages = { hello : { title : '日本語ハローページ' , greeting : ( name : string ) => `こんにちは!, ${ name } ` ; } // 省略 } ロケール ごとに定義したメッセージは、 messagesMap にまとめておきます。 locales は対応する ロケール の配列です。 defaultLocale はデフォルトで利用される ロケール です。 constants/ i18n .ts import { Messages, Locale } from '@/types/i18n' ; import enMessages from './messages/en' ; import jaMessages from './messages/ja' ; export const locales: Locale [] = [ 'en' , 'ja' ] ; export const defaultLocale: Locale = 'en' ; export const messagesMap: { [ key in Locale ]: Messages } = { en : enMessages, ja : jaMessages, } ; 型も定義します。 types/ i18n .ts export type Locale = 'en' | 'ja' ; export type Messages = { hello : { title : string ; greeting : ( name : string ) => string ; } // 省略 } ; 配下の コンポーネント にメッセージを提供する、I18nProvider コンポーネント を定義します。 配下の各 コンポーネント では、useI18nContextを実行することで、メッセージを取得できます。 contexts/i18nContext. tsx 'use client' ; import { createContext, useContext } from 'react' ; import { Locale, Messages } from '@/types/i18n' ; import { messagesMap } from '@/constants/i18n' ; const I18nContext = createContext< | { locale : Locale ; messages : Messages ; } | undefined >( undefined ); export const useI18nContext = () => { const context = useContext(I18nContext); if (!context) { throw new Error ( 'Failed to retrieve I18nContext.' ); } return context; } ; export const I18nProvider = ( { children , locale , } : { children : React.ReactNode ; locale : Locale ; } ) => { const messages = messagesMap[locale]; return ( < I18nContext.Provider value = { { locale , messages } }> { children } </ I18nContext.Provider > ); } ; ロケール 切り替え用の2つの関数を用意します。 switchLocale は、任意の ロケール に切り替える関数です。 appendBrowserLocale は、ブラウザの言語設定に応じて ロケール を切り替える関数です。 サポートしていない場合は defaultLocale の ロケール に切り替えます。 hooks/useI18nRouter.ts import { useRouter, usePathname } from 'next/navigation' ; import { Locale } from '@/types/i18n' ; import { locales, defaultLocale } from '@/constants/i18n' ; export const useI18nRouter = () => { const router = useRouter(); const pathname = usePathname(); // URLのロケールを変更する const switchLocale = ( locale : Locale ) => { const newPath = pathname. replace ( /^\/[^\/]+/ , `/ ${ locale } ` ); router. push (newPath); } ; // URLにブラウザ設定(またはデフォルト)のロケールを付与する const appendBrowserLocale = () => { const browserLocale = window . navigator .language; const locale = locales. find (( locale ) => browserLocale. startsWith (locale)) || defaultLocale; const newPath = pathname. replace ( /^\// , `/ ${ locale } /` ); router. push (newPath); } ; return { switchLocale , appendBrowserLocale } ; } ; ここからappフォルダ配下にレイアウトやページを追加します。 app/[locale]フォルダを作成します。 i18n 対応が必要なページは全てこの[locale]フォルダ配下に配置します。 generateStaticParams の戻り値として、 ロケール 一覧を返すことで、ビルド時に各 ロケール ごとのHTMLが生成されます。 LocaleLayout の引数で ロケール を受け取り、 I18nProvider コンポーネント のpropsに渡します。 これにより、[locale]配下の各 コンポーネント でメッセージが取得できるようになります。 `` app/[locale]/layout. tsx import { I18nProvider } from '@/contexts/i18nContext' ; import { locales } from '@/constants/i18n' ; import { Locale } from '@/types/i18n' ; import '@/styles/main.scss' ; export function generateStaticParams () { return locales. map (( locale ) => ( { locale } )); } export default function LocaleLayout ( { children , params , } : { children : React.ReactNode ; params : { locale : Locale ; } ; } ) { return ( < html lang = {params . locale} > < I18nProvider locale = {params . locale} > { children } </ I18nProvider > </ html > ); } 各ページで useI18nContext を実行して、メッセージを取得します。 app/hello/page. tsx 'use client' ; import { useI18nContext } from '@/contexts/i18nContext' ; export default function Hello () { const { messages } = useI18nContext(); return ( < h1 > { messages . title } </ h1 > // 省略 ); } app/(root)配下にダミーのレイアウトとページを作成します。 ルートのパスにアクセスしてきた場合、app/[locale]/page. tsx の画面に強制的に遷移させます。 appendBrowserLocale を実行し、ブラウザの言語設定に応じた[locale]を指定します。 app/(root)/layout. tsx import { ReactNode } from 'react' ; export default function RootLayout ( { children } : { children : ReactNode } ) { return ( < html > < body > { children } </ body > </ html > ); } app/(root)/page. tsx 'use client' ; import { useEffect } from 'react' ; import { useI18nRouter } from '@/hooks/useI18nRouter' ; export default function RootPage () { const { appendBrowserLocale } = useI18nRouter(); useEffect(() => { appendBrowserLocale(); } ); } 終わりに 最後までご覧いただきありがとうございます。 お役に立てたら光栄です。 参考 https://qiita.com/koshitake2m2/items/dacfdafb833344bada4d 私たちは共に働いていただける仲間を募集しています! みなさまのご応募、お待ちしています! 株式会社 電通総研 新卒採用サイト 執筆: @takigawa.akihiro 、レビュー: @miyazawa.hibiki ( Shodo で執筆されました )
アバター
はいどーもー! 閲覧履歴を表示させるためにCtrl+H( Windows )やcmd+Y( Mac )を押下するつもりが誤ってCtrl+Yやcmd+Hを押下してしまう、コミュニケーションIT事業部の宮澤響です! 本記事では、2024年11月1日より新 シラバス Version 2023V4.0.J02 準拠となった JSTQB認定テスト技術者資格 Foundation Level試験 を受験してきた話をまとめます! なお、その場で結果が表示されるタイプの試験ではないため、本記事公開時点では合否は判明していません…あしからず…! JSTQB認定テスト技術者資格 Foundation Level試験とは 受験のきっかけ 何故シラバス切り替え直後のタイミングで受験したのか 利用教材など 受験してみての所感 難易度について 設問について 自身への影響について おわりに JSTQB認定テスト技術者資格 Foundation Level試験とは JSTQB認定テスト技術者資格 Foundation Level試験とは、 ソフトウェアテスト に関する基礎的な理解が問われる試験です。 ソフトウェアテスト 技術者の国際的な資格認定団体 International Software Testing Qualifications Board (ISTQB)の加盟組織である Japan Software Testing Qualifications Board (以下、 JSTQB )が主催している試験の一つであり、「Foundation Level」とあるとおり、 JSTQB認定テスト技術者資格 試験の中では最も基礎的な内容のレベルの試験となります。 実施形式としてはPBT形式とCBT形式の2種類があります。 PBT形式は指定会場に集合して試験を受験する形式であり、基本的に年2回程度開催されています。 一方、CBT形式は全国各地のテストセンターで試験を受験する形式であり、テストセンターの予約枠に空きがあればいつでも受験可能です。 受験のきっかけ きっかけは、 システム開発 案件にて、テストチームをサポートする役割を任されたことです。 私自身が直接テストを設計・実施する立場ではないものの、メンバーをサポートしていくためにはテストに対する一定の理解が必要であると考え、受験することを決定しました。 なお、新 シラバス 対応の試験予約が開始されたのは試験切り替え前日の2024年10月31日でした。 そのため、受験すること自体は決定していたものの、実際に試験を予約したのは試験前日でした。 何故 シラバス 切り替え直後のタイミングで受験したのか 試験範囲の変更直後は、当然ながら当該範囲の過去問題や出題傾向に基づく予想問題が存在しません。 そのため、資格の取得だけを主眼に置くのであれば、旧 シラバス を基に学習を重ね、10月までに試験を受験する方が、合格可能性は高かったかもしれません。 しかし、以下の理由から、私はこのタイミングでの受験を選択しました。 より新しい知識を習得する方が有用であると考えた(資格の取得よりも知識の習得に主眼を置いた)ため 新 シラバス で記述が増加したとされる アジャイル やDevOpsなどの要素が、私にとっては馴染みのあるものであったため 利用教材など 公式シラバス 学習初期と試験直前の計2回、目を通しました。 といっても、あくまで目を通しただけであり、熟読・精読したというほどではありません。 ソフトウェアテスト 教科書 JSTQB Foundation 第5版 シラバス 2023対応 ( アフィリエイト ではないですよの意味を込めて敢えてリンクは記載していませんが、検索すれば難なくヒットすると思います!笑) 私が学習を始めた時点では新 シラバス に対応している教材がおそらくこちらのテキストのみであったため、こちらを活用しました。 こちらも軽く一周した程度ですが、巻末にある模擬試験は、実際の試験問題の雰囲気を体感するために有用だったと感じています。 なお、弊社では、本資格取得のためのサポートとして、各自が選択した教材1冊を会社の経費で購入できます。 そのため、私も上記制度を利用して会社の経費で購入しました。 ソフトウェアテスト資格完全攻略 テス友 テス友とは、テスト技術者資格認定の勉強用アプリケーション/ Webサービス です。 「テスト技術者資格認定の勉強用」とあるとおり、本試験以外にも、JCSQEソフトウェア品質技術者資格認定やIT検証技術者認定試験にも対応しています。 1問1答形式の問題が10問ずつ(変更可能)出題され、1問解答するごとに解説が表示される、という形式であるため、スキマ時間で効率的に試験対策に取り組むことができました。 受験してみての所感 難易度について 難易度としては、やはりFoundation Levelということもあり、 基本情報技術者試験 や 応用情報技術者試験 の内容を理解できていればそれほど苦戦せずに合格できるレベルだと感じました。 具体的にどのような問題が出題されたかは紹介できませんが、先述のテキスト巻末の模擬試験と同等の形式および難易度でした。 設問について とても個人的な感想になってしまいますが、私が直近で受験・取得した資格が問題文が長く複雑なことで有名な AWS Certified Solutions Architect - Professional や AWS Certified DevOps Engineer - Professional であったこともあり、「問題文が短くて目も脳も疲れない…!」というのが第一印象でした。笑 新 シラバス で加筆された アジャイル やDevOpsなどの概念に関しては、関係する設問は何問か出題されたものの、それそのものがメインの設問はほとんどなかった印象です。 また、詳細を記載できないことが残念ですが、作問者の遊び心を感じるイマドキっぽい設問がとても印象に残っています。 自身への影響について 本資格について学習したことで、テストチームの仕事の進め方や大変さなどを理解できるようになり、テストチームの仕事(特に、欠陥レポートの記載、リーダーの方の振る舞い、など)の品質の高さを再認識できました。 それにより、私自身もテストチームをより親身にサポートできるようになった…かもしれません。 (親身かどうかは受け手側の感じ方次第なので「できるようになった」とは言えません…!) 総じて、本資格の受験は私にとっては有意義なものでした。 おわりに 本記事では、新 シラバス 準拠となった JSTQB認定テスト技術者資格 Foundation Level試験を受験してきた話をご紹介しました。 本記事公開時点では新 シラバス に関する記事はまだあまり多くないため、少しでもこれから資格取得を目指す方の参考になれば幸いです。 最後までお読みいただき、本当にありがとうございました! 私たちは同じ事業部で共に働いていただける仲間を募集しています! みなさまのご応募、お待ちしています! <電通×IT>電通グループ基幹システムプロジェクトマネージャー エンタープライズ向けDX推進リーダー/エンジニア◆電通グループ協業◆提案活動~開発・運用まで <電通×IT>クラウドアーキテクト <電通×IT>アプリケーションアーキテクト 製品・プラットフォーム開発エンジニア 執筆: @miyazawa.hibiki 、レビュー: @nagamatsu.yuji ( Shodo で執筆されました )
アバター
こんにちは。 電通 総研IT入社3年目の木ノ原です。 現在は第3ビジネスユニットに所属しており、金融機関向けソリューションである、 LINKGATEWAYというパッケージの開発・保守を担当しています。 この記事では、私のこれまでの仕事内容などについてお話しします。 1.自己紹介 私は2022年に新卒入社し、半年の研修を経て第3ビジネスユニットに配属となり、現在は3年目となります。 大学は情報学部 情報工学 科出身で、プログラミングなどについて学んでいました。 また、もともと金融関係のことにも興味があったこともあり、金融関係の仕事に携われる部署を希望したところ 希望通りでかつ、お客様と直接やり取りができる第3ビジネスユニットに配属となりました。 2.これまで行ったこと 【1年目】 4月から9月:新人だけの研修で、そこではビジネスマナーや Java などの研修を行いました。 10月以降:部署へ配属となり、そこで実際にプロジェクトへ参画する前に、 業務知識や C言語 などの研修を行いました。 ここで C言語 を学ぶ理由としては、私たちの部署で扱っているLINKGATEWAYが C言語 のため、 まず、先輩のサポートのもと C言語 を学びます。 【1年目以降】 実際にプロジェクトへ参画し、仕事を行いました。 参画したプロジェクトでは以下の図のように進めていき、 この中で私は要件定義工程以外の全ての工程に関わることができました。 次の項目では私が行ってきた仕事の内容についてお話しします。 3.仕事内容 【プロジェクト概要】 私は1年目の1月より、 UNIX から Linux へのシステム更改のプロジェクトに参画いたしました。 このプロジェクトの簡単な概要としては、OSの変更に伴うポーティングと 勘定系システムとの通信方式を変更するというものです。 以降では各工程で私がどのようなことを行ったか、お話しします。 【設計】 この工程では既存システムの更改ですので、新たな設計書を作成することはなく、 既存の設計書の修正を行います。 新規開発案件と違い、既存のシステムを更改するプロジェクトですので、何が変更になるのか、 それによって何をどう修正しなければならないのか、という事を考えながら行うことが重要になります。 【実装・ 単体テスト 】 この工程では設計工程で担当した機能のプログラム修正と、その機能のテストを行います。 実装は C言語 でプログラムの修正を行い、 単体テスト では自身でテスト仕様書を作成した後、 テストを行っていきます。ここで重要なのは修正したところが問題ないかを確認するだけでなく、 修正したことで他の場所に影響が出ていないかテストを行うことが重要です。 テストを行う際のテストデータの準備については、初めての経験でしたので、 先輩方のサポートを受けて、どのようにテストを行っていくか学びながら進めていきました。 【 結合テスト 】 この工程では内部(社内) 結合テスト と外部(社外) 結合テスト の2工程に分けて行います。 内部 結合テスト では、これまで社内で作成してきたものを結合して、システムが正しく動作するかを検証します。 ここで私は先輩と2人1組になってテストを行ったのですが、自分がこれまで担当してきた機能だけでなく システム全体として、どのような動きをするのか大まかにですが、理解しながら進めることができました。 また、先輩と2人1組になってテストを行ったことで、システムの理解だけでなく、 テストで必要なコマンドの知識や、ちょっとした豆知識なども教えてもらえました。 外部 結合テスト では、お客様とコミュニケーションを取りながら他システムとの連携が 問題なく動作できるかを確認・検証します。 ここで私は実際にお客様とコミュニケーションを取ることはありませんでしたが、 先輩方がどのようにコミュニケーションを取りながら進めているかを見聞きすることはできました。 【総合テスト】 この工程では性能テストや連続稼働テストなどを行い、 実際に運用していく中で問題はないかを確認・検証します。 この工程でも実際にお客様とコミュニケーションを取りながらテストを進めました。 テスト仕様書の作成も行ったのですが、ただ単にこのテストが必要という事だけでなく、 なぜこのテストをする必要があるか等の目的の部分についても教えてもらいながら、 作成を進めることができました。 4.これまでの業務経験から感じたこと 私はこれまで仕事を行ってきて、質問しやすい環境というのはとても大切だと感じました。 初めてプロジェクトに参画し、最初は右も左もわからない状態でしたが、先輩方にサポートしていただき、 質問に対しては優しく答えてくれるだけでなく、プラスαのことまで丁寧に教えてくれる人ばかりでした。 こうしたちょっとしたことでも聞きやすい環境というのは働きやすさにもつながりますし、 これから後輩が増えていく身としては、質問しやすい環境・雰囲気作りはとても重要だなと感じました。 5. 最後に ここまで私の仕事内容についてお話してきましたがいかがでしたか? 私たちの部署はLINKGATEWAYを扱い、たくさんのお客様とお仕事をしています。 そのため必要になる知識は多いですが、その分多くのことを学ぶことができます。 これからもこれを見てくださった皆さんと切磋琢磨していけたらと思います。 以下にLINKGATEWAYと採用ページへのリンクを貼っておきますので、興味を持った方はぜひ見てみてください。 ご覧いただきありがとうございました。 LINKGATEWAY https://www.dentsusoken.com/solution/linkgateway.html 採用ページ 執筆: @kinohara.kazuma 、レビュー: @yamashita.tsuyoshi ( Shodo で執筆されました )
アバター
みなさんこんにちは、 電通 総研コーポレート本部システム推進部の佐藤太一です。 設定管理は開発段階だけでなく、運用フェーズでも重要な課題です。MicroProfile Configを活用すれば、設定値の変更が及ぼす影響を最小限に抑えつつ、柔軟な設定管理が実現できます。 このブログエントリでは、MicroProfile Configの基本概念と使い方を初心者向けに解説します。アプリケーションの設定管理を効率化するための第一歩を踏み出しましょう。 はじめに MicroProfile Configの概要 MicroProfile Configを使う目的 アプリケーション開発環境 設定ソース 標準サポートの設定ソース カスタム設定ソースの作成 型変換 標準サポートの型変換 smallrye-config に実装済の型変換 自動的に行われる型変換 Enumを使う コンストラクタを使う ファクトリメソッドを使う まとめ はじめに まずは、MicroProfile Configの概要と利用目的について説明します。 MicroProfile Configの概要 MicroProfile Configは Jakarta EEのMicroProfileに含まれているライブラリです。 このライブラリは、アプリケーションの設定値を外部化し、一元管理するための仕組みを提供します。設定値を ソースコード から分離すると、アプリケーションの保守性や柔軟性が高まるでしょう。 標準で提供されている設定ソースは、 システムプロ パティ、プロパティファイル、 環境変数 です。ただ、設定ソースは柔軟に拡張できるので、データベースから値を取り出したり AWS AppConfigのような クラウド プロバイダー固有のサービスから値を取りだすような事も簡単にできます。 実は、MicroProfile Configは仕様だけが存在するものです。今回の説明に使うのは smallrye-config という Red Hat が実装しているライブラリです。 MicroProfile Configを使う目的 MicroProfile Configを使う理由は、いくつかあります。 まず、設定値の変更に伴う ソースコード の修正を最小限に抑えることで保守性を向上します。さらに、環境毎の設定切り替えが容易になるのでデプロイメントの柔軟性が高まるでしょう。 また、設定された値の型を検証したり、設定値を文字列からアプリケーションで利用する型に自動変換できるので設定ミスによる動作不良を最小限に抑えられます。 加えて、動的な設定変更が必要になるような高い可用性を要求するアプリケーションにも対応できます。 アプリケーション開発環境 具体的な ソースコード を交えた説明をするにあたって、アプリケーションのビルド環境を作りましょう。 エディタはどんなものでも構いませんが、Java21を使って Maven でプロジェクトを作成します。 プロジェクトのルート ディレクト リに配置する pom.xml は以下のような内容です。 <project xmlns = "http://maven.apache.org/POM/4.0.0" xmlns : xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi : schemaLocation = "http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd" > <modelVersion> 4.0.0 </modelVersion> <groupId> com.example </groupId> <artifactId> mp-config-example </artifactId> <version> 0.1.0 </version> <packaging> jar </packaging> <properties> <maven . compiler . source> 21 </maven . compiler . source> <maven . compiler . target> 21 </maven . compiler . target> <project . build . sourceEncoding> UTF-8 </project . build . sourceEncoding> </properties> <dependencies> <dependency> <groupId> io.smallrye.config </groupId> <artifactId> smallrye-config </artifactId> <version> 3.8.2 </version> </dependency> </dependencies> </project> プロジェクトのルート ディレクト リから src/main/java と ディレクト リを作成して ソースコード の格納 ディレクト リとします。 そのまま com/example/config とさらに ディレクト リを掘って、その中に Main.java というファイルで以下の内容を保存します。 package com.example.config; import org.eclipse.microprofile.config.ConfigProvider; public class Main { public static void main(String[] args) { var config = ConfigProvider.getConfig(); var name = config.getValue( "com.example.name" , String. class ); System.out.printf( "Hello, %s%n" , name); } } これが MicroProfile Config を利用する最小限のコードです。簡単ですね。 このまま動かすと com.example.name という設定値が必須項目となりますので、以下のようなエラーになります。 Exception in thread "main" java.util.NoSuchElementException: SRCFG00014: The config property com.example.name is required but it could not be found in any config source at io.smallrye.config.SmallRyeConfig.convertValue(SmallRyeConfig.java: 435 ) at io.smallrye.config.SmallRyeConfig.getValue(SmallRyeConfig.java: 380 ) at io.smallrye.config.SmallRyeConfig.getValue(SmallRyeConfig.java: 359 ) at com.example.config.Main.main(Main.java: 9 ) このエラーに対処するため システムプロ パティに -Dcom.example.name=John を設定してアプリケーションを起動してみましょう。以下のように出力されれば、正しく動作しています。 Hello, John システムプロ パティを起動時に設定するのはやめて、 環境変数 に COM_EXAMPLE_NAME=Alice を設定してからアプリケーションを起動してみましょう。以下のように出力されるはずです。 Hello, Alice これで、MicroProfile Config を使ったアプリケーションの基本的な動作確認は終わりです。非常に簡単ですね。 CDI を使った設定値の取得方法もあるのですが、今回は説明しません。気になる方は仕様を見てください。 参照先: Aggregate related properties into a CDI bean 設定ソース 開発環境をセットアップして設定値を取りだす方法が分かった所で、設定値を保持する仕組みについて説明します。 標準サポートの設定ソース MicroProfile Configが標準で提供している設定ソースを優先度順に並べると以下の3つです。 システムプロ パティ 環境変数 プロパティファイル 優先順位がどのように作用するか、具体的に考えてみましょう。 MicroProfile Configがデフォルトで読むプロパティファイルは META-INF/microprofile-config.properties です。 環境変数 や システムプロ パティに設定がなければ、このファイルに記述された内容が使われますので、ローカルマシンを使った開発ではプロパティファイルを使うのが便利でしょう。 IDE からmainメソッドのあるクラスを実行する際にパラメータを渡すのは、少しだけ面倒ですよね。 アプリケーションをデプロイするにあたってDockerコンテナにパッケージングするとしましょう。 コンテナ オーケストレーション ツールを使うとコンテナをデプロイする時に 環境変数 を追加したり、環境毎に値を切り替えたりするのは非常に簡単です。プロパティファイルに記載があるものをコンテナ起動時に置き換えられます。少し奇妙ですが、MicroProfile Configでは 環境変数 から値を読む際にはキー名の中に含まれる . (ドット)を _ (アンダースコア)に置き換え小文字は大文字に置き換えて処理をします。 例えば、 com.example.name を処理する際には、 環境変数 に COM_EXAMPLE_NAME が定義されている事を期待して処理を行います。 コンテナ オーケストレーション ツールを使っているなら、 環境変数 の置き換えで基本的には対応できるはずです。しかし、緊急避難的に特定のコンテナだけ少し違ったパラメータで動作させたいことは、障害時にはよくあります(障害自体は発生しないで欲しいものですが…)。こういう時にはコンテナの起動パラメータに システムプロ パティを設定することで、既存の設定を上書きできるのです。 なお、 システムプロ パティの値を使う際には、 環境変数 のようなドットからアンダースコアへの置き換えはありません。 カスタム設定ソースの作成 MicroProfile Configが標準で提供している設定ソースは全て静的なものです。つまり、設定値を変更した際に JVM やコンテナを再起動する必要があります。 コンテナを使ってデプロイしているアプリケーションが クラスタ 化されているなら、再起動することはそれほど難しくないでしょうが、様々な事情によって再起動できないアプリケーションは存在しますよね。 カスタム設定ソースを実装すると、こういう要件に対応できます。 この記事では、長くなり過ぎるので AWS のAppConfigをMicroProfile Configから利用するためのカスタムソースを実装する記事をご紹介します。 Implementing a custom ConfigSource in Quarkus using AWS AppConfig 型変換 設定ソースから取りだす際に、文字列としてだけ値を取りだすとアプリケーション内では、そのまま使えない事が多いでしょう。 ここでは、数値や日付として設定値を取りだす方法について説明します。 標準サポートの型変換 まずは、MicroProfile Configが標準でサポートしている型変換を確認してみましょう。 標準で全てのプリミティブ型がサポートされています。つまり、boolean、byte、short、int、long、float、double、charに設定値を自動変換できるのです。同じようにラッパー型であるBoolean、Byte、Short、Integer、Longなども使えます。 特に難しいことはありません、値を取りだす際の第二引数にクラス参照を渡すだけです。例えば以下のようなコードになりますね。 package com.example.config; import org.eclipse.microprofile.config.ConfigProvider; public class Main { public static void main(String[] args) { var config = ConfigProvider.getConfig(); var value = config.getValue( "com.example.intvalue" , int . class ); System.out.printf( "Value is %s%n" , value); } } 設定ソースに一切の値が設定されていない場合のデフォルト値を用意したいことがあります。 通常はOptional型でラップされたものを取りだすための getOptionalValue メソッドを使えばいいのですが、プリミティブ型の時だけは専用のOptional型を使うので少しトリッキーです。以下のようなコードになります。 package com.example.config; import java.util.OptionalInt; import org.eclipse.microprofile.config.ConfigProvider; public class Main { public static void main(String[] args) { var config = ConfigProvider.getConfig(); var value = config.getValue( "com.example.undefvalue" , OptionalInt. class ).orElse( 30 ); System.out.printf( "Value is %s%n" , value); } } 標準でサポートされている型変換としてはClassもあります。Classを指定して値を取りだす際に使われるクラスローダーはThreadから取得できるContextClassLoaderです。 カンマ区切りされた設定値をListや配列として取りだすこともできます。 以下のコードを システムプロ パティに -Dcom.example.listValue=3.1,5.2,4.4,6.8 と設定して実行してみましょう。設定値をカンマ区切りする際に余分なスペースを入れると期待通りに動作しませんので注意してください。 package com.example.config; import java.util.List; import org.eclipse.microprofile.config.ConfigProvider; public class Main { public static void main(String[] args) { var config = ConfigProvider.getConfig(); List<Float> value = config.getValues( "com.example.listValue" , Float. class ); System.out.println( "values are " + value); } } このコードで使われているのは、getValues s メソッドです。複数形のsが付いていますね。見逃し易いので注意してください。これを実行すると以下のように標準出力されるはずです。 values are [ 3.1 , 5.2 , 4.4 , 6.8 ] smallrye-config に 実装済 の型変換 数値型とClass型だけでは、少々不便です。MicroProfile Configの実装であるsmallrye-configには、よく使われる型の変換がいくつか実装されています。 追加でサポートされているクラスは以下のとおりです。 java .net.InetAddress IPv4 アドレスと IPv6 アドレスの両方を扱えます。 java .util.UUID java .util.Currency java .util.BitSet java .util. regex .Pattern java .nio.file.Path ローカルのファイルを扱いたいときに使います。 どれも非常に良く使うものばかりですよね。 自動的に行われる型変換 MicroProfile Configには規約に基づく自動的な型変換機能があります。自分達で定義した型を使いたいときには、この規約をうまく利用しましょう。 より高度なカスタムの型変換機能もありますが、あまり使わないので今回は紹介しません。 Enum を使う まずは、 Enum を使うケースを考えてみましょう。以下のような Enum を定義します。 package com.example.config; public enum Cats { Abyssinian, American_Shorthair, Bengal_Cat, Himalayan; } 普段使っているものと大きな差分はないでしょう。これを使うコードを見てみましょう。 package com.example.config; import org.eclipse.microprofile.config.ConfigProvider; public class Main { public static void main(String[] args) { var config = ConfigProvider.getConfig(); var value = config.getValue( "com.example.cat" , Cats. class ); System.out.println(value); } } このコードを動かす際には、 システムプロ パティとして -Dcom.example.cat=American-Shorthair を設定してください。実行結果として以下のように標準出力されるはずです。 American_Shorthair システムプロ パティとしては、ハイフンを使っていましたが、アンダースコアに読み替えた上で Enum のメンバが選択されていますね。 コンスト ラク タを使う 独自の型に型変換を行うなら引数の型として String もしくは CharSequence を受取るコンスト ラク タを定義するのが簡単です。 例えば、標準でサポートされている型の中には java.math.BigDecimal は含まれていませんが、Stringを引数に受け取るコンスト ラク タが定義されているので型の自動変換ができます。 ちょっと使ってみましょう。 package com.example.config; import java.math.BigDecimal; import org.eclipse.microprofile.config.ConfigProvider; public class Main { public static void main(String[] args) { var config = ConfigProvider.getConfig(); var value = config.getValue( "com.example.number" , BigDecimal. class ); System.out.println(value); } } このコードを動かす際には、 システムプロ パティとして -Dcom.example.number=3344.222 を設定してください。そうすると以下のように標準出力されるでしょう。 3344.222 興味深い振る舞いですよね。 ファクトリメソッドを使う 次はファクトリメソッドが自動的に使われるケースを見てみましょう。 MicroProfileでは public static なメソッドが定義されているとファクトリメソッドとして利用します。メソッド名として有効なのは of valueOf parse です。引数は一つであることを仮定しています。そして、引数の型として有効なのは String もしくは CharSequence です。 例えば、こういうコードになります。 package com.example.config; public class Dogs { String group; public static Dogs of(String value) { var d = new Dogs(); // 少し奇妙なコードだが確実にファクトリメソッドが動いていることが分かるようにコンストラクタを使わない d.group = value; return d; } @Override public String toString() { return "group: " + this .group; } } これを使うコードを見てみましょう。 package com.example.config; import org.eclipse.microprofile.config.ConfigProvider; public class Main { public static void main(String[] args) { var config = ConfigProvider.getConfig(); var value = config.getValue( "com.example.dog" , Dogs. class ); System.out.println(value); } } このコードを動かす際には、 システムプロ パティに -Dcom.example.dog=Hound を設定してみましょう。 実行結果として以下のように標準出力されるはずです。 group : Hound of メソッドがファクトリとして利用されていますね。 まとめ このエントリでは、MicroProfile Configを使った設定管理の方法について説明しました。 MicroProfile Configを使うと、設定値の変更が及ぼす影響を最小限に抑えつつ、柔軟な設定管理が実現できます。設定値を文字列から任意の型に自動変換できるので設定ミスによる深刻な動作不良を防げるでしょう。高い可用性を求められるアプリケーションでも設定ソースを作りこむことで対応できます。 規約に基づいてに実行される型変換では文字列を引数にとるコンスト ラク タやファクトリメソッドがあれば、それが使われます。独自の型を使いたい場合にも簡単に対応できます。 MicroProfile Configをうまく活用してアプリケーションの品質向上に役立ててください。 私たちは共に働いていただける仲間を募集しています! みなさまのご応募、お待ちしています! 株式会社 電通総研 新卒採用サイト 執筆: @sato.taichi ( Shodo で執筆されました )
アバター
XI本部 プロダクト イノベーション センター アジャイル 開発グループの徳山です。 前回の記事「 FlutterFlowでFirebaseと連携する方法 」では、FlutterFlowとFirebaseを活用したバックエンドのセットアップ方法を詳しく解説しました。今回は、FlutterFlowを使って開発できる 社内業務向け スマホ アプリ の作成方法を紹介します。これまで解説した内容を確認しながら、実際の アプリ開発 の流れをご覧ください。 はじめに どのようなアプリを作るのか アプリ概要 機能概要 アプリの作成 1. プロジェクトのセットアップ FlutterFlowプロジェクトの作成 データベースの設定 usersコレクションのスキーマ reportsコレクションのスキーマ セキュリティルール 2. 画面作成および機能の実装 ログイン/新規登録 営業報告一覧 営業報告作成 営業報告詳細 営業報告編集 3. テスト 4. ビルドおよびデプロイ 4. ビルドおよびデプロイ 1. Webアプリとしてのデプロイ 2. モバイルアプリ(iOS/Android)としてのデプロイ まとめ 参考資料 はじめに 本記事の目的は、FlutterFlowを利用して社内用の簡単な業務用アプリを短期間で開発する方法を紹介することです。FlutterFlowの利用を検討している方で業務アプリを素早く作りたいと考えている方に向けてステップ バイス テップの解説を提供します。 なお、細かいセットアップ方法についての解説は本記事では行いませんので前回の記事「 FlutterFlowでFirebaseと連携する方法 」を適宜ご参照ください。 また、本記事は2024年10月時点の情報に基づいたものとなります。 どのようなアプリを作るのか アプリ概要 今回作成するアプリは、 営業チーム向けの営業報告共有ツール です。営業チーム内で共有する業務情報を記録し、他のメンバーと共有することを目的としています。このアプリは 単一部署の複数人 が使用することを想定しています。 ミニアプリのため、実装する内容は下記の内容に絞りました。 機能概要 営業活動の報告入力 : 営業が外出先から直接活動内容を入力。 報告の共有 : 営業メンバー間で活動状況が即時に共有される。 進捗管理 : アプリ内で営業進捗を可視化し、確認できるようにする。 アプリの作成 ここからは実際にアプリを作成します。バックエンドは前回解説した Firebase を利用します。 大まかに下記の項目に分けて解説を行います。 プロジェクトのセットアップ 画面作成および機能の実装 テストとデプロイ 1. プロジェクトのセットアップ FlutterFlowプロジェクトの作成 「Quick Report」というアプリ名で新規プロジェクトを作成します。 スマートでクールという印象を与えるため、Themeは「Sleek&Cool」を選択しました。 FlutterFlowからFirebaseのプロジェクトを新規作成し、Auth, Storageも利用できるように有効化しておきます。 Enable Authentication , Create User Collection のトグルをONにしておくことで、ユーザーコレクションの作成とユーザーのログインを自動で設定できます。 また、ログイン状態によって初期表示するページも設定できるため、それぞれ下記を設定しました。 ログイン前 :Signin ページ(FlutterFlowで用意されているテンプレートを利用) ログイン後 :ReportList ページ(空のページを利用) データベースの設定 今回は以下の2つのコレクションを用意します。 users :営業担当者の情報を記録するためのコレクション reports :レポートデータを記録するためのコレクション それぞれの スキーマ は下記となります。 users コレクションの スキーマ FlutterFlowで用意されているユーザー用の定義をそのまま利用しています。 reports コレクションの スキーマ 企業名(company_name)、営業活動の詳細(activity_details)、備考(remarks)、ステータス(status)、作成者の情報(user_id)を管理できるように設計しています。 セキュリティルール users コレクションと reports コレクションに読み書きのアクセス制限を設定します。 users コレクションは、作成は誰でも可能で、それ以外の操作はログインユーザーである本人のみ可能となるように設定します。 reports コレクションは、作成と読み取りはログインユーザーであれば可能で、上書きと削除は作成者のみ可能となるように設定します。 2. 画面作成および機能の実装 次に、アプリの画面を設計します。今回作成する画面設計は下記のとおりです。 画面名 機能 ログイン/新規登録 ユーザーのログインと新規登録を行う 営業報告一覧 営業担当者が登録した営業報告の一覧を表示する 営業報告作成 新しい営業報告を登録する 営業報告詳細 営業報告の詳細を表示する 営業報告編集/削除 既存の営業報告を編集または削除する ログイン/新規登録 FlutterFlowで用意されているテンプレートを活用して作成します。追加したユーザーの名前や電話番号は標準ではusersコレクションに保存されないため、保存する設定をアクションから追加します。 営業報告一覧 営業報告の一覧と報告の作成ができるボタンを配置しています。 一覧の表示は「ListView」 ウィジェット が用意されており、この ウィジェット にデータを渡すことで簡単に作成できます。 今回は reports コレクションのデータを取得してListViewに渡しています。 また、ヘッ ダーナ ビゲーションにユーザーアイコンを設置し、ログアウトができるようにしています。FlutterFlowではログアウトや確認用のダイアログのアクションが用意されているので簡単にログアウトのワークフローを実装できます。 実際に作成した報告の一覧画面は以下のようになります。 営業報告作成 「作成する」ボタンをクリックすることで、営業報告の作成ページに遷移できます。 ステータスは「choice chips」 ウィジェット を利用しています。単一選択と複数選択の両方に対応したオプション選択用の ウィジェット で初期値の設定や Enum (列挙型)のデータ型を利用した選択肢の作成も可能です。 また、フォームの入力内容をチェックするバリデーションも「Form Validation」 ウィジェット を利用することで簡単に設定ができます。文字の長さや入力形式など個別でエラーメッセージも設定が可能です。 「作成する」ボタンをクリックすると下図のようにバリデーションが効いていることを確認できます。 最後は、報告作成時のアクションワークフローを設定します。条件分岐や画面遷移、スナックバーによるメッセージの表示などFlutterFlowでは多くのアクションが標準で用意されているため複雑なワークフローも組むことが可能です。 <報告の作成フロー> フォームの入力内容のチェック Firestoreへのデータの保存 保存が成功したかをチェック 報告一覧ページへの遷移 保存が成功したメッセージの表示 営業報告詳細 営業報告一覧画面から任意の報告を選択したときに詳細画面に遷移するようにします。各報告を表示するContainerの ウィジェット に遷移するためのアクションを設定し、その際に選択した報告のデータ(ドキュメント)を渡すように設定します。詳細画面側ではこの設定を受け取ることで報告の情報を表示できます。 報告詳細画面は下図のとおりです。 FlutterFlowでは「Page State」という機能があり、ページ内で共通の値をセットして利用できる仕組みがあります。担当者の名前は users コレクションからデータを取得する必要があり、この情報は削除や編集ボタンの表示の判定にも使えるので、Page State機能を使って管理します。この機能は右のプロパティパネルから利用ができます。今回はuserのデータが欲しいので salesPerson という名前でuserドキュメント型の定義を行います。 あとは、画面ロード時に salesPerson の値に報告書の作成者をセットするワークフローを組むことで、ページ内で利用することが可能になります。 1. 報告書の user_id のフィールドと一致する users のデータを取得 2. 取得したユーザーのデータを salesPerson にセット これで無事、報告の詳細に必要な情報を全て取得できました。実際の画面は下図となります。 ログインしているユーザーが報告の作成者ではない場合、ボタンの表示がされないように表示の制御をしています。 これはプロパティパネルの Visibility でロジックを設定することで制御ができます。 削除の処理は、報告の作成の時と同様、「Create Document」というアクションの代わりに「Delete Document」を使うことで簡単に実装できます。 営業報告編集 最後に、報告の編集を行うページを作成します。といっても先ほど作成した作成画面とUIもロジックもほとんど同じです。編集画面に必要なデータは、詳細画面に遷移する際にデータを渡したように編集ページに遷移する時も詳細画面のデータを渡すことで取得ができます。ロジックも作成や削除の時とほぼ共通で、「Create Document」の代わりに「Update Document」を利用するだけです。 最後に、ここまで作成した画面一覧と遷移は下図に示します。 サイドメニューから Storyboard を開くことで、アプリの全体像を一目で把握できます。 3. テスト ブラウザではヘッダーメニューから 「プレビューモード」 または 「Run モード」 を使い、アプリの挙動を確認できます。 プレビューモードはロジックが反映されず見た目だけの確認ができます。Runモードは、実データや遷移など本番と同等の挙動の確認ができるといった違いがあります。Runモードはビルドに時間がかかりますが、ロジックを含めた確認ができ、 デバッグ 機能も利用できます。 確認したい範囲に応じてそれぞれのモードを使い分けましょう。 4. ビルドおよびデプロイ 以下に、 「4. ビルドおよびデプロイ」 セクションの不足している内容を補完して書き上げました。 4. ビルドおよびデプロイ FlutterFlowでは、アプリを開発した後に、さまざまな方法でビルドおよびデプロイが可能です。具体的には以下のデプロイ方法があります。手順はドキュメントに詳細が記載されていますので、必要に応じて FlutterFlow Publishing をご確認ください。 1. Webアプリとしてのデプロイ FlutterFlowで作成したアプリを Webアプリ としてデプロイする方法です。これにより、アプリをURL経由でアクセスできるWebアプリとして公開でき、ブラウザから利用できます。 2. モバイルアプリ( iOS / Android )としてのデプロイ 開発したアプリを iOS および Android 向けにビルドして、それぞれのアプリストア( App Store , Google Play )で公開できます。FlutterFlowはFlutterベースのため、1つのコードベースで クロスプラットフォーム のアプリを作成でき、アプリストアでの配信に対応しています。 iOS アプリ : Apple Developer Programへの登録や証明書の取得が必要です。 Android アプリ : Google Play Consoleを通じてAPKまたはAABファイルをアップロードして公開します。 まとめ 架空の営業報告共有アプリを題材にFlutterFlowで社内業務向け スマホ アプリの作成手順を紹介しました。手順や設定が煩雑に感じる方もいらっしゃると思いますが、慣れれば2〜3時間程度でこのレベルのアプリを作成できます。 今回の記事がFlutterFlowでアプリを作成してみたい方やどのようなアプリを作ることができるのかを知りたい方のお役に立てば幸いです。FlutterFlowについてより知りたい方は、公式ドキュメントや私の過去の記事も参考にしていただけると嬉しいです。 参考資料 FlutterFlow ドキュメント Firebase ドキュメント 私たちは共に働いていただける仲間を募集しています! みなさまのご応募、お待ちしています! 株式会社 電通総研 新卒採用サイト 執筆: @tokuyama.raido 、レビュー: @handa.kenta ( Shodo で執筆されました )
アバター
始めまして。 電通 総研ITに6年間在籍する小椋と申します。 今回は、入社してから今までの業務を振り返りつつ、記事にいたしました。 弊社を知りたいと考えている皆様のお役に立てると幸いです。 経歴 まずは私の今までの経歴を簡単に紹介したいと思います。 2019年3月 大学卒 2019年4月 電通 総研ITへ新卒入社 4月~6月末 電通 総研グループ研修を受講 7月~9月末 電通 総研IT社研修を受講 10月~2020年3月末 現場配属後、現場にて OJT 研修を受講 2020年4月~現在 複数社が利用する社内基幹システムの開発案件に従事 上記の通り、入社後の研修以降、ずっと1つの大型案件に従事してきました。 入社当時は社会人一年目であるため、数多くの不安がありましたが充実した研修と頼れる上司・先輩社員の助けもあり、 6年目社員として成長し続けてこれたと自負しております。 業務内容(参画している開発案件) 複数社が共通で利用する社内基幹システムの開発です。 このプロジェクトは様々な会社が利用する事を想定しているため、いくつかのフェーズを設け段階的に開発を進めてきました。 執筆時点(2024/9)で、既に数社にてシステム利用が開始されているため保守を担当しつつ、その他の会社への導入に向けた作業を進めております。 このプロジェクトの難しいところはまさに”複数の会社が利用する社内基幹システム”であることです。 今までは各社がそれぞれ独自の社内基幹システムを利用してきましたが、それらを共通のシステム利用に切り替えるため、 各社のニーズを取り入れつつ、統一的なシステムを構築していく必要があります。 そのため、各会社・各部署の方々との密なコミュニケーションが必要不可欠でした。 そのコミュニケーションは各社展開を実施している現在も続いており、不足している機能を補う追加開発も行っております。 開発業務に関して 前述した通り、本システムは複数のフェーズを設けた上で開発を進めてまいりました。 各フェーズの内容は以下のとおりとなります。 フェーズ1:リリースターゲットを数社に絞り開発を実施。 フェーズ2-3:フェーズ1で発生した問題点を解決しつつシステムを新たに構築し、 フェーズ1でターゲットとした会社に公開。保守を行いつつその他の各社へ展開。 現在はフェーズ2-3の"その他の各社へ展開"する作業が続いている状況です。 この案件の開発には特徴がいくつかありますが、Vue、TypeScript、SpringBootを利用した案件である事が特徴の一つとして挙げられます。 特にVueは数年前から JavaScript の フレームワーク として様々な案件で利用されることが増えました。 Vueを利用する利点として挙げられる点は以下のようなものがあります。 画面表示されているデータのリアルタイム更新に優れ、ユーザの操作に応じたUI表現が可能。 開発者の目線から見ても オブジェクト指向 に基づいた設計が容易で、 コンポーネント (部品)を作成する事でスムーズな開発が可能。  (興味がわいた方がいらっしゃいましたら、Vueに関して是非調べてみてください!) 他の特徴としましては、オフショア開発を実施していることも挙げられます。 そのため、上流の工程である設計工程をメインに業務を行い、プロジェクト進捗に関わる様々な経験を積むことが可能です。 デメリットとして、コーディング作業をオフショア側に委託しているため、技術的なスキルの向上機会が少ない事が挙げられます。 ただし、実装をオフショア側へ効率的に依頼する事で、「コードレビューの時間を多くする」・「自習の時間を作る」時間を増やし技術力の向上を図る事が可能です。 では効率的な依頼を実施するには、どのようにしていけば良いでしょうか。 私がこれまでの経験で特に重要視しているのは以下の2点です。 正確な情報を伝えること 日本側の役割・オフショア側の役割を明確にすること "正確な情報を伝えること"のために、正確な文章で記載する事も重要です。 今回のオフショア開発ではやり取りを行う際に日本語でコミュニケーションをとる事が出来たため、 言語の壁はあまり感じることなく作業することができました。 ですが、正確な日本語で正確な情報を伝えることをより意識しなければならない現場でもありました。 不正確な文章はそのまま実装側との認識齟齬を生んでしまうためです。 これは日本国内で設計・実装を行う際でも注意しなければならない基本スキルですが、本開発案件ではより注意が必要だったため、その重要性を実感しました。 ※"正確な文章の作成"に関してはAIに文章校正を実施してもらうなど様々な手段が出てきましたので、 これらのツールを活用し、作業の効率化を図っていきたいと思っております。 "日本側の役割・オフショア側の役割を明確にすること"はこの先PMなどを目指すためにも 必要な能力であると感じております。 どの業種でも当てはまる事ではありますが、仕事をチームで進めていくと、 各個人間には必ずといってもいいほど摩擦が発生してしまうものです。 お互いの役割を明確にしながら、円滑にプロジェクトを遂行する事は この摩擦の発生を抑えるために不可欠な要素であると言えます。 また、発生した問題をチームで協力して解決していくことも大切です。 オフショアとのコミュニケーションは上記のような基本ではあれど重要な要素は何なのかを私に経験させてくれました。 その他の働き方に関して 私が参画したプロジェクトは年単位での開発期間を要する大規模なプロジェクトです。 そのため、コロナ渦の影響も大きく受けた案件となります。 その最たるものがリモートワークの導入でした。 リモートワークの導入に伴い、大きく変化したのがコミュニケーションの在り方です。 例えばTeamsを利用した「ビデオ会議」や「チャットベース」での作業進行が挙げられます。 この方法での作業進行は、相談相手の作業状況が分かり辛く、相互理解を深める上で課題が発生しました。 しかし、徐々に適応し、効率的な情報共有やコミュニケーション方法を各々が習得する事で解決しました。 私の場合、相手がどんな作業を今持っているのかを適宜把握する力が特に伸びたと感じております。 この力は現場での幅広い視野を持つことにもつながり、チームメンバー間の円滑なコミュニケーションを とるための力として、今後も大いに役立つものだと感じております。 最後に 今回は私が従事する案件の内容や現在の働き方等に関してご紹介いたしました。 多くの事を書かせていただきましたが、結論として私が本記事で最もお伝えしたかった事は"コミュニケーションの重要性"であり、弊社ではそれらコミュニケーションスキルを学ぶ機会があるという事です。 今回記事にいたしました内容はもちろん一例です。 他の方(後輩・同期・先輩)はそれぞれ異なる事を多く経験し、それによって重要視している内容が異なる方ももちろんいらっしゃいます。 そのため、私以外にも同様に弊社の働き方などを記事にしている方もいらっしゃいますので、お時間があればそちらもぜひご覧ください! 以上、この記事が読んでくださった皆様の不安解消などの一助となれば幸いです。 採用ページ 執筆: @ogura.ren 、レビュー: @yamada.y ( Shodo で執筆されました )
アバター
XI本部 プロダクト イノベーション センター アジャイル 開発グループの徳山です。 前回の記事「 FlutterFlowに制約はある?できることとできないこと 」では、FlutterFlowを使った開発における制約や注意すべきポイントをお伝えしました。今回は、FlutterFlowと相性の良いバックエンドサービスであるFirebaseとの連携について詳しく説明いたします。 はじめに Firebaseとは何か FlutterFlowの接続先について 1. 標準でサポートされているバックエンド(FirebaseやSupabase) 2. API Connector Firebaseとの接続方法(環境構築手順) 事前準備 1. FlutterFlowのプロジェクト作成画面を立ち上げる 2. Firebaseのプロジェクトを作成 FlutterFlowからFirebaseのプロジェクトを作成する場合 FlutterFlowを既存のFirebaseと連携する場合 3. FlutterFlowのプロジェクトの作成 Firebase サービスとの連携 事前準備 認証(Firebase Authentication)について データベース(Firestore Database)について ストレージ(Cloud Storage)について 使用例 コレクションの準備 認証用ページ 認証用ページ タスク一覧ページ タスク登録ページ 動作確認 Supabaseとの違い まとめ 参考資料 はじめに 本記事の目的は、Firebaseの基礎やFlutterFlowと連携する際の基本的な手順を紹介し、初めてノーコード開発やローコード開発に取り組む方やビジネスマンの方に役立つ情報を提供することです。Firebaseを使うことでモバイル アプリ開発 のバックエンド部分を簡略化し、効率的にプロトタイプから本格的なサービス開発へと進むことができます。 FlutterFlowの基本的な知識については、記事「 FlutterFlowとは?ノーコードでスマホアプリ開発を始める方法 」や「 FlutterFlowに制約はある?できることとできないこと 」をご参照ください。 また、本記事は2024年10月時点の情報に基づいたものとなります。 Firebaseとは何か Firebaseは、 Google が提供するBaaS(Backend as a Service)であり、バックエンドの機能開発を簡素化するための多くの機能を提供しています。主な機能には次のものがあります。 Firebase Authentication : パスワード認証や多要素認証といったユーザー認証を簡単に実装できます。例えば、アプリに「 Google でサインイン」ボタンを設置するだけで、ユーザーは Google アカウントで簡単にログインできるようになります。 Firestore Database : 高速で拡張性のあるNoSQLデータベースです。データをリアルタイムで同期できます。例えば、「チャットアプリ」のように、複数のユーザー間でリアルタイムにメッセージを送受信する場合などにも利用できます。 Cloud Storage : 画像や動画などのファイルの保存に適した クラウド ストレージです。たとえば、 プロフィール画像 のアップロード機能などに利用できます。 FlutterFlowはこれらのFirebaseサービスを簡単に活用できるように設計されています。バックエンドの実装が簡素化できるのでFlutterFlowでの機能開発に集中できます。 FlutterFlowの接続先について 先述の通り、FlutterFlowでデータを管理するためには バックエンドとの接続 が非常に重要です。FlutterFlowが提供するバックエンドの接続先としては、主に以下の2つがあります。 1. 標準でサポートされているバックエンド(FirebaseやSupabase) FlutterFlowは、デフォルトでFirebaseやSupabaseとシームレスに連携できます。Supabaseは比較的新しいサービスで内容も魅力的なのですが、FlutterFlowではFirebase連携の方がより早く機能追加される傾向にあるため、ここではFirebaseを用います。 2. API Connector [初心者の方にも分かりやすいように API でデータを取得する簡略図を作成してここに貼る] 標準のFirebase/Supabaseバックエンド以外のサービスを使いたい場合、FlutterFlowの API Connector 機能を使用することで、 REST API を介して他のバックエンドサービスと連携できます。これにより、Firebase以外の独自バックエンドや他のパブリック API (分かりやすいものだと住所や天気、株価などを取得できる API )と連携が可能になります。 Firebaseとの接続方法(環境構築手順) FlutterFlowでFirebaseと連携するためには、いくつかの設定を行う必要があります。英語の見慣れない画面に難しく感じる方もいるかもしれませんが 公式のドキュメント にもしっかり記載されているのでそちらも合わせてご参照ください。 事前準備 Firebaseを利用するにあたり、 Google アカウントが必要となります。アカウントを作成していない場合は、事前に作成しておいてください。 1. FlutterFlowのプロジェクト作成画面を立ち上げる まずは、FlutterFlowにログイン後に「Create Project」よりプロジェクトを作成します。 するとステップ1の画面が表示されるので Setup Firebase のトグルがオンになっていることを確認します。確認後、「Next Step」で次の画面に進みます。 2. Firebaseのプロジェクトを作成 ステップ2の画面では、実際にFirebaseのセットアップを行います。 ここでは、FlutterFlowからFirebaseプロジェクトを新規作成する場合と、FlutterFlowを既存のFirebaseと連携する場合に分けて解説します。 FlutterFlowからFirebaseのプロジェクトを作成する場合 「Create Project」ボタンからFirebaseのプロジェクト設定モーダルを開き、Firebaseで作成するプロジェクト名やリージョンを選択します。指定がなければプロジェクト名はそのまま、リージョンは asia-northeast1(Tokyo) を選択します。 Google アカウントにサインインすることで、FlutterFlowにFirebaseプロジェクトへアクセスや操作する権限が付与され、自動的にFirebaseのプロジェクト作成が開始されます。 作成が完了すると、下図の表示となります。 FlutterFlowを既存のFirebaseと連携する場合 既存のFirebaseプロジェクトの プロジェクトID を入力する必要があるため、まずは連携したいFirebaseプロジェクトの管理コンソールからプロジェクトIDを取得します。FlutterFlowに戻り、取得したIDを入力して「Connect」をクリックします。すると、下記のようなエラーが表示されます。 これはFlutterFlowにFirebaseプロジェクトへのアクセスや操作の権限が与えられていないためです。そのため、既存のプロジェクトと連携する場合はFirebase管理コンソールからFlutterFlowに必要なアクセス権限を追加する必要があります。 下図のようにFirebase管理コンソールから「ユーザーと権限」タブに移動し、「メンバーの追加」ボタンをクリックします。 メールアドレスに firebase@flutterflow.io を入力し、役割は「編集者」を選択します。 設定後、「メンバーを追加」をクリックするとFirebaseのアカウントが追加されたことを確認できます。 FlutterFlowのセットアップ画面に戻り、再度「Connect」をクリックします。すると連携が成功します。 連携は成功しましたが、FirebaseのCloud Functionsという機能を使う場合は firebase@flutterflow.io に以下の2つのロールを追加します。 サービス アカウント ユーザー Cloud Functions 管理者 Cloud Functionsはイベントに対して特定の処理を実行できる機能です。例えば、「ユーザーがログインした際に自動で通知を送る機能を実装したい」場合はCloud Functionsを使用するために設定が必要になります。 追加するには、先ほどのFirebase管理コンソールの「ユーザーと権限」の右下にある「権限に関する詳細設定」のリンクをクリックして Google Cloud の管理画面に移動します。 firebase@flutterflow.io の右に表示されている鉛筆アイコンをクリックし、「別のロールの追加」から サービス アカウント ユーザー と Cloud Functions 管理者 を追加して保存します。 下図のようにロールが変更されていれば完了です。 3. FlutterFlowのプロジェクトの作成 最後に「Start Building」ボタンをクリックして完了です。これでFlutterFlowとFirebaseのプロジェクトの作成と連携が完了です。 実際にはFirebaseの各種サービス(認証やストレージ、データベースなど)を利用するにはFlutterFlowとFirebaseでさらに追加の設定が必要となります。詳細なステップについては、FlutterFlowの公式ドキュメントや FlutterFlow公式 YouTube動画 をご確認ください。 Firebase サービスとの連携 続いて、Firebaseの認証やデータベース、ストレージとの連携についても解説します。すでにFlutterFlowとFirebaseの接続と権限設定が済んでいるため簡単に連携が可能です。 事前準備 Firebaseのサービス(Firebase Authentication, Firestore Database , Cloud Storage)を使うための設定を行います。 FlutterFlowのFirebaseの設定画面を開き、プロジェクトIDの入力欄下にある「Generate Config Files」をクリックします。 これでFlutterFlowからFirebaseのサービスと連携するための準備が完了しました。 認証(Firebase Authentication)について 下図のAuthenticationのページから「Enable Authentication」トグルをオンにして認証を有効にします。 続いてFirebaseの設定画面を開き、「Enable Auth On Firebase」をクリックします。 すると、Firebase Authenticationの管理コンソール画面が開くので「始める」をクリックします。 「ログイン方法」タブ →「ネイティブのプロバイダ」→「メール/パスワード」を選択します。 続いて、メール/パスワードの「有効にする」トグルをオンにして保存します。 これで、FlutterFlowのプロジェクト内でメール/パスワードによる認証が使えるようになりました。 データベース(Firestore Database)について FlutterFlowのサイドメニューからFirestoreを選択肢、「+」ボタンをクリックします。 コレクションの入力モーダルが表示されるので、ユーザー情報用のコレクションを作成するため users と入力し、「Create」をクリックします。 FlutterFlowで用意しているユーザー用の設定を使うか確認されますが、設定の流れを確認するために「No, Thanks」を選択します。 users コレクションが正常に作成されました。 次に、どのようなデータ(ユーザーの名前やメールアドレスなど)を扱うかを設定できるフィールドを設定します。 FlutterFlowでは自分で必要なフィールドを1つずつ設定することはもちろん、AIの力を借りることやFlutterFlowで用意しているデフォルトの定義を利用することもできます。 今回はFlutterFlowの用意しているユーザー用の定義を利用します。 選択後、用意されていたフィールドが反映された users コレクションを確認できます。 次に、 誰がどのような権限 で users コレクションにアクセスできるのかを設定しましょう。 下図の設定ページへのリンクをクリックし、Firestoreの設定画面に移動します。 ここでは作成したコレクションへのアクセス権限の設定を行うことができます。作成するアプリの要件に応じて適切に設定してください。操作ごとにアクセス対象範囲は下記の4つが選択できます。 No One :誰もその操作を行うことができません。 Tagged Users : 指定したフィールド(nameやemailなど)にデータが登録されているユーザーだけ操作を行うことができます。 Authenticated Users : ログインしているユーザーのみ操作を行うことができます。 Everyone : 誰でも操作を行うことができます。 設定ができたら「Deploy」をクリックします。 設定するアクセス権限のルールが表示されますので、問題なければ「Deploy Now」をクリックします。 これでFirestore Databaseを利用できるようになりました。 ストレージ(Cloud Storage)について ストレージはファイルアップロード機能などを利用する場合のみ設定を行います。 まず、認証と同様にFlutterFlowのFirebaseの設定画面を開いて「Enable Storage On Firebase」をクリックします。 Cloud Storageの管理コンソール画面が開くので「始める」をクリックします。 「テストモードで開始する」を選択して「次へ」をクリックします。 リージョンの選択画面に移りますが、Firebaseのプロジェクトのリージョンが選択されているので「完了」をクリックします。 これでCloud Storageも利用できるようになりました。 使用例 ここではFirebase AuthenticationとFirestore Databaseの実際の使用例について解説します。 以下のページを作成して、簡易的なユーザーの新規登録機能とタスクの登録機能を実装します。 認証用ページ :新規登録、ログイン用のページ タスク一覧ページ :ログイン後に表示されるページ。登録したタスクの一覧を表示します。 タスク登録ページ :タスクを新規登録するためのページです。 コレクションの準備 ユーザー( users )とタスク( todos )のデータを管理するために2つのコレクションを作成します。 users はFlutterFlowで用意されているユーザー登録用のコレクションを利用します。 todos は「タスク名、ログインしているユーザーの情報、作成日時」を取得できるように設定します。 認証用ページ FlutterFlowでは便利なページテンプレートが用意されているためそちらを利用します。 認証用ページ 「Auth」の中から任意のものを選択して認証用のページを追加します。 テンプレート内ですでにログイン用のアクションが設定されているので、簡単に認証機能を実装できます。 テンプレートを利用すると、すでに認証に必要なアクションが設定されているため認証ページを簡単に作成できます。 タスク一覧ページ タスク一覧ページは空のページを作成します。ログインしたユーザーのメールアドレスを確認するための Text ウィジェット と登録したタスクの一覧を表示するための ListView ウィジェット を配置します。右上には、タスク登録ページへ遷移するための「+」アイコンを IconButton ウィジェット で配置します。 Text ウィジェット には、ログインしたユーザーのメールアドレス情報がテキストに反映されるように設定します。 ここに表示されるオプションは、先ほど作成した users コレクションに基づいています。 ListView ウィジェット には、 todos コレクションの情報が反映されるように設定します。 タスク登録ページ タスクを登録するためのページを作成します。タスクを入力するための InputField ウィジェット 、入力内容をチェックするための Form ウィジェット 、入力されたタスクを todos コレクションに登録するための Button ウィジェット を配置しているだけのシンプルなページです。 最後に、初期表示されるページとログイン後のページを設定しておきます。 動作確認 では、テストモードでアプリを起動して動作確認をしてみましょう。 テストモードは右上のアイコンから起動できます。 新規登録のフォームに必要事項を入力します。 「登録する」をクリックすると、タスク一覧ページに遷移します。登録したメールアドレスも反映されています。 右上の「+」アイコンよりタスク一覧ページへ遷移し、タスクを入力します。 「登録する」ボタンをクリックすると、タスク一覧ページへ遷移し、入力したタスクが表示されていることを確認できます。 Firestoreにデータが登録されているか確認してみましょう。 「Manage Content」よりFirestoreに登録されているデータを確認できます。 ユーザーのデータは下図のように表示されています。 タスクのデータは下図のように表示されています。 以上でFirebase AuthenticationとFirestore Databaseを利用できていることが確認できました。 Supabaseとの違い Firebaseの他に、SupabaseというBaaSサービスとFlutterFlowは連携が可能です。どちらも優れたバックエンド機能を有するサービスですが、FlutterFlow上では扱いが少し異なります。 Firebaseに関しては、画像やデータの追加、データへのアクセス設定などFirebaseの各種サービスをFlutterFlowのメニューから直接操作できます。 一方、Supabaseの場合はテーブル定義のみFlutterFlowで閲覧できるなど参照できる情報が限定的です。FlutterFlowと連携して扱うことができる機能に両者で大きく差はないものの、開発経験があまりない方はFirebaseで開発を始めることをおすすめします。 まとめ 今回は、FlutterFlowとFirebaseを連携する方法について、Firebaseの特徴から連携方法、Supabaseとの違いを解説しました。Firebaseを活用することでFlutterFlowでの開発を効率化し、認証やデータ管理の手間を省くことが可能です 次回は、FlutterFlowとFirebaseを利用した簡単な社内業務アプリを作成します。ここまで解説した内容を踏まえた記事となりますので、まだ読まれていない方はぜひ下記の記事も閲覧していただければ幸いです。 FlutterFlowとは?ノーコードでスマホアプリ開発を始める方法 FlutterFlow vs Adalo:ノーコードモバイルアプリ開発ツールの比較 FlutterFlowに制約はある?できることとできないこと 参考資料 FlutterFlow ドキュメント Firebase ドキュメント Supabase ドキュメント 私たちは共に働いていただける仲間を募集しています! みなさまのご応募、お待ちしています! 株式会社 電通総研 新卒採用サイト 執筆: @tokuyama.raido 、レビュー: @nagamatsu.yuji ( Shodo で執筆されました )
アバター