Photoruction工事中!

Photoructionの開発ブログです!

Photoruction Labo Demo Dayの様子~1年間の集大成~

BPOチームでエンジニアをやってますkazuです🦌

2024年4月からスタートした開発イベント「Photoruction Labo」。チームや個人の関係性を深めることを目的に、8名のメンバーが集まり、各チームに分かれて開発を進めてきました。気づけば、あっという間の1年。本記事では、その1年間の集大成となる様子をお届けします✨

これまでのLaboの内容については、こちらをご覧ください↓↓↓

kojichu.photoruction.com

kojichu.photoruction.com

kojichu.photoruction.com

kojichu.photoruction.com

kojichu.photoruction.com

※ここに、これまでのLaboの記事

Demo Dayを開催した理由

各チームは、「新しい技術を学びたい」「業務をもっと効率化したい」「社内の人とのつながりを深めたい」など、それぞれの想いを胸に、1年間プロダクト作りに全力で取り組んできました。

みなさんの頑張りをどうせなら社内の皆さんにも見てもらいたい。そして、Laboの活動を通じて得た学びや成果を共有したい。そんな想いから、今回のイベント「Demo Day」を企画することにしました。

Photoruction Labo Demo Day

当日は、運営の挨拶から始まり、これまでのやってきたことを振り返りながら、各チームどんな開発を行なってきたかを説明して、デモの時間を作りました。

運営からの挨拶

まずは、運営メンバーであるCREリーダーのよしきさんから挨拶👏

開発合宿として淡路島にいったり、シェアオフィスを借りてお寿司を食べたりしてるチームもありました🍣

最終的に20人ほどいました😳

各チームの紹介

各チームが開発してたプロダクトはこんな感じです!

day1チーム

VRを用いてオフィスを再現したプロダクト

fracchi

モバイルを活用した日記アプリ

シヨウワカール

Photoructionのプロダクトに関する仕様を回答するAIチャットbot など

各メンバーに「大変だったことは?」と聞いてみたところ、やはり多くの声が挙がったのは「本業との時間のやりくり」でした。

普段の業務では、プロダクトオーナー(PO)があらかじめ「何を・どこまでやるか」を決めてくれます。しかしLaboでは、自分たち自身がPOであり、同時にエンジニアでもあります。そのため、限られた時間の中で「何をやるか」「何をやらないか」を自ら判断する必要があり、こうした体験ができるのもLaboの醍醐味ではないかと思います✨

Demoの時間

day1

day1チームは、VRを用いてオフィスを再現しました🏢

実際の様子はこちら↓↓↓

UnityもBlenderも、Webエンジニアにとって縁のない代物でこれの扱いがとても難しい😭

そして直角のものを再現するのは比較的簡単ですが、曲線を再現するのが難しかった…

ただ当日は、皆さんからの反応も良く割と再現できてたようなので安心しました笑

fracchi

これは、fracchiのデモの様子👀

fracchiチームは、Webとモバイルの両方で開発を進めていましたが、発表直前まで謎のビルドエラーに悩まされていたそうです。最終的にはギリギリでビルドに成功し、なんとか間に合ったとのこと(笑)

シヨウワカール

シヨウワカールは、このようにphotoructionの仕様について質問をするとそれに対して回答をしてくれるチャットボットを開発してました🤖

こちらは、実際にslack上で質問を投げることで回答してくれるのですが、社内での実用性が高いということで、継続して開発をすることで社内システムとして動かせるようにしようということになり、かなりの収穫がありました!

Laboのこれから

Demo Dayを終え、第一期 Photoruction Labo はひとまず終了となりました🎉

まずは「1年間しっかり継続すること」「その中で成果を出すこと」を目標に運営してきたので、無事に最高の形で締めくくることができて、本当に嬉しく思います。

中でも印象的だったのは、参加メンバーから「携わったプロダクトや技術に対して、より興味を持てるようになった」との声があったこと。Laboを企画して本当によかったな、と心から感じました😭

会社としてもこのLaboを“技術研究の場”としてさらに盛り上げていきたいという想いがあり、第二期 Photoruction Labo の開催が決定しました🙌

今年はAIブームの真っ只中ということもあり、ここからサービスに活かせるようなプロダクトが生まれるかもしれません…!?!

Photoructionでは、これからも新しい技術にどんどんチャレンジしていきます。少しでも気になる方は、ぜひ以下からカジュアル面談をお申し込みください!

これからも応援よろしくお願いします🙇‍♀️

株式会社フォトラクションでは一緒に働く仲間を募集しています

Androidチームがクラッシュフリー率を改善した話 💪

Androidエンジニアの斎藤です。

私が所属するAndroidチームとしての取り組みとその成果について紹介させていただきます。

Androidチームの課題への向き合い方や雰囲気など感じていただければと思います 🙇‍♂️

はじめに

クラッシュフリー率について

クラッシュフリー率はアプリがクラッシュせずに正常に動作したユーザーやセッションの割合を示す指標のことで、アプリの品質を図る上で1つの指標となっています。

一般的なアプリのクラッシュフリー率は分かりませんが、私自身が過去に関わってきたAndroidアプリと比較すると低い数字でした。

フォトラクションアプリの状況

またチーム目標としてはクラッシュフリー率の向上を目標としていましたが、これに対する具体的なアクションはあまりありませんでした。

フォトラクションアプリは2017年から開発されたものでJavaコードが残っていたりします。 加えて別会社の業務委託によって追加された機能などもあり全ての機能を網羅的に理解できる人はチームにはいない状況でした。それらのコードがクラッシュする時もあり調査が進まないこともありました。

改善に向けて

改善に向けた具体的なアクションとして下記のことにチームで取り組みました。

クラッシュの棚卸し

Androidチームは毎日決まった時間に1時間ほどのチームミーティングを設けています。毎週火曜日にチームで Crashlytics を見て新しいクラッシュがないか、増加していないかを見ることにしました。

まず発生したクラッシュのスタックトレースを見て、その場で発生箇所のコードを全員で見ます。 発生原因と修正箇所の目処が立ったらクラッシュのメモ欄に記載しておきます。

すぐにわからなそうであればチケット着手のタイミングで子タスクとして調査チケットを作成して詳細な原因調査から始めます。クラッシュに紐づくJIRAチケットがない場合は、このタイミングでJIRAチケットを発行します。

この一連の作業により、今Androidアプリでどのようなクラッシュが発生しているか、問題のコードがどのように実装されているかを知ることができます。 「このバグこの前のアレですかね?」「ですね」みたいな会話ができるようになりました。 問題に対する修正方針がチーム内に共有されることで、新規コーディング時にも同じようなバグをうまなくなります。

クラッシュを修正するチケットをスプリントに差し込む

スプリント(SP)の稼働の10%を目安にクラッシュの改善を積むことにしました。 新機能開発を優先することもあったので、クラッシュ改善がないSPもありましたが、新機能開発がないSPにクラッシュ改善ができたので平均すると10%~20%くらいにできたのではないかと思います。

実績

ここ半年で87%->95%に改善することができました。

加えてこの間に新機能開発を止めることなくできたというのは何よりも大きかったです。

まとめ

  • 目標達成には具体的なアクションが必要。
  • 問題は根気強く分解してチームで1歩1歩着実に。
  • 価値提供はやめない。
  • その上でよりスピードを。

直面する問題が大きすぎると全てを捨てて新しく作り直したくなる誘惑にかられると思います。しかし作り直したところでいずれはまた別の問題に直面するはずです。つまるところ問題が一定程度大きくなるとリセットしなければならなくなってしまいます。 チームに求められることは問題の大小に関わらず問題を根気強く分解してチームで1歩1歩着実に進めて顧客に価値提供をし続けることです。 その上でよりそのスピードを高められるように今後もチーム一丸となって進めていければと思いました。

株式会社フォトラクションでは一緒に働く仲間を募集しています

DTOクラスの基本

はじめまして、BPOチームでエンジニアやってますkazuです🦌

最近業務で、DTOクラスを教えてもらったので理解を深めようと思い記事にしてみました。

そもそもDTOクラスとは

DTO(Data Transfer Object)とは、システム間やレイヤー間(例:UIとビジネスロジックビジネスロジックとデータベースなど)でデータを転送する時に用いられるオブジェクトのこと。

APIやDBから受け取ってきた生のデータを扱いやすい形に変換して、一貫した形式でアプリケーション内部に受け渡しができる。

特徴

  • ロジック(ビジネスロジックドメインロジック)を持たない
  • プロパティを保持するシンプルなクラス
  • 入力値の以上や型揃えの不備を発見しやすくなる

つまり、あくまで「データの運搬がメイン」のオブジェクトで、ビジネスロジックドメインロジックのような業務ルールや制約などの処理に含まれず、純粋にデータのやり取りを担うことを目的としている。

なぜ、DTOを使う必要があるのか

1. レイヤー間の依存を減らす

例えば、ドメインオブジェクト(エンティティ)をUI層に直接渡すと、UI層で余計なフィールドやメソッドを操作できてしまい、依存関係が複雑になったりする。

DTOを挟むことで、UI層に必要な情報だけを切り出し、UI層とドメイン層の結合度を下げることができる。

2. データのまとまりを担保する

データをひとつのオブジェクトにまとめることで、転送やシリアライズが簡単になり、データの受け渡しを行う関数やAPIの引数/戻り値を整理しやすくする。

3. セキュリティやバリデーションのしやすさ

データチェックやバリデーションをDTOクラスの生成過程で扱いやすくなる。

DTOがよく使われるシュチュエーション

Webアプリケーションのリクエスト/レスポンス

マイクロサービス間通信

  • マイクロサービス同士が通信する際、ServiceA → DTO → ServiceBのようにデータ転送をする

レイヤードアーキテクチャ

上記のような間で、Entityをそのまま渡すと密結合になるため、DTOを介して疎結合に保つ。

サンプルコード

class OrgDTO {
  constructor(contents) {
    this.orgId = this.parseIntValue(contents["orgId"]);
    this.email = contents["email"];
    this.name = contents["name"];
  }

  parseIntValue(value) {
    return value ? parseInt(value, 10) : null;
  }
}

function main() {
  // サンプルデータ(外部から取得する想定のデータ)
  const contents = {
    "orgId": "1",
    "email": "aaa@example.com",
    "name": "test"
  };

  // DTOクラスのインスタンスを生成
  const result = new OrgDTO(contents);
  console.log("result", result);
}

main();

例えば、このように入力値の orgId が文字列として与えられる場合、parseIntValue 関数を利用して文字列型を Int 型に変換することができます。このように、生のデータをアプリケーション層で扱いやすい形に整形することで、コードの可読性と保守性を大きく向上させることができます。

また、データの取り扱いに役割を限定することで、ドメインロジックやビジネスロジックとの結合度を下げることができ、システム全体の見通しが良くなります。結果として、その後の処理でデータを扱う際に余計な手間が減り、開発効率が向上しそうです。

まとめ

  • DTOクラスは、「データをやり取りするだけ」のオブジェクト
    • ロジックを持たず、転送用フィールドとアクセサだけを持つのが基本
  • レイヤー間の依存度を下げ、コードの可読性を上げるために利用
    • 疎結合を保ち、メンテナンス性を高めるのに役立つ
  • Webアプリやマイクロサービス、レイヤードアーキテクチャで使われることが多い
    • リクエスト/レスポンスやDBとのやりとりなど

開発組織オフラインイベント Photoruction X ✨

初めまして!CREとしてエンジニアをやってますkazuです🦌

今回は、12月に開催された開発組織オフラインイベント「Photoruction X」についてお届けします👏 企画運営メンバーとして約2ヶ月間、イベントの実現に向けて尽力してきました。当日の様子や運営メンバーの取り組み、そしてPhotoructionの魅力について少しでも知っていただける内容となっています。ぜひ最後までご覧ください!

Photoruction Xで達成したかったこと

各部署・各チーム・各メンバー間でのX(交流点)を作り、コミュニケーションの場を生み、未来につながるコミュニティを作ることを目的としています。今回のイベントでは、X(交流点)をたくさん生み出すことを目標とし、その目標を達成させられるようなコンテンツをいろいろ用意しました!

Photoruction X ロゴ

当日のイベント風景

当日は、運営の挨拶から始まり、中村CTOからこれからどんな組織にしていきたいかの共有、レクリエーションなどを行いながら、普段接点を持つことがないメンバーとの交流をできるようにしました。

イベント会場としてお借りしたのは、スペースマーケット本社になります✨ spacemarket.co.jp

広々とした空間で、テーブルなども臨機応変にレイアウトを変えたりできるので、使い勝手が良かったです!また、カウンターもついていることから、料理の提供もしやすく何より料金が安くかったので運営としてはとても助かりました🥺ありがとうございます!

気になる方は、こちらでチェックしてみてください↓↓↓

https://www.spacemarket.com/

Photoruction X 開催🎉

僕は司会を務めさせていただきました👏

内心準備したものを楽しんでもらえるかドキドキしていました(笑)

運営からの挨拶

はるっちと僕からの挨拶!(右側見切れてますが笑)

中村さんからも挨拶をいただきました!

企画の趣旨を説明しつつ本日のタイムスケジュールをお伝えしました!

テクノロジー本部ココロエとはなんだろう🤔

テクノロジー本部のココロエ

中村CTOから、テクノロジー本部が目指すこれからについての共有の時間です⏰

テーマは、「あざとく、優しく、組織力向上への道」ということで、ホスピタリティとあざとさで組織力向上を目指そうというものです。

ホスピタリティとは

相手の状況や感情を理解し、ベストなアクションを取ること

ホスピタリティが高い組織のメリット

  • 心理的安全性の向上
  • スムーズなコミュニケーション
  • 持続可能な働き方
  • 信頼関係の構築

「ホスピタリティが高い組織のメリット」を再認識する中で、自分自身のホスピタリティ力をさらに高めることで、組織の成長により大きく貢献できると感じました。心理的安全性やスムーズなコミュニケーションを通じて、信頼関係を構築し、持続可能な働き方を実現するために、自分にできることを今後も追求していきたいと思いました!

あざとさ

スマートに価値や成果を伝え、共感や支持を得る力

あざとさが組織にもたらす強み

  • 外部への魅力発信
  • 競争力の向上
  • チームのモチベーションアップ

スマートに価値や成果を伝える力は、組織の魅力を外部に発信し、共感や支持を得るうえで非常に有効だと感じます。この力が競争力の向上や人材確保にも繋がる点に気づき、新たな視点を得ることができました。「あざとさ」という言葉のポジティブな使い方にも感心しました笑

Photoruction Labo 中間報告会

Photoruction Laboってなに?ってところから始まり、各チームのプロダクトの発表を行いました。

こちらは、僕とCREチームリーダーのよしきさんで司会進行!

Photoruction Xの目的と似ていますが、チーム単位での開発を行うことで人と人同士の繋がりを増やして、組織力向上を目指そうというのが主旨となっています。

そして、各チームのプロダクトの発表へ…

fracchiでは、flutterを用いて日記を記録して投稿するアプリを作成しています。

fracchiは、先日開発合宿にも行ってるので、気になる方はこちらをご覧ください↓↓↓

https://kojichu.photoruction.com/entry/2024/11/27/090000

シヨウワカールでは、AIチャットbotを作成し、使用の不明点について質問したらそれに回答してくれるプロダクトを開発しています。

これが実現したら、CREの仕事も大助かり…🥺

最後は、day1チームの発表です!

こちらは、VRを用いてオフィスを再現させています。

UnityとBlenderを用いているのですが、BlenderとUnityとの互換性がまあ悪い。笑

普段のプログラミング言語とも異なるツールなので、最初から覚えるのはかなり苦労しました💦

それでも、どうにか「誰がどうみてもオフィスだよね」くらいのレベル感には到達。

長い道のりでしたが、残りの数ヶ月でものを掴んだり勝手に何かかが動いたりまで実装できるように頑張ります💪

レクリエーション

お待ちかねのレクリエーション👏

今回は、以下の4つを企画しました!

意外に盛り上がったのが、スポーツスタッキングでした!笑

各チームがタイムアタック形式で競い合い、隣同士でプレイの様子が見える状況が白熱した雰囲気をさらに引き立てていました!競技中の緊張感とガヤの声で、会場全体が一体感に包まれていました!

最終的に優勝したのはチームAでした🎉

なんと優勝チームには、Amazon ギフト5,000円の券 or 沖縄出張券が与えられるという豪華景品🥺

最終的な得点

懇親会🍣

今回は、出張寿司の方に来てもらいその場でお寿司を握ってもらいました!

じつは、出張寿司で来てくれたゆうじくんは元々友達であり、今回の企画運営を任されたタイミングで、「ゆうじの寿司をぜひ食べてほしい!」と思い、企画に練り込んでいました笑

皆さん美味しいと言いながら、もりもり食べてくれたので僕としては大満足でした😭

ゆうじくんのインスタ気になる方いましたら、ぜひこちらもご覧ください↓↓↓

https://www.instagram.com/yuji.m_sushi?igsh=YXMxMTMxYW1sZXR0

最後はみんなで写真を撮って、終わりました〜

まとめ

初めてメンバーだけで運営を行いましたが、コンセプト設計からコンテンツ企画、会場選定、予算管理、社内広報まで、さまざまな制約の中で「どんな体験を提供するのか」「何を達成するのか」を逆算しながら取り組みました。その過程では多くの葛藤もありましたが、無事に当日を迎え、イベントを成功させることができました。そして、何よりも参加者の皆さんの笑顔を見られたことが大きな励みとなりました!

イベント運営に関わることができて、本当に良かったです!

中村さん機会をくださり、ありがとうございました🙇‍♀️

P.S

春っち、武井さん、期間限定チームだったけど一緒にイベント作りできた事は一生の思い出です。 二人とイベント作りできてとても楽しかったです!最高のチームだったと思います。 またチーム組む機会あったらよろしくね🤝

株式会社フォトラクションでは一緒に働く仲間を募集しています

Photoruction Labo 開発合宿@LIFORK大手町 🖥️

こんにちは、Build Web所属の田村です。

何度か記事になっていますが、弊社テクノロジー本部ではPhotoruction Laboという開発イベントを実施しています。

私たちのチーム”fracchi”は主にFlutterを使って何か作ってみよう!をテーマに進めていますが、このたび11月2日(土)に開発合宿に参加しましたのでレポートします!

↓↓↓Photoruction Laboについては、こちらの記事を参考にしてください

kojichu.photoruction.com

なぜ開発合宿に行くことにしたのか

fracchiは2.5名体制となっていて、メンバーは

  • 田村 Build Webグループ リーダー
  • ヤスィン Build Mobileグループ リーダー
  • 田中 CREグループ リーダー ←開発はせずfracchiの面倒を見てくれるマネージャー的存在

となっています。

週あたり4時間程度Laboのために割り当てて進めることにしていますが、そうは言ってもお互いにリーダー職でとても多忙な毎日を送っているため、なかなかLaboのために時間をとることが難しい😓

実際Flutterの開発環境を5月に作成し、その後だいぶ間が空いて8月下旬にやっと最初の実装コミットというスローペース。というか、全く進んでいない・・・。

ここでガツンと進捗を出そうぜ!とマネージャー田中さんがあれこれと計画をしてくれたことがきっかけでした。

VRチームから”淡路島で合宿して楽しかったし良かったよ!”と聞き当初は日光や熱海で計画しましたが、開発に集中することと手軽さに重点をおき都内のコワーキングスペースで開催することになりました。

↓↓↓fracchiの開発合宿、場所はこちら

lifork.jp

https://maps.app.goo.gl/A21t33NVGrc6umRVA

↓↓↓ちなみにVRチームの淡路島合宿の記事

kojichu.photoruction.com

開発合宿の様子

合宿といっても都内コワーキングスペースということで、最初は「いつもの仕事と変わらんだろう🤔」ぐらいに実は思っていましたww

“ホテルに缶詰”みたいな感じですかね。ペンが進まない作家が編集者につかまって逃げられないように閉じ込められるアレ。

ところが予想に反してこのコワーキングはとても趣があって雰囲気も最高!充実の作業環境!👍️

当初のイメージとはまったく異なり、数カ月分の進捗以上のものをたった一日で生み出すことができました🙌

エンジニアの2人

これから始めるところですね💪

周辺の様子

緑もいっぱいで外の喧騒はまったく気になりませんでした👍️

シェアオフィスの中

インテリアも落ち着いた雰囲気でとてもリラックスして作業に集中することができます👨‍💻

作業スペース①
作業スペース②
作業スペース③

こんな作業スペースもあります

まるでお金持ちの友達の家にお呼ばれしたかのよう

これはこれで気分転換できそう

その他の設備

おいしいコーヒーを淹れることができます☕

作業に必要なものはなんでも揃ってる(モニターやケーブル等も)

打ち合わせもできます

ランチ

霧雨けむるアンニュイな土曜にがんばる私たちのために田中マネージャーが予算取りしてくださいました🍣

遠方への移動費や宿泊代を削減してよかったと思えた瞬間でした🫣

最後に:開発合宿が終わって思うこと

通常の業務の中でLaboのためにうまく時間を取ることができなかったのですが、こういう機会があったことでそれをうまくカバーすることができました🎉

また私はいつもは田舎でリモートワークをしていてそれはそれでメリットもたくさんあるのですが、たまにはオフィスで仕事をしたりチームのメンバーの顔を見たいなぁと思うことがあります。

いつもヤスィンさんとは業務ではグループ間の共有・調整などのやり取りが主となり一緒に作業をすることはほとんど無いのですが、同じ場所で同じ目標に向かって手を動かすことで初めてわかることがたくさんありました。

ランチや徒歩移動のときにはお互いの家族のこと、今まで経験してきたこと、文化の違いなどいろいろ話すことができました👍️

現状、弊社テクノロジー本部はグループ・チームが違うとガクッとコミュニケーション量が減り同じエンジニア職でありながらお互いのことをあまりよくわかっていないということが少なくないです。

Photoruction Laboの目的として個人のスキルアップもありますが、希薄になりつつあるエンジニア間のコミュニケーション機会を増やしてより強い組織にしていくことも大事なことだと思ってます。

合宿ではオフラインで接することで良い体験を得ましたが、今後オンラインでのコミュニケーションにも活かしていけたらと思いました。

小声)そして・・・なんとかゴールに辿り着きたい ←切実🫠

おまけ:今回の出張のおみやげ

東京駅で新幹線に乗る前に買ったサンドクッキーとフィナンシェ🍪

前日のオフィス出勤と合わせて2日間家をほったらかしてしまいましたが、家族にとてもおいしいと喜ばれました👍️

coco-ris.jp

https://maps.app.goo.gl/BvsAiq78BUp2dwjbA

株式会社フォトラクションでは一緒に働く仲間を募集しています

Laravel + Brefで実現するサーバーレスアプリケーション

はじめに

BPOチームの春冨です。

今回は業務でサーバーレスアプリケーションを実装することになり、Brefというツールを使用する予定です。初めて使うツールなので、まずは簡単に試してみました。この記事ではその実践内容を紹介します。

Bref とは

Brefは、LaravelなどのPHPアプリケーションをAWS Lambda上で動作させるためのツールです。通常、LambdaはNode.jsやPythonJava、Goといったランタイムを公式にサポートしていますが、PHPは含まれていません。Brefはこのギャップを埋めるため、独自のPHPランタイムを提供し、PHPアプリケーション(例:Laravelアプリケーション)をAWS Lambda上で実行可能にします。

システム構成

システム構成図

今回作成するシステムの構成図は以下の通りです。

  • 静的ファイルはCloudFront経由でS3から取得
  • 動的なリクエストはCloudFrontからAPI Gatewayを介してLambdaに送信し、バックエンドで処理

バックエンドはLaravel + Brefで、フロントエンドはReactで実装してビルドしたものをS3に配置するSPAとして構築しました。

実装手順

実装はバックエンドとフロントエンドに分けて進めます。

バックエンド

LaravelでAPIを実装

api.phpに以下のようなコードを追加し、簡単なレスポンスを返すようにしました(Laravel 11を使用)。

<?php

use Illuminate\Support\Facades\Route;

Route::get('/hello', function () {
    return response()->json(['message' => 'Hello World!']);
});

Brefのセットアップ

brefの公式ドキュメントに従い、Serverless FrameworkのインストールやAWSアクセスキーの設定を行います。今回はbrefというプロファイルを作成し、デプロイに使用しました。

Laravelにbrefをインストールし、デプロイ

composerを使ってbrefをインストールします。

composer require bref/bref bref/laravel-bridge --update-with-dependencies

次に、serverless.ymlをコマンドで生成します。

php artisan vendor:publish --tag=serverless-config

デフォルトのserverless.ymlを編集します。

  • regionap-northeast-1に変更
  • profileに作成したプロファイル名を追加
  • runtimephp-83-xxxに変更(Laravel 11にはPHP 8.3が必要なため)
service: laravel

provider:
    name: aws
    # The AWS region in which to deploy (us-east-1 is the default)
    region: ap-northeast-1
    # Environment variables
    environment:
        APP_ENV: production # Or use ${sls:stage} if you want the environment to match the stage
        SESSION_DRIVER: cookie # Change to database if you have set up a database
    profile: bref

package:
    # Files and directories to exclude from deployment
    patterns:
        - '!node_modules/**'
        - '!public/storage'
        - '!resources/assets/**'
        - '!storage/**'
        - '!tests/**'

functions:

    # This function runs the Laravel website/API
    web:
        handler: public/index.php
        runtime: php-83-fpm
        timeout: 28
        events:
            - httpApi: '*'

    # This function lets us run artisan commands in Lambda
    artisan:
        handler: artisan
        runtime: php-83-console
        timeout: 720 # in seconds
        # Uncomment to also run the scheduler every minute
        #events:
        #    - schedule:
        #          rate: rate(1 minute)
        #          input: '"schedule:run"'

plugins:
  - ./vendor/bref/bref

以下のコマンドでデプロイすると、API GatewayとLambdaが作成されます。

serverless deploy

フロントエンド

Reactアプリケーションを作成

npx create-react-app my-app

ReactからLaravelのAPIを呼び出す機能を実装

App.jsに以下のコードを追加し、LaravelのAPIから取得したデータを画面に表示させます。

import React, { useEffect, useState } from 'react';
import logo from './logo.svg';
import './App.css';

function App() {
  // useStateを使ってAPIから取得したデータを保存する
  const [apiData, setApiData] = useState(null);

  // useEffectを使ってコンポーネントのマウント時にAPIリクエストを送信
  useEffect(() => {
    // Laravel APIへのリクエストを送信
    fetch('/api/hello')
      .then(response => response.json())  // レスポンスをJSON形式に変換
      .then(data => {
        setApiData(data);  // APIのデータをstateに保存
      })
      .catch(error => {
        console.error('Error fetching data:', error);
      });
  }, []);  // 空の依存配列により、この効果はコンポーネントが初回レンダリングされたときだけ実行される

  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Edit <code>src/App.js</code> and save to reload.
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>
        {/* APIデータが存在する場合に表示 */}
        {apiData && <p>API Response: {apiData.message}</p>}
      </header>
    </div>
  );
}

export default App;

ReactをビルドしてS3に配置

npm run build
aws s3 sync build/ s3://your-bucket-name

CloudFrontの設定

最後に、CloudFrontを作成し、S3とAPI Gatewayをオリジンとして設定します。

/api/*パスパターンでAPI Gatewayに向くようにビヘイビアを設定し、それ以外はS3に向くようにします。

以上で実装が完了です。CloudFrontのURLにアクセスすると、ReactアプリにLaravelのレスポンスが表示されるようになります。

まとめ

今回の記事では、LaravelとBrefを使用してサーバーレスアプリケーションを構築する方法を紹介しました。Brefを利用することで、AWS Lambda上でLaravelを動作させる環境を簡単に構築できることが分かりました。

株式会社フォトラクションでは一緒に働く仲間を募集しています

LambdaからRDSにアクセスができない理由

初めまして!CREとしてエンジニアをやってますkazuです🦌

社内システム自動化プロジェクトのインフラ構成を考えていた際、本番環境のRDSにLambdaからアクセスする必要があり、「とりあえずRDSにLambdaからアクセスさせればいいんだな〜」と思っていたところ、実は簡単にアクセスできるものではないことを知ったので、その時調べたLambdaとRDSの関係についてまとめた記事になります。

※こちらの図は、業務で作成したインフラ構成図とは異なるものです。

そもそも、LambdaからRDSに接続することになったワケ

本プロジェクトは、要件定義から開発まで一貫して担当しているプロジェクトであり、これまで社内で手動でやっていたのものを自動化する事が目的です。最終的にはLambdaからRDSにアクセスをし、本番DBの値を更新する事でその結果をSlackに通知する事を目指しています。

正直なところAWSに関する知識は乏しく、「Lambdaを呼び出して実行すれば、本番DBを更新できるだろう」と考えていました。

しかし、インフラ構成図をもとにフィードバックを受ける中で、LambdaからRDSへのアクセスが簡単ではないことを知り、その理由について疑問が湧いてきたので調べることにしました。

なぜ、LambdaからRDSへ接続ができないのか

  • RDSの作成場所がVPC内であること
  • VPCに接続するには、同じVPCのプライベートサブネット空間にLambdaを配置する必要がある

RDSの作成場所がVPC内であること

Auroraなどの RDSは、基本的にVPC内のプライベートサブネットに配置されます。これは、セキュリティ面を考慮して、外部から直接アクセスできないようにするためです。パブリックネットワークに露出させないことで、外部からの不正アクセスリスクを低減し、安全性を確保しています。これにより、データベースを社内や関連システムからのみアクセス可能な状態に保つ事ができます。

プライベートサブネットにあるRDSに接続するには

VPC内のプライベートサブネットにある RDSに接続するためには、Lambdaも同じVPCのプライベートサブネット内に配置する必要があります。Lambdaの配置場所は、パブリックサブネットとプライベートサブネットのどちらかを選択する事が可能ですが、RDSとの接続を前提とする場合は、プライベートサブネット内にLambdaを置きます。

Lambdaがインターネットと接続できない

ここで、一つ問題があります。Lambdaをプライベートサブネット内に配置することで、RDSへのアクセスは可能になりましたが、インターネットとの接続ができません。

プライベートサブネット内にあるLambdaが外部のAPIやインターネットリソースにアクセスする必要がある場合、以下のような方法を使ってインターネット接続を実現する事ができます。

NATゲートウェイを使う

NAT(Network Address Translation)ゲートウェイは、プライベートサブネット内のリソースがインターネットに接続できるようにするAWSのサービスです。 NATゲートウェイをパブリックサブネットに配置し、プライベートサブネット内のLambdaからインターネットにリクエストを送ると、そのリクエストはNATゲートウェイを通じてインターネットに出ていきます。これにより、プライベートサブネット内にあるLambdaが安全に外部通信を行えるようになります。

NATゲートウェイは一方向の通信を許可する仕組みであり、インターネットからの直接アクセスはできないため、セキュリティを保ちつつインターネット接続する事が可能です。

まとめ

今回は、LambdaがRDSにアクセスできない理由について解説しました。まだまだAWSについては勉強が必要そうです。

株式会社フォトラクションでは一緒に働く仲間を募集しています