エキサイト就業型インターン「Booost!!!」を通して学んだこと

はじめに

2025年11月、Booost!!! Excite Internship 2025 に1ヶ月間参加しました。

自社開発で大規模な Web アプリケーション開発に携わり、実務を通じて技術力を高めたい、また現場の開発フローを学びたいと考え、参加を決めました。

本記事では、Life & Wellness 事業部で Web アプリ開発に携わった経験をまとめます。

自己紹介

私は琉球大学大学院の修士1年で、研究テーマは主に HCIです。センサに関する研究を行っており、最近は「筋変位センサによる持久走時の三相疲労推定」をテーマに、取得した筋変位データを機械学習で分析し、疲労推定を行っています。

アルバイトでは、大学1〜3年生の頃は飲食店や雑貨屋さんでアルバイトをしていました。大学4年生からは技術系のインターンに積極的に参加し、複数の企業様のインターンでweb・モバイルアプリの開発経験を積んでいます。

個人開発でポートフォリオサイトも作っています。よければぜひご覧ください。

https://kouya.st.ie.u-ryukyu.ac.jp/

趣味はアコギ、サックス、スマブラ(enjoy勢)、フルマラソンに向けて走ったりしています。

配属先で取り組んだこと

Life & Wellness 事業部の エキサイト電話占い に関連する新機能として、 「特定の占い師一覧を表示・管理するためのバッチ機能管理ツール」の開発を担当しました。

具体的に行ったタスク

【フロントエンド】

  • API 経由でバッチ一覧を取得し、管理ツール上に表示する機能を実装
  • バッチの登録機能の実装
  • ページ構造の見直しに伴うパスのリファクタリング
  • バッチ削除機能の実装

【バックエンド】

  • 占い師データを DB から削除する API の実装

【UI/UX 改善の提案】

  • 新規登録の際に ID 直指定ではなく、一覧から選択できる仕組みの提案
  • 削除確認ダイアログの「はい」「いいえ」の色・位置が逆でダークパターンになっていたため改善案を提示

【そのほか】

  • メンターの方と一緒にリリースのロールプレイを体験
  • GitHub Actions による CI/CD の仕組みを理解

学んだこと

今回のインターンでは、技術面・開発プロセスの両面で多くの学びがありました。

まず、バックエンドでは BEAR.Sunday、フロントエンドでは Smarty の理解が深まり、実務のコードを読みながら開発する経験を積むことができました。 また、毎日の朝会で進捗や作業内容を共有することで、コミュニケーション(共有)をとる重要性を実感しました。

さらに、リリースのロールプレイを通じて、CI/CD や GitHub Actions による自動デプロイの流れを体験でき、バックエンド周りの理解度も深まりました。

実装中には、ツールの UI/UX がより良くなるよう改善点を自分なりに考え、実際に提案することができました。ユーザ視点を常に意識する姿勢がエンジニアにとって非常に重要だと改めて感じました。

おわりに

1ヶ月のインターンを通じて、実務レベルの開発に携わりながら、技術的にもチーム開発の面でも大きく成長できました。 特に、限られた期間の中で自分の手で機能を実装し、改善案まで考えられたことがとても学びになりました。

今回得た経験や学びを今後の研究や開発にも活かし、より良いサービスづくりに貢献できるエンジニアを目指していきたいと思います。 メンターの皆さま、事業部の皆さま、本当にありがとうございました。

就業型インターン「Booost!!!」:【お悩み相談室】コラム記事の新規アプリケーション移植

背景(過去フレームワークからの移行)

インターンシップでは、既存の「お悩み相談室」のコラム記事機能を旧フレームワーク(BEAR.Saturday)から新規フレームワーク(Laravel基盤)へ移植する作業を担当しました。

BEAR.Saturdayについて

移行元のシステムはBEAR.SaturdayというPHPフレームワークで構築されていました。 BEAR.Saturdayの紹介記事によると、このフレームワークは主に次の3つの要素で構成されています。

  • ページ(Page): URLに対応するコントローラーの役割。onInject(パラメータ取得)、onInit(ロジック実行)、onOutput(ビュー割り当て)というライフサイクルを持ちます。
  • リソース(Resource): DBや外部APIとのインターフェース。onReadonCreateなどのメソッドでCRUD操作を実行します。
  • ビュー(View): Smartyテンプレートエンジン(.tpl)を使用した表示層。

アーキテクチャのデータフロー:

新規フレームワークの構造

移行先のシステムはLaravelをベースとしたモダンアーキテクチャを採用しています。 主な構成要素は以下の通りです。

  • Controller: リクエストを受け取ってUseCaseを呼び出します。
  • UseCase: ビジネスロジックカプセル化し、Repositoryを利用してデータを取得します。
  • Repository: データアクセス層(DB操作など)を担当します。
  • ViewModel: ビューに渡すデータを整形・保持するクラス。ビュー側のロジックを排除します。
  • View: Bladeテンプレートエンジン(.blade.php)を使用。

新規アーキテクチャのデータフロー:


実際の作業内容

リポジトリ〜コントローラー開発

新規アプリケーションは各レイヤーの責務が明確に分離されたアーキテクチャを採用しており、今回の移植作業もこの構造に合わせて開発を進めました。

  1. Controller:

    • リクエスト処理: HTTPリクエストのエントリポイントとして、URLパラメータ(columnKey)を受信します。
    • ビジネスロジック呼び出し: 直接的なデータ処理をせず、UseCaseを実行して必要なコラムデータをリクエストします。
    • 結果ハンドリング: UseCaseの実行結果状態を確認し、データが無い場合は404エラー、システムエラーの場合は500エラーを返すなど、適切なエラーハンドリングを実行します。
    • ビュー応答: データ取得成功時、ViewModelにデータを格納してビューに渡します。この際、ユーザーエージェント(User Agent)に応じてPC用(index)またはSP用(index_sp)ビューファイルを動的に選択して返却します。
  2. UseCase & Repository:

    • UseCase: ビジネスロジックの中心として、コントローラーのリクエストを受けて具体的な処理フローを制御します。
    • Repository: 実際のデータベースアクセスはRepository内の実装クラスに委譲されています。これによりビジネスロジックとデータアクセス技術が分離され、保守性とテスト容易性が確保された構造になっています。

実際のデータ取得フロー(例: columnKey=12 リクエスト時):

View Composer活用及びメリット

コラム機能には「過去記事一覧」のように複数のページで共通に表示される要素がありました。 このような共通要素を効率的に管理するため、View Composerを導入しました。

View Composerとは? View Composerはビューがレンダリングされる直前に、特定のデータやロジックを該当ビューにバインドできるようにするLaravelの機能です。これにより、コントローラーで毎回データを渡さなくても、ビューが呼び出される際に自動的に必要なデータが注入されます。

今回のプロジェクトではこの機能を活用してバックナンバー表示ロジックを以下のように実装しました。

class ViewComposer
{
    public function __construct(
        private UseCaseInterface $useCase
    ) {}

    public function compose(View $view): void
    {
        // 1. UseCaseを通じてデータ取得
        $useCaseOutput = $this->useCase->handle();

        // 2. ViewModelでラップしてビューに'vm'変数として渡す
        $view->with(
            'vm',
            new ViewModel($useCaseOutput)
        );
    }
}

テンプレートでの使用例:

{{-- ビューコンポーザーがバインドされたビューをinclude --}}
@include('elements.viewComposer')

View Composerのメリット: * コントローラー肥大化防止: 共通パーツのデータ取得ロジックを各コントローラーに記述する必要がなくなります。 * 再利用性向上: どのビューでも@includeするだけで必要なデータが自動的に供給されます。 * 責務分離: ビュー構築に必要なロジックを専用クラスとして分離できます。

.tplから.blade.phpへの変換(Pythonによる自動化)

移行対象のビューファイル(.tpl)は数が多く、手作業での変換は時間的コストとミスのリスクが高い状態でした。 そこで変換パターンを分析し、Pythonスクリプトconverter.py)を作成して一括変換を実行しました。

自動変換アプローチ

スクリプトでは正規表現を使用して次の変換処理を自動化しました。

  1. 構文変換:

    • Smarty変数展開 {$var} → Blade {{ $var }}
    • コメント {* ... *}{{-- ... --}}
    • Include文 {include file="..."}@include('...')
  2. 静的HTMLからViewModelへの移行:

    • 旧ファイルではHTML内に直接記述されていたタイトルや日付などをViewModelメソッド呼び出しに置換しました。
    • 例: <h1 class="ttl-column">...</h1><h1>{{ $vm->getTitle() }}</h1>
    • 例: <time datetime="..."><time datetime="{{ $vm->getDateTime() }}">
  3. ヘルパー関数適用:

    • 画像パスとリンクをLaravelのasset()url()ヘルパーを使用する形式に変換しました。
    • 例: {$config.img}/path/to/img{{ asset('path/to/img') }}
  4. ヘッダー・レイアウト生成:

    • YAML設定ファイル(config.yml)からメタデータ(タイトル、description、CSS)を読み込み、Bladeの@section@pushディレクティブを自動生成しました。

変換スクリプト例(正規表現による置換ロジック):

# HTMLタグ内の静的テキストをViewModelメソッド呼び出しに置換
content = re.sub(r'(<h1 class="ttl-column">).*?(</h1>)', r'\1{{ $vm->getTitle() }}\2', content)

# datetime属性と表示用日付の置換
content = re.sub(
    r'(<time datetime=").*?(" itemprop="datepublished">).*?(</time>)', 
    r'\1{{ $vm->getDateTime() }}\2{{ $vm->getDateTimeJapanese() }}\3', 
    content
)

# 画像パス置換 (assetヘルパーへ)
content = re.sub(r'\{\$config\.img\}([\w\-\./]+)', lambda m: f"{{{{ asset('{m.group(1)}') }}}}", content)

この自動化により、大量のファイルを短時間で、そして統一された品質で新フォーマットに移行することができました。

結果

🎉

感想

今回のインターンシップは、始まりから予想外の困難がありました。私は現在韓国に在住しており、日本から業務用PCを配送してもらう必要があったのですが、通関手続きなどにより受領が遅れ、実際に作業に投入できる時間はわずか5日間だけでした。

限られた作業時間の制約よりも大きな負担は技術的な部分でした。私はPHP言語自体が初めてだっただけでなく、過去のフレームワークであるBEAR.Saturdayと現在のLaravelの動作方式をどちらも学習し理解しながら作業を進めなければなりませんでした。

「果たして5日という短い時間で、慣れない言語と2つのフレームワークを理解し、課題を完遂できるのか?」という不安が大きかったです。

AIを活用した突破口

このような不安を解消し、スピードを上げることができた核心要因は、Exciteの積極的なAI活用文化でした。

会社レベルで業務にAIツールを積極的に導入し活用する雰囲気だったため、私も躊躇なくAIをメンターのように活用することができました。初めて接するPHP文法やBEAR.Saturdayの不慣れな構造についてAIに絶えず質問してフィードバックを受け、おかげで膨大なコードベースを素早く把握してビジネスロジックを理解する時間を画期的に短縮することができました。

5日間の旅程

限られた時間を効率的に使うため、以下のようにスケジュールを圧縮的に運用しました。

  1. 1日目: プロジェクト開始のためのPC環境設定及びオンボーディング
  2. 2〜4日目: レガシーコード分析及びマイグレーションコード実装集中
  3. 5日目: 最終仕上げ及びブログ振り返り作成

AIという強力なツールのおかげで、期間内に課題を完了することができました。

最後に

物理的距離があるにもかかわらず、5日間細やかにケアしていただき多くのサポートをいただいた伊藤さんに深く感謝申し上げます。

可愛すぎる空間でFigma Make体験!Make with Figma Tokyo イベントレポート

こんにちは、デザイナーの澤田です。

2025年11月7日(金)・8日(土)、原宿で開催された「Make with Figma Tokyo(Figma Make Cafe)」にデザイナー3人で参加してきました!

Figma Japan主催のリアルイベントとして、最新プロダクト「Figma Make」を体験できるブースや、デザイン好きが集うセッションが盛りだくさん!

私は初日に参加したので、その様子をレポートします ☕️

おしゃれすぎる会場

会場は、原宿駅から徒歩すぐのカフェスペースで開催。吹き抜けが気持ちいい明るい空間でした〜!

入口にはなんと「Figmaガチャ」が設置されていて、中身はステッカーやバンダナ!外の暖簾や提灯も素敵で、入る前からテンション上がりました...!

入り口のFigma ガチャ
入り口の暖簾

入ってすぐ左にはFigma Makeを体験できるデモエリアがあり、実際に触って遊べる仕組みがとても楽しかったです! こちらのデモはコミュニティにも公開されているそうです〜

Figma Make体験スペース

ノベルティグッズも豪華!

先着でもらえるグッズはなんとTシャツとキャップ👕🧢

どれもデザイン性が高く、紙袋まで可愛いというこだわりっぷり

豪華ノベルティ

さらに、カフェではドリンクを注文できて、私は抹茶アイスドリンクを選びました! Figmaマーク入りのどら焼きもいただけてとっても可愛く、おいしかったです〜!

会場は常に活気があり、「このグッズ可愛い!」「過去のイベントも行ったよ!」といった声があちこちで聞こえるほど。 過去イベントのTシャツやキャップを身につけた方も多く、Figmaファンの愛を肌で感じる空間でした。

Speed Make セッションに挑戦⚡️

今回の目玉コンテンツのひとつが、抽選制の「Speed Make」セッション。 Figma Makeを使って短時間で自由にサービスを作り、最後に発表するというハッカソン形式のワークショップです。

初めてFigma Makeを触る方も多い中、皆さん試行錯誤しながらもすごいスピードでプロトタイプを完成させていました。

私は「その日の気分にあった色とフレーズを添えたカードを作るサービス」を作成。 ChatGPTと壁打ちをしてから作成したプロンプトをFigma Makeに流し込む形で制作しました。

Figma Make操作画面

実際に作ったサービスはこちら: https://last-fix-04567930.figma.site

参加して感じたこと

今回のイベントは、空間もグッズも体験も遊び心に満ちたイベントでした。

Speed Makeでは、思いついたアイデアをすぐ形にできるスピード感に驚き、AIがデザイナーの創造を支えるパートナーであることを実感しました。

次のイベントでは、もらったTシャツとキャップを身につけて、またこの空気を味わいたいと思います。

最後まで読んでいただきありがとうございました〜🌸

就業型インターン「Booost!!!」を通して学んだこと

はじめに

Booost!!! Excite Internship2025に10月から1ヶ月の間参加させていただきました。ヘルスケア事業部での開発を通して学んだことをブログ記事としてまとめようと思います!

自己紹介

情報学専攻の修士1年生です。 専門は自然言語処理で普段は「SNSのファクトチェックの自動化」というテーマで研究をしており、特にLLMによる含意関係認識精度の向上と言ったファクトチェックの自動化に必要となる要素技術の研究に取り組んでいます。

開発面では、ESが生成AIで書かれたものかどうかを判定する言語モデルを搭載した採用支援アプリ「ES Harmony」を開発し、サポーターズ様ITピッチコンテスト「技育展」の全国大会に出場するなどの経験をしてきました。 これだけを書くと、アプリ開発をバリバリにやっていたかのように思えてしまいますが実際はそこまでではなく、「ES Harmony」では私はAIES判定モデルの学習をメインに担当しており、アプリ開発面では相方と協力して開発するにとどまっていました。

アプリ開発に関する技術力に課題を感じていた中で大規模アプリケーションの開発に携わることによって、具体的に自分にはどのような知識が足りないのかといったことを明確にして、エンジニアとしての今後の成長に繋げられたらと思い、本インターンシップに参加させていただきました!

配属先で取り組んだこと

Life&Wellness事業部の電話占いサービスにおいて、特定の占い師を目立たせるバッチを表示する機能の改修に取り組みました。

具体的に行ったタスク

  • APIからバッチ表示の判定に利用する値を取得する処理の実装
  • 取得した値をアーキテクチャに沿った適切な流れでビューまで渡し、バッチの表示/非表示を行う処理の実装
  • 変更内容に対応したテストの修正

学んだこと

仕事の進め方についての学び

「自己紹介」の章で触れたインターン参加の目的とは別に裏テーマを持ってインターンに臨んでいました。それは「周りの人への助けの求め方・タイミング」です。

タイミングについて

他社様のインターンシップに参加している際に、周りの人へ助けを求めるタイミングには以下の2種類があることに気がつきました。

  • 疑問が出た瞬間に質問をする
  • 何かに詰まってしまっても、自分が思いつく限りの解決策が尽きるまでは粘って、万策尽きてから質問する

この2種類の存在に気がつけた一方、どちらがより良いのかが分からずにいました。そこで本インターンシップでは後者を意識してお仕事を進めました。

その結果、「疑問が出ても粘る事」には以下のメリット・デメリットがあることが分かりました。

  • メリット:疑問にぶつかっても意外と自分で解決できるし、あらゆる可能性を試す過程を踏むことで学習効果を高められる
  • デメリット:とてつもなく時間がかかり、タスクの消化ペースが落ちる

これらのメリット・デメリットを踏まえて、以下のような仕事の進め方をすると良いのではないかという学びを得ました。

  • 作業が詰まってしまったら、思いつく限りの解決策を文字にして列挙する
  • 制限時間(30分?1時間?)を決めて列挙した解決策を片っ端から試す
  • 制限時間が来てしまったら、「試した解決策とその結果」と「試そうとしていた解決策」を添えて質問する

(このように書きましたが、ここまでできたら苦労しないか…と思いました)

周りの人への助けの求め方について

web会議上でメンターさんに質問する際でも、質問したい内容を以下の形式で言語化してslackの自分のtimesチャンネルに投稿してから質問するように心がけていました。

  • 現状
  • 試したこと
  • 聞きたいこと

これにより、質問内容が明確になってやり取りがスムーズになるだけでなく、現状を言語化する過程で自分の頭の中が整理され、新たなアプローチが思いついて自己解決できるケースもありました。

開発面に関しての学び

インターン当初はアーキテクチャの知識が乏しく、自分がコードのどの部分を修正すべきかさえ分かりませんでした。

しかし、デバッグ機能でコードを追う中で、システムが意図的に設計されていることに気づきました。 例えば、テスト容易性のためのインターフェースの導入や、拡張性のためのクラス責務の分割などです。

正直、インターン参加前は「なぜアーキテクチャを学ぶ必要があるのか」、その意義を実感できていませんでした。 しかし今回、責務分割されたクラスやインターフェースに実際に触れたことで、アーキテクチャを学ぶ意義として以下の2点を実感しました。

  • コードの相互依存性を最低限にすることで、システムの拡張や保守がしやすくなること
  • テストのしやすさも念頭においた設計をする必要性があること

これらは普段の研究用コードでも悩んでいた点であり、アーキテクチャを学ぶ意欲が強く湧きました。 まずは基礎的な「レイヤードアーキテクチャ」から学んでいこうと考えています。

おわりに

今回のインターンシップでは、このブログ記事に書ききれなかった部分も含め、本当に多くのことを学ばせていただきました。 何よりも、メンターの方の丁寧なご指導と手厚い支援があったからこそ、困難な課題にも挑戦し、機能実装を達成できたと実感しております。心より感謝申し上げます。 また、インターンの開催にご尽力いただいた人事の皆様、面接をはじめ日々の業務でお時間をいただいた社員の皆様にも、重ねてお礼申し上げます。 皆様のおかげで、エンジニアとして大きく成長できた1ヶ月でした。この貴重な経験を、今後のキャリアに必ず活かしていきたいと思います。 本当にありがとうございました。

エキサイト就業型インターンBooost!!!を通じて実業務開発について学んだ!!!

はじめに

こんにちは!2025年の10月から1ヶ月、経営管理SaaS KUROTENの就業型インターンに参加させていただいた高橋です。今回のインターンで学んだことに関して紹介します!

  • インターンシップでの業務内容
  • 実務で行う開発と趣味開発の違い
  • コミュニケーションで必要なこと

自己紹介

自分は大学3年生で、大学では情報系の学部に通っています。大学1回生の秋からプログラミングを始めて競技プログラミングやweb開発をやっています!

インターンシップでの業務内容

今回自分はサーバサイドエンジニアとして以下の二つのコンテナとそれに紐づくDBテーブルを実装しました。

  • APIコンテナ
  • 通知コンテナ

APIコンテナ
websocketで値を受け取り、データベースに対して値を入れる処理とAmazon SQSに対してデータを流してあげる処理をする。

通知コンテナ
SQSから値を受け取りAmazon SESを用いてメールを送る、また処理完了の通知をブラウザに返す。

実務で行う開発と趣味開発の違い

自分が趣味開発と違うと感じたことは以下の点です。

  • github上でしっかりと修正履歴も残す
  • テストコードを書く
  • GHAの実行時間とテストコード量の考慮
  • 命名の際の可読性

github上でしっかりと修正履歴も残す

自分はいつもコンフリクトするのがめんどくさくgit rebase -i HEAD~ngit commit --amendなどを多用して履歴を最小限にしてマージすることがよくあるのですが実務ではこれをすることでバグの発見が遅れたり、変更履歴をたどりづらくなるデメリットが大きくなるのでfix履歴も残すようにすると良いと学びました。

テストコードを書く

実業務ではただ動作確認としてのモックを作りそれを他の層から呼び出すということは行わずにテストコード用のライブラリを用いてそれぞれの層に対してテストを行なってあげることによってその層の挙動の確認を他の層に依存せずに書くことができるというのがとてもメリットに感じました。

GHAの実行時間とテストコード量の考慮

実務に携わるまではGHAでのテストコードは多いほどそのコードの品質を保てるという点でいいと思っていました。しかし今回業務に携わらせていただいて、もしprod環境でバグが発生した際にそのバグを早急に修正し,dev環境、prod環境にデプロイしていくという作業を考えたときにテストコードが多いことでその過程に遅れが発生してしまい修復作業に時間がかかってしまいます。そのためテストコードを書くのはapplication層以外の部分にしているという実務ならではの話を聞けてとてもいい経験になりました。

命名の際の可読性

コミットメッセージやコメントアウトなどを書く際に英語をなるべく使わないようにすることで認知負荷を下げることを教わりました。コミットメッセージにはそのままブランチ名を書いていましたがこれでは直感的に理解しづらい部分があり日本語で書いた方がわかりやすいなと自分でも感じました。

コミュニケーションで必要なこと

基本的には作業の邪魔にならないようにPRのレビューや確認事項があるときはslackでのメンションで相手の作業を止めないように心がけています。しかし実装方法やドメインについて話すときは通話で話すことによって文面での意図のすれ違いやかえって業務効率が下がってしまうことを防ぐことができると学びました。

最後に

最後になりますがこの度インターンでお世話になったメンタの方、エンジニアの方、人事の方本当にお世話になりました。 今回自分が上記のような機能を実装できたのはメンタの方が丁寧にどうすれば良いかを教えていただいたり、自分が意見を言ったときにそれに対してフィードバックをしていただいたおかげです。また今回インターンで様々な体験を積ませていただけたのは人事の方が手厚くサポートしていただいたからです。このインターンで本当にたくさんのことを学ばせていただきました。1ヶ月という短い間でしたが本当にありがとうございました!

エキサイト就業型インターン「Booost!!!」を通じて学んだこと

はじめに

2025年10月の一ヶ月間、エキサイト株式会社のBB事業部で就業型インターンシップ「Booost!!!」に参加させていただいた土屋啓太です。今回は、インターンで取り組んだことや学んだことを振り返り、紹介します。

自己紹介

東邦大学大学院修士1年の土屋啓太です。大学院では情報科学を専攻しており、複雑ネットワークと制御理論、グラフニューラルネットワークの研究を行っています。

技術領域としては、ソフトウェアとインフラの両方に興味があり、特にコンテナ技術や分散処理周りに関心を持っています。プログラミング言語としてはRustが好きです。

趣味は自宅サーバー、料理、読書です。

エキサイトのインターン以前の技術経験

研究・個人開発

大学院では複雑ネットワークと制御理論、グラフニューラルネットワークの研究に取り組んでいます。個人開発では簡単なWebアプリケーションを作成したり、自宅サーバーでインフラ周りの学習を進めています。

また、ハッカソンへの参加が好きで、これまで複数回参加してきました。ハッカソンでは主にバックエンドやインフラを担当することが多く、GoやTypeScript、AWSなどを使った開発を経験してきました。

インターンでやったこと

配属先・担当プロジェクト

BB事業部に配属され、社内向けのDB管理ツールの開発プロジェクトに参加しました。具体的には、事業に関する原価管理データの表示・検索ツールの新規開発を担当しました。

プロジェクトの背景

これまで、原価管理データの確認には既存の汎用データベース管理ツールを使用していましたが、頻繁に参照するデータであることから、専用の検索・表示ツールを開発することになりました。

実装した機能

【原価管理データ表示ツールの開発】

主な要件と実装内容は以下の通りです:

検索機能 - 契約ID、ユーザーID、日付(月単位)、データ区分、地域、カテゴリなど、複数の条件での検索機能を実装 - 異なるID体系間の相互変換機能(マスタテーブルとの連携) - 検索条件をGETパラメータで管理し、URLで検索結果を共有できる仕様

表示機能 - DataTableを使った見やすいデータ表示 - サーバーサイドでのページネーション機能(大量データへの対応) - 既存の汎用管理ツールへの編集リンク

テスト - 開発した機能に対するテストコードの作成

使用した技術スタック

  • バックエンド: PHP、Laravel
  • フロントエンド: Vue.js
  • データベース: Oracle DB
  • その他: Git、GitHub

技術的なチャレンジ

【初めての技術スタックへのキャッチアップ】

今回のインターンで最も苦労したのは、PHPとVue.jsという、これまで使ったことのない技術のキャッチアップでした。特にPHPのLaravelフレームワークは初めて触る技術だったため、フレームワークの思想や設計パターンを理解するのに時間がかかりました。

公式ドキュメントを読んだり、既存のコードベースを読み解きながら、少しずつキャッチアップを進めていきました。メンターの方にも質問をしながら、実装を進めることができました。

学んだこと

技術面での学び

アーキテクチャの理解が深まった】

今回のインターンで最も大きな学びは、ソフトウェアアーキテクチャについての理解が深まったことです。

  • MVCアーキテクチャ: Laravelを通じて、MVCパターンの実践的な使い方を学びました
  • オブジェクト指向設計: 実際のプロダクトコードを通じて、オブジェクト指向の設計原則を学び直すことができました
  • オニオンアーキテクチャ: レイヤー分けやドメイン駆動設計の考え方を知ることができました
  • 依存性逆転の原則: 特に依存性逆転については、実装を通じて理解が深まりました。抽象に依存することで、テストしやすく、変更に強いコードを書けることを実感しました

これまで個人開発やハッカソンでは、アーキテクチャをあまり意識せずにコードを書くことが多かったのですが、実際のプロダクト開発では、保守性や拡張性を考えた設計の重要性を学びました。

【Laravel・Vue.jsの習得】

初めて触るLaravelとVue.jsでしたが、一ヶ月という短い期間で基本的な機能の実装ができるまでになりました。特にLaravelのEloquent ORMやルーティング、ミドルウェアの仕組みは、今後他のフレームワークを学ぶ際にも活かせる知識だと感じました。

【メンターとのコミュニケーション】

分からないことや詰まったことがあった際に、適切なタイミングで質問することの大切さを学びました。一人で悩みすぎず、早めに相談することで、効率的に開発を進められることを実感しました。

印象に残ったこと

メンターの方々が、技術的な質問に対して丁寧に教えてくださったことがとても印象に残っています。単に答えを教えるのではなく、考え方や背景にある設計思想まで説明していただけたので、深い理解につながりました。

また、実際に使われる社内ツールの開発に携われたことで、「誰かの役に立つものを作っている」という実感を持つことができ、とてもやりがいを感じました。

今後に向けて

インターンを通じて得た気づき

今回のインターンを通じて、アーキテクチャ設計の重要性を強く実感しました。これまでは「動くコード」を書くことに注力していましたが、「保守しやすく、拡張しやすいコード」を書くことの価値を理解できました。

また、Web開発における実践的なスキルセット(Laravel、Vue.js、Oracle DB)を身につけることができ、今後の開発の幅が広がったと感じています。

これから取り組みたいこと

  • アーキテクチャの学習継続: 今回学んだクリーンアーキテクチャドメイン駆動設計について、さらに深く学習したいと思います
  • テスト駆動開発の実践: テストコードの重要性を学んだので、個人開発でもTDDを実践していきたいです
  • PHP/Laravelの深掘り: 今回学んだLaravelをさらに深く学び、モダンなWeb開発のベストプラクティスを身につけたいです
  • インフラとの統合: 好きなインフラ領域と、今回学んだアプリケーション開発を組み合わせて、フルスタックな開発ができるようになりたいです

おわりに

この一ヶ月間、エキサイト株式会社BB事業部の皆様には大変お世話になりました。実際の開発現場で働かせていただき、技術面だけでなく、チーム開発の進め方や、プロダクト開発における考え方など、多くのことを学ぶことができました。

特に、メンターの方々には技術的な質問だけでなく、キャリアについてのアドバイスもいただき、本当にありがとうございました。

このインターンでの経験を糧に、今後もエンジニアとして成長していきたいと思います。アーキテクチャやテストの重要性、チーム開発のプロセスなど、学んだことを今後の研究や開発に活かしていきます。

ありがとうございました!

エキサイト就業型インターンBooost!!!を通して

こんにちは、齋藤 丈です。 この記事は、エキサイト株式会社(https://info.excite.co.jp/internship/booost2025/)の就業型インターン「Booost!!! 2025」に参加した体験記です。

はじめに(自己紹介)

改めまして、東北工業大学 工学部 情報通信工学科 3年の齋藤 丈です。(2027年卒見込み) 将来的にフルスタックなエンジニアになることを目標に、ハッカソン参加や自主制作、複数のインターンに挑戦しています。

これまでは、PKSHA Technologyでのインターン(Vue.jsやAWS Bedrockを使用)やハッカソン(Next.jsやFlutterを使用)などで、主にフロントエンド開発AI・LLMを活用した開発を担当する機会が多くありました。

フロントエンドの経験を積む中で、その先のバックエンド、特に「保守性・拡張性を考慮したアーキテクチャ「品質を担保するテスト」といった領域を実務で深く学びたいという思いが強くなり、今回はバックエンド(PHP/Laravel)に強みを持つエキサイトのBB事業部インターンに参加しました。

この記事では、インターンで学んだ以下の点について詳しくまとめていきます。

  • 参加理由: なぜエキサイトのインターンを選んだのか
  • タスク内容: LaravelInertia.js、オニオンアーキテクチャDIP
  • ぶつかった壁: PHPUnitMockery を使ったテスト設計
  • 社内の雰囲気: ビアバッシュでの交流やメンターさんからの「金言」
  • 得られた成長: 技術面と「なぜ?」を問う思考面での変化

1. エキサイトのインターンに参加したいと思った理由

「はじめに」で述べたバックエンドのアーキテクチャを学びたいという理由に加え、実務の「型」を学びたかったからです。

具体的には、 1. 実務でのタスク管理: 課金サービスを、現場でどのように活用しているのか。 2. 要件の細かさとルール: 個人開発では曖昧にしがちな要件定義や、企業ならではの開発ルール(ブランチ戦略、レビュー体制など)を体験したい。 3. コーディングのアンチパターン: 「動く」だけでなく「保守しやすい」コードとは何か、現場でNGとされる書き方を学びたい。

という3点を強く意識しており、エキサイトのインターンはこれらを学ぶ最適な環境だと感じました。

2. 参加までの準備にあたって

インターン参加にあたり、フレームワークLaravel を重点的に勉強しました。

フロントエンドの Vue.js に関しては、直前のPKSHAのインターンでも使用していたため、コンポーネント設計の知識は活かせると考えていました。

3. 具体的なタスク内容

私が担当したのは、BB事業部で使われている社内顧客検索ツールの機能開発です。

  • 概要: 既存の管理ツールに、新たな検索機能を追加し、そのテストを実装する。
  • 技術スタック:
    • バックエンド: PHP (Laravel)
    • フロントエンド: Vue.js ( Inertia.js 経由)
    • テスト: PHPUnit
    • インフラ: AWS (EC2), Docker

Inertia.js と オニオンアーキテクチャ

今回の開発で特徴的だったのが、Inertia.js の採用と、オニオンアーキテクチャ です。

1. Inertia.js による Laravel と Vue の連携

Laravel といえば Blade テンプレートが一般的ですが、このプロジェクトでは Inertia.js を使い、フロントエンドを Vue.js で構築していました。 Controller から Blade を返す代わりに、Inertia::render() を使って Vue コンポーネントを指定し、Props としてデータを渡す仕組みです。

// (例) AbcController.php
public function index(Request $request, AbcRepositoryInterface $repository)
{
    // ...ロジック...
    $results = $repository->search($searchParams);

    // Inertia::renderでVueコンポーネントを呼び出し、Propsを渡す
    return Inertia::render('Clb/Abc/Index', [
        'results' => $results,
        'searchParams' => $searchParams,
    ]);
}

Vue.js は他のインターンでも触れていましたが、Inertia.js を介して Laravel から Props を受け取るこの形は新鮮で、フロントとバックの責務分離が明確になるメリットを感じました。

2. オニオンアーキテクチャDIP(依存関係逆転の原則)

もう一つの特徴は、ディレクトリ構造です。 単なる MVC ではなく、責務を細かく分離したオニオンアーキテクチャ(またはレイヤードアーキテクチャ)に近い構成が取られていました。

特に、メンターさんに教えていただきながら分析した Controller の実装は、DIP (Dependency Inversion Principle: 依存関係逆転の原則) の良い学びになりました。

▼ 抽象(Interface)に依存する設計

// app/Http/Controllers/Clb/Applications/AbcController.php

// Controllerは「具象クラス」ではなく「Interface」に依存している
public function __construct(
    private AbcRepositoryInterface $repository
) {
}

public function search(Request $request)
{
    // Interfaceのメソッドを呼び出すだけ
    $data = $this->repository->search($request->all());
    // ...
}

▼ DIコンテナによる具象クラスの注入

// app/Providers/AppServiceProvider.php

// Interfaceが要求されたら、こちらの具象クラスを注入する
$this->app->bind(
    \App\Repository\Clb\AbcRepositoryInterface::class,
    \App\Repository\Clb\AbcRepository::class
);

このように AbcController が具体的な実装(AbcRepository)を知らなくても動作する設計になっており、テスト容易性保守性が格段に向上することを実感しました。

4. 困難だったことと、どう乗り越えたか

実務レベルのコードベースと設計思想に触れ、多くの壁にぶつかりました。

困難1:アーキテクチャの理解と「どこに書くか」

オニオンアーキテクチャの「作法」を理解するのが最初の壁でした。 「このロジックは Controller? それとも Repository?」 「ControllerRequestRepositoryInterface 以外受け取ってはいけない?」 など、ファイル構成図とにらめっこする日々でした。

[克服] メンターの伊藤さんに質問し、AbcController の実装を例にDIPの重要性を教えていただきました。 また、DataSearchRepository の実装を読み解き、「Controller はリクエストの検証とInertia::render での応答に専念し、複雑なDB操作(Eloquent のクエリビルダを使った whereInwhereRaw など)はすべて Repository 層に隠蔽する」という責務の分離をコードレベルで学びました。

困難2:実務レベルのテスト設計 (PHPUnit)

タスクには PHPUnit によるテスト実装も含まれていました。 これまでフロントエンド開発が中心で、バックエンドのテスト、特にDBが絡むテストは本格的に書いたことがありませんでした。 メンターさんから「テスト設計が大事。Xmindなどでパターンを洗い出すと良い」とアドバイスをいただき、設計から挑戦しました。

  • 正常系: 正しいパラメータが渡された場合に、期待通りのデータが返るか。
  • 異常系: 想定外のパラメータ(null, 空文字, 異なる型...)が来た場合に、適切にエラー処理されるか。

[克服] テストコードは「AAAパターン (Arrange, Act, Assert)」を意識して書くことを学びました。

  1. Arrange (準備): テストデータ(createTestDataのようなメソッド)を用意し、Mockery を使って Repository が依存する Eloquent Model などの動作をモック(偽装)します。
  2. Act (実行): テストしたい Repository のメソッド(例: search())を実行します。
  3. Assert (検証): 実行結果が期待値(「searchメソッドが1回呼ばれたか」「返り値の配列が正しいか」など)と一致するか検証します。

Mockery を使ってDBなどの外部依存を断ち切り、テストしたいロジックだけを正確に検証する手法は、非常に大きな学びとなりました。

5. メンターとの対話と社内の雰囲気

今回のインターンで最も印象的だったのは、メンターさんとの技術的な対話、BB事業部のリアルな雰囲気、そして社内イベントでの温かい交流でした。

社内イベント「ビアバッシュ」

インターン期間中、「ビアバッシュ」という社内イベントに参加する機会がありました。

ここでは事業部の垣根を越えて多くの社員さんと交流でき、特にメディア事業部からBB事業部に異動されてきた岡崎さんのお話が非常に興味深かったです。

岡崎さんからは、ご自身のキャリアパスや、Javaフレームのメリット・デメリットなどについて伺い、さらに本選考を控える私に対して、エンジニアとしてのキャリアに関する重要なアドバイスもいただきました。

イベント後日、岡崎さんからSlackのDMで応援の声や、これからもどんどん頼ってくださいといった温かいメッセージをいただき、技術面だけでなく人としての面倒見の良さにも感動しました。

メンターさんの紹介

  • 中村さん: 困った際にすぐにGoogle meetを立ち上げてハンズオンで課題を解決まで導いてくださりました。
  • 伊藤さん: 中途入社で中村さんと同じチーム。受託開発や楽天での経験をお持ちで、特に Laravelアーキテクチャに造詣が深い方でした。

「技術的負債」と向き合う現場

BB事業部では、エキサイト独自の旧フレームワーク「BEAR」で書かれたコードが残っており、それをPHPの古いスタイルで書かれたコードと呼び、モダンな Laravel に置き換えていく過渡期にありました。

メンターの伊藤さんからは、技術選定やコーディングに関する非常に示唆に富むアドバイスをいただきました。

▼ メンターさんからの金言(一部抜粋)

  • 「(古いコードの)実装方針は真似しないでほしい」
    • → 既存コードが必ずしもベストプラクティスとは限らない。なぜそう書かれているかを疑い、より良い書き方を常に模索する重要性を痛感しました。
  • 連想配列はダメ。Laravel Collection を使って」
    • foreach で配列を回すのは旧来の書き方であり、mapfilter が使える Collection を使うことで、可読性が高く、保守しやすいコードになることを学びました。
  • 「面接では本音(どう思っているか)が大事」
    • →技術選定の理由などを「流行っているから」ではなく、メリット・デメリットを比較し、自分の言葉で語れることが重要だと再認識しました。

単に「雰囲気が良い」だけでなく、技術的負債と向き合い、どうすれば保守性や開発生産性が上がるかを真剣に議論している、非常に健全な開発チームだと感じました。

6. インターンを通してどう成長できたか

今回のインターンを通して、技術面と思考面の両方で大きく成長できました。

1. 技術面:「動く」から「保守する」への意識改革

  • アーキテクチャの理解: DIPやレイヤードアーキテクチャのメリットを、コードレベルで理解できました。
  • テスト実装力: PHPUnitMockery を使ったバックエンドのテスト設計(正常系・異常系)の重要性と実装方法を学びました。
  • モダンなPHP: CollectionEnum など、Laravel の便利な機能を活用した「読みやすいコード」を意識できるようになりました。

今回エキサイトでバックエンドのアーキテクチャとテストを深く学べたことで、Web開発の全体像(フロント、バック、インフラ、チーム開発)をより立体的に理解できたと感じています。

2. 思考面:「なぜ?」を深く掘り下げてる姿勢

メンターさんとの対話や面接練習を通じて、**「なぜその技術を選ぶのか?」**を自分の言葉で説明できることの重要性を痛感しました。

例えば、メンターさんとの面談で「Go言語に興味がある」と話したところ(趣味でUdemyで勉強中のため)、「なぜGoなのか?」「PHP(Laravel)と比べて何が優れており、何が劣っていると思うか?」「BB事業部のようなWebアプリケーション開発において、Goを採用するメリット・デメリットは?」といった深掘りをされることを知り、かなり驚きました。

単に「流行っているから」「速そうだから」といった表面的な理解では通用しないこと、技術選定の背景にあるトレードオフを自分の言葉で説明できることの重要性を痛感しました。

この経験から、今後は「プリンシプルオブプログラミング」や「達人DB」といった基礎技術書もしっかり読み込み、技術の本質的な理解を深めていきたいと強く思いました。

7. おまけ:お世話になった方々へ

メンターの伊藤さん 技術的な壁にぶつかるたび、的確すぎるアドバイスをありがとうございました。特にアーキテクチャの話や「PHPのモダンな書き方」に関する話は、今後のエンジニア人生の指針になります。「実装、真似しないでくださいね」という言葉、忘れません!

メンターの中村さん Jiraの使い方からスクラムの進め方まで、チーム開発のイロハを丁寧に教えていただきありがとうございました。中村さんのサポートのおげで、安心してタスクに進めることができました。

岡崎さん ビアバッシュでの貴重なお話や、その後の温かいDM、本当にありがとうございました。

土屋さん 一緒に一ヶ月間の開発を共に乗り越えた仲間として本当にお世話になりました!!すごく勉強になりました!!!!

BB事業部の皆様 技術的負債というリアルな課題に立ち向かう現場で、インターン生として今回このような形で受け入れてくださり、本当にありがとうございました!

8. 最後に

エキサイトのインターンは、LaravelVue.js を使ったモダンな開発フローと、DIPに基づいた保守性の高い設計思想、そして「技術的負債」というリアルな課題、そのすべてを体験できる濃密な時間でした。

フロントエンドやAI開発の経験はあったものの、バックエンドの「守り」(アーキテクチャやテスト)の重要性をこれほど痛感した経験はありませんでした。

この記事が、エキサイトのインターンに興味がある方や、「フロントの次は何を学ぼうか」と悩んでいるエンジニア学生の参考になれば幸いです。

Excite就業型インターン「Booost!!」から学べたこと

はじめに

はじめまして!10月から Booost!!! Excite Internship 2025 に参加していました、髙木と申します。
ここでは1ヶ月間のExcite就業型インターン「Booost!!」から学べたことをブログにしました!


自己紹介

情報系の大学に通っています、髙木と申します。 普段は長期インターンでDifyプラグイン開発を行っていたり、インターンに参加したり個人開発を行ったりしています。 私が "Booost!!! Excite Internship 2025" に参加しようと思った理由は、「Goを使った開発を行いたい」と「アーキテクチャの理解を深めたかった」という理由から参加しました。

今回のインターンは特に「クリーンアーキテクチャの理解を深める」を意識して臨みました。 なんとなく個人開発などでクリーンアーキテクチャは実装したことがありましたが、わかったフリで実装している部分も多かったので、理解を深めることを意識しました。


なぜアーキテクチャの理解を深めたいのか

近年、AIの早すぎる進化にプロダクト開発の在り方が変わってきていると思います。 AIのコード生成の精度の良さにコードを書く価値というものも変化しているなかで、今後は設計の部分がより重要視されるのではないかと考えています。 もちろん昔からアーキテクトは大事ではあったと思いますが、コードを書くという所に集中が減った分、設計に時間をかけることができるのでここの理解を深めておく必要があると感じました。 またシンプルに開発思想を知ることに面白みを感じたというのも理由にあります。


業務内容

配属先は SaaS・DX事業部のkuroten で、バックエンドの機能追加を担当しました。

具体的には、kurotenのメッセージ内容が古いものが表示されていたので作成された日時のものを表示する タスクです。
各層の依存関係を見ながら、メッセージ内容を更新する実装をしました。

また、別のインターンでは質問のしづらさということがあり、学習のしづらさがあったので今回は質問の仕方を変えてみたり、積極的に質問することを意識しました。 やはり、自分で長時間考えてしまうより、長年プロジェクトに関わっている方に聞く方が早く、その分学びの量も増えるので積極的に質問するべきだと痛感しました。


学び①:アーキテクチャの責務の分離

この1ヶ月で最も大きく変わったのは、アーキテクチャの考え方です。

これまでは「MVC」や「レイヤードアーキテクチャ」をなんとなく理解して使っていたのですが、クリーンアーキテクチャの思想を意識して開発を進めたことで、責務の分離の重要性を強く実感しました。

たとえば、処理の流れを「UseCase(ビジネスロジック)→ OutputPort(出力用インターフェース)→ Presenter(表示変換)」のように明確に分けることで、「どの層が何を担当しているのか」が自然と見えるようになりました。

また責務を分離することでテストや使用している技術の変更に強くなること。現代のアプリケーション開発は多くの変更を取り入れることからクリーンアーキテクチャは適していると感じました。

自分が理解した各層の責務をまとめてみます。


UseCase(ユースケース層)

「アプリケーションの中で“何をしたいか”を定義する層」

たとえば「ユーザーを登録する」「お知らせを作成する」「ログインする」といった、
アプリの具体的な操作や処理の流れを司るのが UseCase

  • 役割処理の流れを組み立てる
    • CreateUserUseCase → ユーザー情報を受け取って登録処理を呼び出す
    • SendNoticeUseCase → メッセージ送信処理の順序を定義する

ポイント
UseCase自体は「どのデータベースを使うか」や「どんなUIで表示するか」を具体的に知ってはいけない。 interfaceで定義されたメソッドを使い、抽象的に使用を徹底することでクリーンアーキテクチャの良さが発揮される。

あくまで“アプリの動き”だけを定義する。

Service(ドメインサービス層)

「業務的なルール(ビジネスロジック)の実装を担う層」

UseCaseが「やることの流れ」だとすれば、Serviceは「どうやるか」を担当する。

  • 役割:ビジネスルール(ドメイン知識)をコードで表現する
    • NoticeService → 新しいお知らせを作成し、バリデーションや日時の整形を行う
    • AuthService → 認証トークンを検証してユーザー情報を返す

ポイント
ServiceはUseCaseから呼ばれる存在で、
「どうやってドメインのルールを実現するか」を責務としている。


Infrastructure(インフラ層)

「外部とのやり取りを担当する層」

データベースやAPI、メールサーバーなど、
“外の世界”と通信する処理をまとめるのが Infrastructure の責務。

  • 役割:外部サービスとの接続部分を抽象化・管理する
    • DB接続
    • S3や外部APIの呼び出し
    • ログ設定や環境変数の管理

ポイント
Infrastructureは「実装の詳細」を扱います。
クリーンアーキテクチャでは、この層を内側(UseCase・Service)から直接参照しないようにすること。
→ 代わりにRepositoryインターフェースを通じてアクセスします。


Repository(リポジトリ層)

「データの取得・保存を担当する層」

Repositoryは、「どんなDBを使ってもいいようにするための仲介役」。

  • 役割:データの処理(CRUD)を抽象化する
    • UserRepository → ユーザー情報をDBから取得/保存
    • NoticeRepository → お知らせの一覧を返す

ポイント
Repositoryはインターフェースとして定義し、 実際の実装は Infrastructure層 に置きます。
こうすることで、「使う側(UseCase)」は“どう保存するか”を知らなくてもよく、repository層だけを知っていればいいことになる。


ここで私的に、Repository と Infrastructureの違いがわかりずらかったのでまとめてみました。

Repository と Infrastructure の違い

観点 Repository層 Infrastructure層
目的 データアクセスの抽象化を行う 具体的な実装(SQL文, ORM文)
内容 「どんな処理を行うか」をインターフェースとして定義 実際にDBや外部APIにアクセスする実装を書く
依存関係 UseCase層から呼ばれる Repositoryインターフェースを実装し、DBなどに依存
イメージ 「契約書」 「契約書の内容から働く人」

まとめると:
Repositoryは「契約書」であり、Infrastructureは「実装する人」です。
この責務の分離があるからこそ、DBの種類(MySQL → DynamoDBなど)を変えても、他の部分を変更しなくても変更することが可能になります。


Controller(コントローラ層)

「外部(HTTPリクエスト)からアプリを動かすための入口」

Controllerは、「リクエストを受け取る入り口」です。

  • 役割

    • APIリクエストを受け取る
    • リクエストデータをUseCaseに渡す
    • 結果をPresenterに渡してレスポンスを返す
  func (c *UserController) Create(ctx iris.Context) {
      input := parseUserInput(ctx)
      output := c.usecase.CreateUser(input)
      ctx.JSON(output)
  }

これによって、修正が非常にしやすくなり、「データをどう扱うか」と「どう見せるか」を完全に切り離して考えを持ったのは大きな収穫でした。

今後は個人開発でクリーンアーキテクチャ以外に挑戦し、ソフトウェア開発の思想を広げていきたいと思います。


学び②:テストコードとの出会い

もう一つの学びは、テストコードです。
恥ずかしながらバックエンド志望でありながら、テストコードの経験が皆無と言っていい程浅いです。

今回はkurotenのテストコードの書き方を見習い、そこで得た知見を業務時間外などで実装してみたりしテストに対して理解が深まったと感じています。

実務ではテストコードは多く書いていないですが、kurotenのテストコードを理解し、テストに対する知見を得られたことは本当に良かったです。


おわりに

1ヶ月の間、 "Booost!!! Excite Internship 2025" で貴重な経験を積ませていただきありがとうございました! バックエンド経験の浅い私を受け入れてくださった担当社員の方をはじめ、メンターの方には感謝申し上げます。

就業型インターンシップ「Booost!!!」を振り返る

はじめに

はじめまして!10月から Booost!!! Excite Internship 2025 に参加しておりました、大澤と申します。1ヶ月間の就業型インターンでの学びや振り返りをブログ形式まとめてみました!

自己紹介

外国語大学に通っている学部3年の大澤です。大学は情報系ではないですが、趣味でプログラミングをかれこれ10年ほどしており、大学在学中にも留学先でWeb開発を学んでおりました。

就業型インターンの経験はExciteさんが2社目で、今回は特に「チーム開発におけるソフトスキルの向上」を意識して臨みました。 前回のインターンでは、自分の中で「ソフトスキルやコミュニケーション面」に課題を感じていたため、この機会を“技術力の向上”だけでなく、“チームで成果を出すための働き方を見つける場”として位置づけていました。

業務内容

配属先は SaaS事業部 FanGrowthチーム で、フロントエンドのリファクタリング業務を担当しました。

具体的には、Nuxtで構築されていた共催募集ページをReact環境へ載せ替えるタスクです。 単なる移植ではなく、デザイン刷新も伴うため、Figmaで共有された新デザインをもとに既存のReactコードベースの方針を踏襲しながら実装しました。

また、Nuxt側の機能や仕様を引き継ぐ必要があるため、Figma上で不明点がある箇所や仕様の曖昧な部分は、積極的にデザイナーさんやメンターの方と連携して確認を進めました。 以前の自分なら「非同期コミュニケーションだから後回しにしよう」と考えていたかもしれませんが、今回は「聞くことでチーム全体の生産性が上がるか」「後々聞かないとお互いの問題になりうるか」といった観点を意識し、早めの確認を徹底しました。

学び①:ソフトスキル・コミュニケーション面での成長

この1ヶ月で最も大きく変わったのは、「質問や相談に対する心理的ハードルが下がったこと」です。 以前は“迷惑をかけたくない”や“自分のタスクだから一人で頑張らなくては”という意識が先立っていましたが、今では「チームの成果を最大化するための行動」として自然にコミュニケーションを取れるようになったと感じています。

特に意識していたのは以下のようなことです:

  • 聞くことでチーム全体の生産性が上がるかを考える
  • タスクの後続工程や影響範囲を逆算して早めに確認する
  • 同期/非同期コミュニケーションに関係なくスピード感をもって進める

そして今回は、「ただ聞けるようになる」だけではなく、“どういう時に聞くのがチームにとって良いのか”という判断を自分の中で少しずつ仕組み化することができたと思います。 たとえば、「これを今聞くことでチームの生産性が上がるか」とか、「ここで声をあげておくことで、後々のトラブルや認識ズレを防げるかもしれない」といった具合です。 作って終わりの個人開発ではないため、違和感や疑問をそのままにせずチームに言語化して共有することで、後の工程の手戻りや自分の作業効率を守れる場面も合ったのではないかと感じています。

もちろん、分からないことを全部を逐一聞く必要はありませんし、開発の暗黙のルールや優先度、タイミングの感覚――いわゆる“チームのよしな”――は最初は難しかったですが、最初のうちは意識的に少し多めに聞くことによって、その中で“どこまでが聞くべきラインか”などを体感的に掴んでいくことができました。 結果として、「聞くことに対しての抵抗」がなくなり、チームの生産性を高めるために必要なコミュニケーションだと自然に捉え・考えられるようになったことが、今回一番大きな変化だったと思います。

学び②:AIを活用した開発フローの最適化

もう一つの学びは、AIを組み込んだ開発ワークフローの確立です。 特に CursorのPlanモード と Figma MCP を活用した設計・実装支援が非常に効果的でした。

以下が自分が実際に行っていた流れです:

  1. Nuxt版のレポジトリで関連する機能・仕様・型情報をPlanモードでMarkdownとしてなるべく詳細に出力させる
  2. React版のレポジトリで、同じくPlanモードを有効にし、対応するFigmaリンクを提示
  3. 「既存コードベースの構造を踏襲する」「共通コンポーネントを優先して使用する」などの条件、実際に参考になる既存実装やコンポーネントを詳細に明記
  4. Nuxt側の仕様書を参考として貼り付け、APIや型は共通である旨を伝える
  5. フェーズを「UI実装」と「ビジネスロジック実装」に分け、まずUIから着手

このようにAIと壁打ちしながら仕様を固め、「Build」ボタンで実装開始→自分が微修正→確認という流れで効率的に進めることができました。 もちろん完璧に一発で仕上がるわけではありませんが、ベースの構築をAIに任せることで、より重要な部分(UIの細部調整やデザイン意図の理解)に集中できたのが大きな収穫です。

また、インターンの後半からは Figma MCP の活用を本格化させ、プロンプトの改善やAIとの対話方法の最適化にも挑戦し、出戻りややり直しが実際に減った感覚がありました。 AIをアシスタントとしてではなく、開発の一員としてともに考える存在として扱うことで、単なる効率化にとどまらず、より構造的に開発を進められるようになったと考えています。

今後は個人開発でも継続的に MCP や AIエージェント、git worktree などを活用して、並行開発フローをさらに発展させ自分なりのワークフローを見つけていきたいです。

おわりに

今回のインターンでは、技術的にもコミュニケーション的にも多くの学びを得ました。

チームのみなさま、メンターを担当してくださった社員の方々、質問にも丁寧に答えてくださり、チーム全体が温かく支え合う雰囲気の中で安心して挑戦できました。 1ヶ月という短い期間でしたが、自分の課題を明確に捉え、次の成長につながる手応えを感じられた時間でした。

大変お世話になりました。とても充実した、楽しい1ヶ月でした!

個人開発・学生団体を経て、Exciteインターン「Booost!!!」から学んだこと

はじめに

2025年10月から1か月間、「Booost!!! Excite Internship 2025」に参加しました。この記事では、インターンで取り組んだ内容や学んだことについてお伝えします!

自己紹介

私は、大学では機械系の学部に通う学部3年生です。普段は、同大学の文化祭実行委員会の情報局に学部1年生の頃から所属し、そこで情報系に興味を持ち、実行委員の活動をDX化するプロダクトの開発を行っています。時には、情報局のメンバーとハッカソンに出場したり、日々の生活を便利にするWebアプリを個人開発したりしています。長期間のインターンは今回が初めてでした。

インターン以外での技術経験

研究については、機械系ですが、カメラやLiDARを使用して計測・分析するような、情報系にも近いテーマで取り組んでいます。

個人開発では、生活を便利にする系統のものが多く、例えば自宅PCを遠隔起動するためのWOLアプリなどを作成しました。アプリケーション開発だけでなくインフラ分野も好きで、自宅ではミニPCなどを複数台使ってクラスター環境を構築して遊んだりもしています。

比較的最近出場したハッカソンでは、JPHACKS2024に参加し、Award Dayまで進むことができました。 過去のアルバイトでは、小中高校生向けのプログラミング指導をしていたこともありました。

インターンでやったこと

担当したプロジェクト

私は、SaaS事業部のFanGrowthチームに配属されました。 担当したのはフロントエンド開発です。このプロジェクトでは、既存機能の改修や、Vue.jsで構築されたページのReactへのリプレイスなどに取り組みました。

取り組んだ内容

開発環境構築

開発端末として高性能なMacを支給していただきました。しかも新品の状態で届いたため、とても驚いたと同時に大変嬉しかったです。というのも、私は普段Windows(厳密にはWSLのLinux)環境で開発を行っていたためです。支給されたMacは普段使いのPCよりもレスポンスが良く、非常に快適に開発作業を進めることができました。

一方で、WindowsMacとではキー配置が大きく異なるため、この点には最も苦戦しました。Windowsでは大半の操作をCtrlキーで行うのに対し、MacではCommandキーが主体であり、かつCtrlキーも別の役割で存在します。配置場所も異なるため、インターン中に何度押し間違えたかわかりません。

その他の環境面については、ターミナルは普段から使い慣れていたzshでしたし、パッケージ管理もaptのような感覚でbrewを使えたので、特に苦労はありませんでした。

また、開発ツールとしてCursorを初めて使用しました。普段はGitHub Copilotが利用できるVSCodeで開発していたのですが、Cursorでの開発はAIとの連携がよりスムーズで、貴重な開発体験となりました。

担当したタスクと実装

インターン期間中は、主にReactで作成されたページの細かな修正作業を担当しました。業務に慣れてくると、既存のVue.jsで実装されていたページをReactへリプレイスするという、より大きなタスクも任せていただきました。

このリプレイスではデザインも刷新されており、私はある管理ページに関する一連の機能開発を担当しました。具体的には、データの一覧表示、キーワードやステータスでの絞り込み機能、そして新規作成・編集・削除を行うためのモーダル機能など、フロントエンド開発全般にわたる様々なタスクに取り組みました。

このタスクでは、コードの可読性や保守性を意識した設計を特に心がけました。例えば、ページ全体でデータ取得やモーダルの開閉といった状態管理を行い、実際の表示は「一覧表示エリア」や「検索フィルター」といったUIコンポーネントに委ねることで、ロジックとビューの関心を分離しました。

特に、新規作成・閲覧・編集など複数の役割を持つ複雑なモーダル機能の実装では、そのロジックをカスタムフックとして積極的に切り出しました。フォームの入力値管理やバリデーション、API連携といったデータ操作に関するロジックと、モーダルの表示モードや確認画面の開閉といったUIの状態に関するロジックをそれぞれ別のフックに集約しました。

このようにロジックを分離することで、ビューコンポーネント側は複雑な状態管理を意識することなく、受け取った値の表示とイベントの実行に集中できる設計を目指しました。

また、一覧で表示するカードのように、多くの情報を含むコンポーネントは、その中でも「基本情報」と「統計情報」のように、役割ごとにさらにコンポーネントを細かく分割し、見通しを良くする工夫も行いました。

成長したところ・難しかったところ

技術面

今回、初めて企業で実際に運用されている大規模なプロダクトの開発を体験し、学生団体での開発や個人開発では経験できない規模のコードやファイル量に圧倒されました。

配属先のプロダクトでは、専用のUIコンポーネントが整備されており、Storybookも充実していたため、フロントエンドの作成については仕様に慣れてしまえばスムーズに進めることができました。

開発中は、効率を上げることを特に意識していました。例えば、フロント側で叩くAPIの仕様や、リプレイス対象である旧Vue実装のページでどのような処理が行われているかをAIにリサーチ・要約させている間に、自分はFigmaのデザインを基にReact側のUIを作成する、といったプロセスを試していました。

また、プルリクエストを出すと自動的に gemini-code-assist によるコードレビューが実行される仕組みがあり、その指摘が非常に的確で、コード品質を担保する上で大変参考になりました。それだけでなく、メンターの方からいただけた的確なレビューや、時にはコードについて褒めていただけたことも、大きな励みになりました。

非技術面

コミュニケーションツールとしてTandemというサービスが導入されていたのが印象的でした。これは単なるボイスチャットツールとは異なり、同じルームにいると、他の人が始めた1on1の話し声も少しだけ聞こえる仕組みになっていました。これにより、まるで実際に同じオフィスにいるかのような感覚で、他の方々がどんな作業を進めているのかをなんとなく感じ取りながら自分のタスクを進めることができ、非常に面白い体験でした。

Tandem以外にも、Slackなどを通じて質問や相談がしやすい空気感があり、非常にありがたかったです。

また、期間中にはオフラインでのイベントにも参加させていただき、同時期にインターンに参加していた他の学生の皆さんとも交流する機会がありました。自分とは異なる分野で頑張っている方々の話は大きな刺激になりましたし、特にAIを開発にどう活かすかといった点でうまく活用しようと取り組まれている様子は、参考にできることが多かったです。

また、開発の進め方についても大きな学びがありました。特にリプレイスのタスクでは、機能ごとにタスクが分割されていたため、全体像を把握し、「次のタスクのことを想定して機能を整備する」といった見通しを立てて開発することの難しさを感じました。同時に、もしかしたら次のタスクは別の方が担当するかもしれない、という可能性も念頭に置いて開発することが、実務では必要なのだというマインドセットも身につきました。

チームでの開発サポートも手厚く、定期的な振り返りの場では、メンターの方が進行状況や困りごとがないかを丁寧に確認してくださったため、安心してタスクを進めることができました。

おわりに

1か月という短い期間でしたが、SaaS事業部のFanGrowthチームの一員として、実務でのフロントエンド開発に携われたことを大変嬉しく思います。

学生団体の開発では経験できなかった規模のプロダクトに触れ、特にビューとロジックを明確に分離するカスタムフックの設計や、再利用性を考慮したコンポーネント分割の重要性を改めて感じられました。

また、技術面だけでなく、TandemやSlackを通じた活発なコミュニケーション、オフラインイベントでの他の学生との交流、そしてタスクの見通しを立てて開発するマインドセットなど、チーム開発における非技術面での学びや気付きも非常に多かったです。

メンターの方をはじめ、手厚いサポートと的確なレビューで支えてくださったチームの皆様、そしてこのような貴重な機会を提供してくださったエキサイト株式会社の皆様に、心より感謝申し上げます。ありがとうございました!

Booost!!! Excite Internship 2025 でのエンジニア業務体験記

はじめに

初めまして!2025年10月の1ヶ月間 "Booost!!! Excite Internship 2025" に参加させていただいた、加藤といいます!

この記事では、このインターンシップで私が取り組んだ業務内容や、そこから得た学び等について紹介していければと思います。

自己紹介

私は情報工学専攻の修士1年生です。研究室の方では、AIの応用領域の研究を行っています。

私が "Booost!!! Excite Internship 2025" に参加しようと思った理由は、リアルなITエンジニアの業務を体験して、エンジニアとして働くことの解像度を高めたかったためです。

インターンシップでの業務内容

概要

「お悩み相談室」というサービスの中の「コラム詳細ページ」の、旧実装から新実装への移植作業を行いました。旧実装と新実装では、データ取得方法やアーキテクチャの構造などが異なるため、旧実装の実装内容を理解した上で、新実装のアーキテクチャの形式に変換していくことが求められる業務でした。

以降の説明では、新実装のアプリケーションを「本実装」として、新実装の説明を行っていきます。

本実装のアーキテクチャ構造

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

本実装では、レイヤードアーキテクチャ(層構造の設計)を採用しています。具体的には、以下のように役割ごとに層を分けて、それぞれが連携して動作するアプリケーションとなっています。

【リクエストの流れ】
ユーザのブラウザ
    ↓
① Controller層(入力の受付、案内係)
    ↓
② UseCase層(ビジネスロジック係)
    ↓
③ Repository層(データ取得係)
    ↓
④ ViewModel層(表示用データ整形係)
    ↓
⑤ View層(HTML表示係)
    ↓
ユーザのブラウザに表示
Controller層

リクエストを受け付け、UseCase と ViewModel を呼び出し、最終的に View に表示を指示する、司令塔の役割を果たします。ここにはビジネスロジック(複雑な計算や判断)は書かず、処理の振り分けに専念します。具体的には以下のような処理を行うことが考えられます。

<?php
/**
 * ユーザ一覧ページを表示する
 */
public function index(Request $request): View
{
     // 1. UseCaseにデータの取得を依頼
     // (例: 'active' ステータスのユーザのみ取得するよう依頼)
     $userDomainData = $this->fetchUserListUseCase->execute('active');

     // 2. 得られたデータをViewModelに渡してデータの整形を依頼
     // (ドメインデータを、Viewが表示しやすい形に加工)
     $viewModel = $this->userListViewModel->build($userDomainData);

     // 3. 得られたデータをViewに渡してデータの表示を依頼
     // (Laravelの view() ヘルパー関数)
     return view('users.index', [
         'viewModel' => $viewModel // 整形済みデータをViewに渡す
     ]);
}
UseCase層

アプリケーション固有のビジネスロジックを実行します。具体的には以下のように、Repository からデータを取得し、必要な処理を加えます。

<?php
/**
 * ビジネスロジックを実行する
 */
public function execute(string $status): array
{
    // 1. Repositoryにデータの取得を依頼
    $allUsers = $this->userRepository->findByStatus($status);

    // 2. 得られたデータにロジックを適用
    // (例: ビジネスルールに基づき、スコアが100以上のユーザのみに絞り込む)
    $highScorers = [];
    foreach ($allUsers as $user) {
        if ($user->score >= 100) {
            // (例: ビジネスルールに基づき、名前を大文字に変換する)
            $user->name = strtoupper($user->name);
            $highScorers[] = $user;
        }
    }

    // 3. データを返却する (ドメインデータ)
    return $highScorers;
}
Repository層

データベースやJSONファイルなど、具体的なデータ保存場所とのやり取りを記述します。「どこから」「どうやって」データを取るかはこの層だけが知っている、すなわち、データ取得方法が隠蔽(抽象化)されているため、Repository層のデータ取得方法が変わったとしても、呼び出し側(UseCase)は影響を受けません。具体例は以下のようになります。

<?php
/**
 * データを取得する
 */
public function findByStatus(string $status): array
{
    // 1. JsonファイルやDBなどからデータを取得
    
    // (例: Eloquent ORM を使う場合)
    $users = User::where('status', $status)
                 ->where('deleted_at', null) // 削除済みは除外
                 ->get();

    /*
    // (例: クエリビルダ を使う場合)
    $users = DB::table('users')
               ->where('status', $status)
               ->get();
    */
    
    // 2. データを返却する (例: 配列に変換)
    return $users->toArray();
}
ViewModel層

UseCase から受け取ったドメインデータ(ロジック適用済みのデータ)を、View がそのまま表示できる形式に加工します。ViewModelで事前に整形を行うことによって、Viewファイル内で複雑な処理を書かないようにしています。具体例は以下のようになります。

<?php
/**
 * データを表示用に加工する
 */
public function build(array $userDomainData): self
{
    $this->userCount = count($userDomainData);
    $this->pageTitle = "ユーザ一覧 (" . $this->userCount . "名)";
    
    $processedUsers = [];
    
    // 1. Viewで使いやすいようにデータを表示用に加工
    foreach ($userDomainData as $user) {
        
        // (例: 登録日を 'Y年m月d日' 形式にフォーマット)
        $joinedDate = Carbon::parse($user['created_at'])->format('Y年m月d日');
        
        // (例: Viewでの強調表示フラグを追加)
        $isPremium = $user['plan_type'] === 'premium';

        $processedUsers[] = [
            'displayName' => $user['name'] . '様', // '様' を付ける
            'joinedFormatted' => $joinedDate,
            'isPremiumUser' => $isPremium,
        ];
    }

    $this->displayUsers = $processedUsers;

    // 2. データを返却する (自分自身のインスタンス)
    return $this;
}
View層

Controller から渡された ViewModel のデータを使って、HTMLを組み立てます。複雑なロジックは書かず、「表示するだけ」に徹します。具体例は以下のようになります。

{{--
  $viewModel (UserListViewModelのインスタンス) を
  Controllerから受け取る
--}}

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>{{ $viewModel->pageTitle }}</title>
    <style>
        /* ViewModelのフラグに応じてスタイルを適用 */
        .premium {
            font-weight: bold;
            color: gold;
        }
    </style>
</head>
<body>
    {{-- 1. 受け取ったデータをHTMLとして表示 --}}
    
    <h1>{{ $viewModel->pageTitle }}</h1>
    <p>合計 {{ $viewModel->userCount }} 名のユーザーが見つかりました。</p>

    <ul>
        {{-- $viewModel内の加工済みリストをループ処理 --}}
        @foreach ($viewModel->displayUsers as $user)

            {{-- ViewModelのフラグを使ってCSSクラスを動的に変更 --}}
            <li class="{{ $user['isPremiumUser'] ? 'premium' : '' }}">
            
                {{-- ViewModelで加工済みのデータを表示するだけ --}}
                <strong>{{ $user['displayName'] }}</strong>
                (登録日: {{ $user['joinedFormatted'] }})
            </li>

        @endforeach
    </ul>

</body>
</html>
なぜこんなに複雑な構造にするのか?(アーキテクチャの設計思想)

各層が1つの役割だけを持って独立することで、どこを修正すればいいかが明確になり、個別にテストが行いやすくなり、将来の変更に強くなります。これを「責任の分離」といいます。

例えば、

  • 表示が崩れた → View層だけ修正
  • データ取得方法を変更 → Repository層だけ修正
  • ビジネスルール変更 → UseCase層だけ修正
  • Laravelから別のフレームワークに移行 → Controller, ViewModel, View だけ変更

のように修正すべきファイルを明確にし、将来の変更に強くなります。

アーキテクチャの設計思想についてより詳しく知りたいと思った方は、以下のWebページ等を参考にしてみてください。

クリーンアーキテクチャ完全に理解した · GitHub

Model View ViewModel - Wikipedia

UseCase層、Repository層に見られる3ファイル構成について

この設計では、UseCase層、Repository層が3種類のファイルで構成されています。これは契約(Interface)、データ転送(Output)、実装(Implementation)を明確に分離する設計パターンです。

Interface

この機能(UseCase、Repository等)が「何を受け取り」「何を返すか」だけを定義します。つまり、チーム内の「合意」であり、使う側はこの契約書だけを見て開発できるようになります。具体例は以下のようになります。

<?php
/**
 * 契約書 (Interface)
 *
 * 役割: 「ユーザー一覧を取得する」機能の仕様を定義する。
 * - 入力: (string) $status ... 'active' や 'pending' などの状態
 * - 出力: (FetchUserListOutput) $output ... 専用のデータ構造
 *
 * 呼び出し側(Controller)は、このInterfaceにのみ依存する。
 */
interface FetchUserListUseCaseInterface
{
    /**
     * ユースケースを実行する
     *
     * @param string $status 取得したいユーザーのステータス
     * @return FetchUserListOutput 処理結果のデータ構造
     */
    public function handle(string $status): FetchUserListOutput;
}
Output

返すデータの型と構造を厳密に定義します。ロジックを持たず、型がすべてを語ります。これは Data Transfer Object (DTO) と呼ばれます。具体例は以下のようになります。

<?php
/**
 * データ構造 (Output DTO)
 *
 * 役割: FetchUserListUseCase の戻り値の「型」。
 * "型が語る"ドキュメントであり、コメントは不要。
 * ロジックは一切持たない。
 */
final class FetchUserListOutput
{
    /**
     * @param UserOutputData[] $users ユーザー情報の配列 (下のクラスを参照)
     * @param int $totalCount 取得した総数
     */
    public function __construct(
        public readonly array $users,
        public readonly int $totalCount,
    ) {
    }
}

/**
 * データ構造 (Output DTO の一部)
 *
 * 役割: $users 配列の中身の「型」。
 */
final class UserOutputData
{
    public function __construct(
        public readonly string $id,
        public readonly string $displayName,
        public readonly string $joinedDateFormatted, // 例: '2025/10/28'
        public readonly bool $isPremiumUser,
    ) {
    }
}
実装クラス

Interface で約束した機能を実際に実装します。ロジック、データ加工、データ取得など、具体的な処理はすべてここで行います。具体例は以下のようになります。

<?php
/**
 * 実装クラス (実際の処理)
 *
 * 役割: FetchUserListUseCaseInterface の契約(handleメソッド)を実装する。
 * ビジネスロジックはここにカプセル化される。
 * このクラスは将来的に何度でも書き換え可能。
 */
class FetchUserListUseCase implements FetchUserListUseCaseInterface
{
    // 依存するのは Repository の「Interface」
    private UserRepositoryInterface $userRepository;

    public function __construct(UserRepositoryInterface $userRepository)
    {
        $this->userRepository = $userRepository;
    }

    /**
     * {@inheritdoc}
     * 契約(Interface)で決められた処理を実行する
     */
    public function handle(string $status): FetchUserListOutput
    {
        // 1. Repositoryからデータを取得 (これは生のDBデータやドメインモデル)
        $domainUsers = $this->userRepository->findByStatus($status);

        // 2. ビジネスロジックの適用
        // (例: 登録から1年以上経過したユーザーのみに絞り込む)
        $filteredUsers = array_filter($domainUsers, function ($user) {
            return Carbon::parse($user->created_at)->diffInYears(Carbon::now()) >= 1;
        });

        // 3. 「Output」のデータ構造に変換する
        $outputUsers = [];
        foreach ($filteredUsers as $user) {
            
            // (ロジック: '様' を付ける、日付をフォーマットする)
            $displayName = $user->name . '様';
            $joinedDate = Carbon::parse($user->created_at)->format('Y/m/d');
            $isPremium = $user->plan_type === 'premium';

            // DTOに詰める
            $outputUsers[] = new UserOutputData(
                id: (string) $user->id,
                displayName: $displayName,
                joinedDateFormatted: $joinedDate,
                isPremiumUser: $isPremium
            );
        }

        // 4. 最終的な「FetchUserListOutput」の型で返却する
        return new FetchUserListOutput(
            users: $outputUsers,
            totalCount: count($outputUsers)
        );
    }
}
なぜ3ファイルに分けるのか?

UseCase層がRepository層を呼び出す実装において、普通の実装を行うと、高レベルのモジュール(UseCase)が、低レベルのモジュール(Repository)の実装を知っている状態、すなわちUseCase層がRepository層に依存する状態になります。これは、ビジネスロジック(UseCase)が、インフラ(DB)の都合によって変更されてしまう、脆い(もろい)設計といえます。このような状態を解消するためには、抽象(Interface)を用いた設計が有効です。高レベルモジュールが低レベルモジュールのInterfaceのみを見て実装を行うことによって、高レベルモジュールが低レベルモジュールの実装に依存することを避けることができます。この時そのInterfaceを実装するのは低レベル層であるため、普通の実装における「高レベル層→低レベル層」の実装の依存関係から、「低レベル層→抽象(高レベル層が参照)」の実装の依存関係に変わります。このことを「依存性の逆転」と呼びます。

達成した業務内容

コラム詳細ページについて、Controller層、UseCase層、Repository層、ViewModel層、View層をすべて実装し、テストの作成・実行を行いました。

学んだこと・得られた経験

PHP、Laravelの業務経験

私は、本インターン参加前の時点で他の言語の開発経験はあったのですが、PHPは完全未経験でした。そのため、一からキャッチアップしながら業務に従事しました。業務で扱ったアプリケーションは規模が大きく、使用しているアーキテクチャも複雑な構造を持っていたので、キャッチアップに時間がかかってしまい、序盤のうちはなかなか思ったような実装を行うことができませんでした。そんな中でも担当社員の方が丁寧にアプリケーションについて教えてくださったおかげもあり、少しずつ理解が進んでいき、実装を行うことができました。

この、完全未経験の言語での開発を一からキャッチアップして、大規模アプリケーションへの実装を行うことができた経験というのは、自分の中で非常に大きなものになったのではないかと感じています。

リアルなエンジニア業務経験

インターンではかなりエンジニアのリアルに近い実務経験を積めたのではないかと感じています。その理由は以下の通りです。

  • 実際に社内で開発しているアプリケーションの実装を行えた
  • 社内規定に従ってプルリクエストを出し、社員の方からレビューをいただいて修正する経験を積めた
  • 開発チームの週次ミーティングに参加して、自分も開発チームの一員として進捗報告を行い、他の人の進捗報告を聞くという経験を積めた

インターンでの業務を経て、「エンジニアとして働く」ということの自分の中のイメージがより具体化されたと考えています。

おわりに

1ヶ月の間、 "Booost!!! Excite Internship 2025" で貴重な経験を積ませていただきありがとうございました!PHP未経験の私を一から導いて下さった担当社員の方をはじめ、私を受け入れてくださった社員の皆様に感謝申し上げます。

エキサイト就業型インターンBooost!!!を通じてバックエンドのアーキテクチャについて学んだこと

はじめに

こんにちは!2025年9月の一ヶ月間、エキサイト株式会社のBB事業部で就業型インター ンシップ「booost!!」でバックエンドコースでインターンに参加させていただいた小椋遼 太郎です。今回はインターンで学んだことを振り返り、紹介します。

自己紹介

私は大学3年生で、大学では情報系の学部に通っています。これまでは大学のプログラミ ングサークルやハッカソンでチーム開発をしながら、個人開発としてビジネス的視点も身 につけながら音楽関連のwebアプリを作成をしていました。サークルに入って本格的に勉 強をし始めたのは大学2回生の秋冬からだったのもあり、バックエンドのエンジニアとし ては初めてのインターンシップでした。

インターンシップの業務内容

BB事業部のAPIがBEAR.SaturdayというPHPの独自フレームワークを使用しており、 そのAPIをLaravelに移行するという業務に取り組みました。私はRuby on Railsや Next.jsなどは使用したことあったのですが、Laravelに触れるのは初めてでした。しかし 後にも触れる設計のおかげもあり、PHPも特段ストレスなく書くことができました。

学んだこと

このインターンで得られた学びはとても大きいものでした。以下にバックエンドエンジニ アとしての根本的な知識の部分と、それらを元にした実践の設計的な知識の二つに分けて まとめようと思います。

原則的な知識

まずインターンの中で共有していただいた資料であったり、書籍であったりからエンジニ アとしての基本的な考え方を身につけることができました。その中から重要であると感じ たものをまとめます。

命名規則の重要性

関数や変数の名付け行為は最重要であり、関数や変数がどんな役割を持っているのか関数 名で把握ができると可読性が大幅に向上します。名付けが適切でない場合、コードを詳し く読み、実装内容を理解する時間が必要になってしまいます。今後の修正するときの時間 を減らすためにも命名は重要だと学びました。

YAGNIの原則

YAGNIは「You Aren't Going to Need It.」の略で、日本語訳で「それはきっと必要にな らない。」という意味です。多分必要になるだろうでコードを書いてはいけない、というこ とを表しています。拡張性を考慮したコードを最初から書く必要はなく、必要になってか ら書くという大切だという基本的な原則を学びました。

KISSの原則

KISSは「Keep It Simple, Stupid」の略であり、日本語訳で「シンプルにしておけ、愚か 者よ。」という意味です。これはコードを書く時、最優先の価値を単純性や簡潔性におく、 というものです。常に複雑にならないようにシンプルに保ち続けるという根本的な原則を 示しています。覚えた技術を無理に披露しない、将来の必要に備えた過剰なコードを書か ない、わかりやすい簡潔なコードを書くという意識を持たせてくれました。

SOLIDの原則

SOLIDの原則はS(SingleResponsibility):単一責任の原則、O(Open-Closed):オープン クローズドの原則、L(Liskov Substitution):リスコフの置換原則、I(Interface Segregation):インターフェース分離の原則、D(Dependency Inversion):依存性逆転の 原則の頭文字であり、これらはコードを書くうえで問題を起さずにコードを書く、チーム 開発では必須の知識だと感じました。その中でも重要だと感じたものを説明します。

  1. 単一責任の原則はクラスが一つの責任(変更可能性)しか持たないようにするというもの です。これにより変更が発生した場合、他のクラスやファイルも変更しなければいけない という自体を防ぐことができます。
  2. オープンクローズドの原則は、拡張にはオープンで変更にはクローズドであるべきだ、 というものです。クラスの内容は変更せず、機能を追加することでそのクラスが使われて いるクラスのエラーを防ぐことができます。
  3. 依存性逆転の原則は、上位モジュールは下位モジュールに依存してはならない、どちら も抽象化に依存するべきだ。というものです。まずここでいう上位モジュールは動作を実 行するクラス、下位モジュールは動作を定めているツールです。抽象化とはインターフェ ースを指します。この原則ではクラスはツールの内容を知るべきではなく、ツールはイン ターフェースの要件を満たすべきであり、そのインターフェースにクラスは依存するべき である、というものです。この原則ではインターフェースを導入し、上位クラスが下位ク ラスに依存することを目的とした原則で、重要な考えだと感じました。

設計的な知識

開発するにあたって、先に挙げた原則的な知識を前提としてアーキテクチャについて考 え、実装していく必要がありました。実装するにあたって重要だと感じた知識をまとめま す。

関心の分離

関心とはソフトウェアの機能や目的のことを意味します。つまり関心の分離とは、それぞ れの機能や目的に関連するコードをまとめて、他のコードから分離するということです。 設計技法においてはMVCなどのパターンが挙げられます。(ビジネスロジック、ユーザー 表示、入力処理のように分離)。またこのときビジネスロジックをコントローラーにまとめ て書いてしまうとfat-controllerになってしまいます。これだと先ほど挙げた単一責任の 原則に反してしまったり、可読性が下がったりなどのデメリットがあります。可読性が下 がると、保守を行なっていく際に莫大な労力がかかってしまうので、多少開発の時の手間 を考えても、repositoryやserviceなどでビジネスロジックやDBロジックのように分離 することで解決するべきだと感じました。

インターフェースと実装の分離

先に挙げた依存性逆転の原則から、インターフェースを実装することが望ましいことを学 びました。具体的にはRepositoryのinterfaceやServiceのinterfaceを実装すること で、クライアントへの影響を考えず、実装の修正を行うことができます。具体的なコード 例に関しては他の方が記事で書いているので、ぜひ読んでみてください。

変更容易性

変更容易性とはどれだけ容易に変更することができるかを表す度合いです。設計を行う際 は、簡単に修正、拡張できるか意識する必要があります。特に保守を行うサービスでは変 更が容易である必要があると実感する場面がありました。変更容易性を高めるために、設 計や開発の中で特に意識すべきだと思うのは、 1. 変更があったときに副作用を最小にできるアーキテクチャであるかを考えながら開発を行うこと 2. ソフトウェアの開発環境を変化させた時の移動のしやすさを考慮すること だと感じました。また、単一責任の原則を守っていれば変更容易性も高く保つことができ ます。

再利用性

プログラミングにおいて重複したコードはよろしくないです。それは意味的でも機能的で も当てはまりますが、それを避けるため共通部分はなるべく切り出してメソッドを作成し たり、一般化したメソッドを書く必要があります。モジュールごとに関心を分け、再利用 ができるメソッドが望ましいとコードを書く中で学びました。

MVC+RSの学びやすさ

今回、これまであげたようなエンジニアとしての前提知識であったり、設計する上での基 本的な知識を身につけることができたのは、API移行先の設計がクリーンアーキテクチャ ベースのMVC+RSであったことが大きいと感じています。このアーキテクチャでは、こ れまであげたような原則的な知識の実践例が示されており、得た知識を適切な形で活かす ことができました。これまでは、設計に対して何も知らなかった私が、一つの正解例のよ うな設計を勉強しながら知識をつけることができたので、ある程度設計における理想と、 自分のコードの良し悪しの基準を持つことができるようになりました。

最後に

最後になりますが、本インターンでメンターをしてくださった方々、面接をしてくださっ た人事やエンジニアの方々、お時間をいただきインタビューをさせて下さった方、面談を 重ねてインターンをサポートしていただいた人事の方、インターンの開催に尽力していた だいた株式会社エキサイトの方々、本当にありがとうございました。 丁寧なバックアップ体制と環境でバックエンドエンジニアとして成長できたと感じていま す。 他の予定と重なってしまいほぼ2週間と少しの短い間でしたが、本当にお世話になりまし た。充実したインターンシップをありがとうございました。

就業型インターン「Booost!!!」の振り返り

自己紹介

私は、現在、情報系大学の情報メディア工学科の3年として在籍をしております。
プログラミング自体は大学からスタートで、関数? 構造体?なんじゃそれと超がつくほどの初心者でした。
そこから時間を見つけては自主学習をしてみたり、個人開発で商品在庫管理アプリを作ってみたり、ハッカソンインターンに参加をしボコボコにされたり、と色んなことを経験してきました。
これまで参加してきたサマーインターンでは、期間が短いのもあり、がっつり会社の実務を経験することはなく、インターンで実際の業務に取り組んで成果を出すというのは、今回が初めてでした。

配属先で取り組んだこと

Life&Wellness事業部で、電話占いサービスにおいて、特定の占い師を目立たせるバッチを表示する機能の改修に取り組みました。

具体的に行ったタスク

バッチ表示対象の占い師の先生の情報が入っているDBテーブルを新規作成
バッチ一覧取得 GET API 作成
バッチ登録 POST API 作成
GET、POSTAPIに対するテストコード作成
APIで叩いたレスポンスを用いてフロント側で表示させるための橋渡し(Repositoryの作成)

自分が得られた学び

クリーンアーキテクチャの概念について

元々、Go + クリーンアーキテクチャで、バックエンドを作っていたのもあり、概念については押さえていました。
クリーンアーキテクチャで重要なことは以下の3つだと思います。

  1. controller → usecase → repository → infrastruture(外部DB,外部API) という外から内へ依存すること(依存性逆転)
  2. 依存性逆転には、interfaceを利用し、抽象化されたものに依存するようにする。→ 実機能ではなくあくまで抽象化された機能に依存しているため、依存先の変更による影響を受けない。これがコードの保守性・拡張性、モックによる差し替えが簡単でテストのしやすさに繋がる。
  3. controllerはHTTP処理のみ、repositoryは、DBの永続化処理のみなどの責務の分離

今回はこれに加えて、service層やviewModelなどより細かい層に分割していました。
これは、規模が中規模〜大規模であるからが故に、細かく分割しているのかな?と思っていたのですが、開発チームごと文化が反映された形が今のアーキテクチャだと教えてもらいました。
実務でクリーンアーキテクチャが実際にどのように構築されているかを見て、どう動いているのかを確認する経験はとても貴重なものになりました。
また、実装する処理について、どの層に担わせるのが適切かを考える良い機会にもなりました。
例えば今回の、バッチを付与するかしないかの判断では、当初ビジネスロジックに関する処理のため、usecaseにその処理を書けばいいのでは?と思っていたのですが、これは、バッチを付与する + 他のキャンペーン処理など複雑な処理を実装する場合は、usecaseに担わせるべきですが、今回は対象の占い師の先生が取ってこれる、存在しているのならバッチを付与して表示するというシンプルな実装なので、ViewModel側でいるかいないかの判定メソッドを作成して、Bladeで表示という形が一番適切だと知ることができました。
しっかりと根拠や理由を持った上で、実装を行わなければ、後で自分が何をしているのかわからなくなってくる問題が起きるのだなと分かりました。
今後しっかり判断するための軸を持った上で実装に取り組まなければと感じました。

不要なtry/catchの使用 (なんとなくで実装しない・書いたコードに責任を持つ)

自分は普段の開発の時、APIを叩いた時try/catchで囲む癖がありました。
今回のコード作成でも、try/catchを多用してしました。
しかし、例外を出す必要性がないため、try/catchを使わなくていいというレビューをいただいた時、自分って特に理由や背景も持たずになんとなくでtry/catchを使用しているのは?と思い、try/catchについてもう一度復習することにしました。

try/catchを使う際に考えるべきことは以下の2点だと考えています。

  • try内でエラーが発生する可能性ないなら、そもそもtry/catchを使う必要がない。
  • catchとしてはtryで拾ったエラー(例外)に対して追加で新しい処理を加えたい場合に使用される(catchの用途の一つ)

自分はここら辺のことを何も考えずに、API処理に対して、try/catchで囲っていました。
これは良くない動きをしたなと反省しています。
就業中に、エンジニアとして自分の作った処理、実装に責任を持たないといけないと教えていただきました。
大切なのは、コードに対してなぜこの実装をしたのか?どういう背景なのか?の根拠を持って実装することであると、それが責任を持つことだと学ぶことができました。
自分の作ったコードに対して、理由や根拠をしっかり持つことは今後の開発でも活かすことができると思った重要な概念でした。

依存性注入について

テストコードの作成は、今回が初めてでした。テストコードの作成が一番難しかったです。
GETAPI、POSTAPIそれぞれに対しての作成に取り組んだのですが、特に印象に残っている部分は依存性注入についてです。
特に時間について取り扱うときに、依存性注入の考えが必要になります。
テストをする時、input に対して output が不変なものが求められます。
実行ごとに結果が変わっている時、テストがうまくいっているのか判断ができないからです。
時間というのは、実行ごとに値が変わってしまう変化があるものです。これを不変なものにしたいです。
その時に使われる方法が依存性注入という方法で、テスト関数が外部のオブジェクトに依存するように仕向けたものです。
具体的には、時間に関するクラスのインスタンスを外部で生成してから、その値を関数に渡すことで、外部に依存させるようにする。
これによって、時間が不変なものでなくなり、テストとして求められる形になります。
この概念は今まで学んだことがなかったので、テストをする際はただコードを作っているだけでなく、様々なことを考慮して作らないといけないのだなと面白い発見が多々ありました。

開発する時に特に意識したこと (自分が普段から意識していること)

教えてもらった内容、アドバイスを聞いて終わりにしない

人間は忘れやすい生き物です。
聞いてそうなのねとその時理解できていても時間が経てばやっぱり忘れてしまいます。
朝会や質問中に教えていただいた内容は、終わってから必ず自分でもう一度整理することをしています。
これには以下の2点の目的があります。

  1. 記録として残しておくことによって、振り返りをしやすくするため。
  2. 自分で本当に理解しているか?言語化できるか?を確認するため。

2については、特に重要です。自分が目指しているのは、小学生にも説明できるレベルで言語化が行えるかということです。
このインターンで一番避けたかったのが、わかった気になっているということです。
なので、わからないなと思った部分は、素直にわからないと言って、ぼんやりとした理解から確固たる理解へと落とし込みました。ただでさえAIが発達していて、エンジニアとしての在り方が変わろうとしています。
AIは、自分の持っている知識0から1の1を10や20にしてくれる存在だと思っています。
逆を言えば、AIが0から1を生み出すことはできない、必ず人間の手が必要になります。
自分で理解することをサボってしまうと、AIの答えが果たして正しいものなのか?求めているものなのか?の判断すらできないと思います。
なので、私はしっかり理解した知識を自分のものにするということを現在、今後も大事にしていこうと思います。

積極的にコミュニケーションを取ること

就業期間中は、積極的にコミュニケーションを取ることを意識しました。
具体的には、自分の業務の進捗や状況をslackの自分のチャネルに発信することをしました。
これは、自分で抱えていることが正しいことなのか、それとも違っている部分があるのかを判断することができず、情報を開示して第三者に見てもらうことによって、ズレや認識の違いを早急に知れたらという考えがありました。
また、疑問点は、なるべくすぐ質問することを徹底しました。
しかし、積極的に質問をしすぎたあまり、相手の時間を多く取らせてしまった部分もあり、あるいは自分で調べれば解決できそうな内容ももしかしたらあったのでは?と思いました。
これについては、

  1. 事前に質問内容をまとめる
  2. 会話を始まる前に、〇〇の2点について質問したいですと要件を伝える

これらを意識するだけでも、相手側がどれくらいの時間がかかるかの見積もりを行えるので、その配慮を行うべきだったと反省しています。

最後に

今回のインターンシップでは文章に書ききれなかった部分も含めたくさんの学びや成長をすることができました。特に、機能実装を達成できたのは、メンターの方々の丁寧なご指導や支援があったからそこで来たと思っております。心より感謝申し上げます。また、面談によって支えて下さった人事の皆様にも重ねてお礼申し上げます。今回の就業型インターンは、毎日楽しく業務をすることができ、このインターンをやってよかったと心から思っております!短い時間でしたが、貴重な機会をいただき、本当にありがとうございました。

Booost!!! Excite Internship2025を通して学んだこと

はじめに

Booost!!! Excite Internship2025に9月から1ヶ月の間参加させていただきました、戸井と申します。ヘルスケア事業部で開発を行ったので、インターンの振り返りをブログ記事としてまとめようと思います。

自己紹介

情報系の大学院で、ソフトウェア工学(特にLLMを用いたコード生成)の研究を行っています。趣味は漫画や本を読むこと、食べること、ゲーム、体を動かすことです。 最近はAIエージェントに興味があり、エージェントをシステムに導入した個人開発をやろうかなと考えてます。

個人開発やチーム開発での開発経験はありますが、完全に実務での開発は初めてです。

やったこと

ヘルスケア事業部でお悩み相談室の開発に参加させていただきました。具体的には、以下のタスクを行いました。

  • 新規登録ページにLINEアカウントによる登録ボタンを設置
  • 記事一覧ページの移植

技術面での学び

大規模なコード量を持つプロジェクトの開発

大規模なコード量を持つ「お悩み相談室」の開発に携わる中で、コードの流れや設計思想を理解する力が身につきました。

お悩み相談室はクリーンアーキテクチャで設計されていて、開発を始めた際はどういう処理が行われているか、全く理解できませんでした。 そこで、View、Controller、Reposiotryといった各責務の流れ通りにコードを読み進めることから始めました。その結果、処理の流れや、コードで何が行われているかよく理解でき、責務についての理解も深まりました。

大規模コードを持つプロジェクトはコード量が多いので、最初にコードを読んで流れを理解することが重要だと実感しました。

責務の分離への理解

Model、Controller、Viewなどのアーキテクチャ概念は知っていましたが、インターンでより責務分離について理解することができました。

例えば、以下のViewでは、ViewModelで定義しているisLoggined関数を使用して、ログインしている際に特定のバナーを表示しています。しかしこのコード、責務の分離という観点では適切ではありません。

final class FunctionIndexGetController extends Controller
{
    public function __construct()
    {
    }

    public function __invoke(Request $request): View | RedirectResponse
    {
        // ViewModelを取得
        $vm = new FunctionIndexViewModel();

        return view('pages.function.index', ['vm' => $vm]);
    }
}
final readonly class FunctionIndexViewModel
{
    public function __construct(
        private bool $loggedInStatus,
    ) 
    {
    }

    public function isLoggedIn(): bool
    {
        return $this->loggedInStatus;
    }
}
// View
@if ($vm->isLoggedIn() === true)
  <div class="banner">
    ...
  </div>          
@endif

なぜなら、「ログイン状態ではバナーを表示する」というロジックを、画面の表示を担当するViewに持たせているからです。 ロジックはController(ViewModel)に持たせるべきであり、改良すると以下のようになります。

final readonly class FunctionIndexViewModel
{
    public function __construct(
        private bool $loggedInStatus,
    ) 
    {
    }

    public function isLoggedIn(): bool
    {
        return $this->loggedInStatus;
    }

    public function shouldShowBanner(): bool
    {
        return $this->isLoggedIn() === true;
    }
}
@if ($vm->shouldShowBanner === true)
  <div class="banner">
    ...
  </div>          
@endif

ViewModelでログイン状態によるバナー表示判定を行い、それをControllerを経由してViewに渡します。 Viewでは、isShowBannerがtrueなら、バナーを表示します。些細な変更ですが、このようにすることでViewに表示処理のみを担当させることができます.

依存性の注入と逆転による責務分離

僕が参加したLaravelプロジェクトでは、InterfaceやUseCaseを採用していました。これらのコードを実装することで、依存性の注入と逆転について、深く理解できました。

例として、以下のRepository、UseCaseのコードでは、どちらもInterfaceを参照しています。

interface FunctionRepositoryInterface
{
    public function get(): FunctionRepositoryGetOutput;
}
final class FunctionRepository implements FunctionRepositoryInterface
{
    public function __construct()
    {
    }

    /**
     * MySQLから内容を取得する
     */
    public function get(): FunctionRepositoryGetOutput
    {
        ~~~
    }
}
final readonly class FunctionGetUseCase implements FunctionGetUseCaseInterface
{
    public function __construct(
        // 依存性を注入
        private FunctionRepositoryInterface $functionListRepository,
    ) {
    }

    // 様々な実装
}

RepositoryではInterfaceを参照することで実装を厳密にでき、UseCaseではInterfaceを介することで、外部から依存性(Repository)が注入されています。 また、InterFaceを利用することで、

  • UseCase(高レベル)=> Repository(低レベル)

の依存関係から、

  • UseCase(高レベル)=> Interface <= Repository(低レベル)

という依存関係に変化します。これにより、高 => 低の依存関係が逆転します。

依存性の注入と逆転を利用することで、オブジェクト間の依存関係が疎になり、UseCaseはRepositoryの実装から完全に独立できます。 例えば、RepositoryでMySQLではなくSQliteからデータを取得するように変更したい場合、Repositoryを修正するだけで済みます。

テストコードの書き方

テストコードの実装は、正直一番難しかったです。 RepositoryやControllerのテストを行いましたが、そもそもどのようなテストを書けばいいのか、失敗テストは書くべきなのかといったように、考慮することが多くありました(メンターさんからも、テストが開発で一番難しいかも、と言われました)。

このような実装面以外にも、プロジェクトの運用的な側面でも意識しなければいけないことがありました。

例えば、Repositoryのテストでは、Repositoryで取得した内容とテストの中で取得した内容が一致するかのテストを行なっていましたが、取得内容が変更される可能性のあるデータの場合、将来的にテストが機能しなくなる可能性がある、という指摘をいただきました。この経験から、運用面についてもエンジニアは考えなければいけないことがあるということを学びました。

テストについては上手くできないことが多かったので、今後の課題と感じています。

実務・チーム開発でのGit操作

チーム開発、特にPull Requestを作成する際に、以下のことに気をつけました。

  • 機能単位でコミットを行う
  • コミットメッセージにprefixをつけて構造化する
  • コミット前に静的解析を行い、コードの保守性などをチェックする
  • --amendでのコミットメッセージ変更は、pushした後は行わない
  • PRでコンフリクトが発生したら、基本的にPR上で解決する(ローカルで解決しようとして、さらに面倒になった経験から)

コミュニケーション・業務遂行面での学び

相談内容の構造化

相談内容の構造化を行うことで、質問する側・答える側の両方にメリットがあると実感しました。 インターン中にどうしても詰まっている箇所について質問がある際は、以下のようなテンプレートを使用していました。

## やったこと
~~~
## わからない・詰まっている箇所
~~~

見出しをつけて内容をわかりやすくすることで、答える側の負担が減るように意識しました。 また、内容を言語化することで自分が今詰まっている箇所について、より理解できるようになったと思います。

早めに頼ることの大切さ

早めに人を頼ることで,早く問題を解決できると実感しました.

インターン開始時の環境構築で、なぜかdockerでプロジェクトが開始できないというエラーが発生してしまいました。 個人開発ではAIに頼りまくっているので、同じようにGemeniを使おうと思いましたが、せっかくのインターンなので、メンターさんなどに聞くことにしました。 相談した結果、プロジェクト内のあるファイルが環境構築コマンドで作成されていないことが判明しました。 このエラーは、自分だけでは絶対に気づけないものだったので、早めに相談して良かったと思いました。 早めに相談するというのは当たり前のことに思われますが、実務で実感できたのはいい経験でした。

考えることの大切さ

開発の際に、しっかり考えることも大事だと学べました.「早めに頼る」ことと矛盾しているようですが,しっかり考えることで物事への理解がより深まるだけでなく,人に頼る時の言語化も上手くなります。 具体的にどう考えていたかというと、例えば上記の質問テンプレートのように、内容を細分化して把握する、原因を細かく遡って追求する、といったことを意識していました。

自分で考えることと人に頼ることのバランスですが、個人的には30 ~ 1時間ほど解決しないようであれば、人に聞いたほうが早いと思います。

若手は人やAIをどんどん頼ろう

僕がインターン生というのもありますが、それに限らず若手は積極的に頼っていくべきだと思います。 人を頼ることで成長スピードが早くなるだけでなく、しっかりとしたコミュニケーションを行うことで、信頼関係を築くこともできます。 AIについては賛否両論ありますが、これも積極的に使ったほうがいいと思います。一見大したことのない、しかし時間のかかりそうなエラーでも、AIを使えば解決できることもあります。

個人的には、AIを使ってもわからなかったら、人を頼るべきだと思います。

まとめ

1ヶ月間というインターン期間は、始めこそ時間がたっぷりあると思っていましたが、終わってみるとあっという間でした。 アーキテクチャに関する理解や、読みやすいコードの書き方など、技術・コミュニケーションともに様々なことを吸収できて、とても楽しかったです。 実際の開発業務に携わった経験は、非常に貴重な経験として、今後の糧とさせていただきます。

また、インターン後半では、メンターさんから就活に役立つような業界情報を教えていただき、今後就活を進めるにあたって非常に参考になりました。

メンターさんを含むヘルスケア事業部の皆さん、そしてエキサイト株式会社の皆さん、インターン生として受け入れていただき、本当にありがとうございました!

インターンシップ「Booost!!!」を通して

はじめに

はじめまして! 9月のExciteの就業型インターンシップ「Booost!!!」に参加して得られた知見などを紹介します!

自己紹介

情報通信工学専攻の学部3年生です

個人でWeb開発を行ったり、アルバイトでフロントエンド開発の経験があります。 大規模アプリケーションに携わるのは初めての経験なので、現場の開発体験やエンジニアとして働くイメージを掴むことを目標に参加しました!

業務内容

Saas事業のFanGrowthにフロントエンド業務でアサインされましたが、面接時からバックエンドも担当してみたいという希望を唱えていたこともあり、後半にPHPを使ったAPI開発をすることができました! (わがままを聞いてくださってありがとうございます🙇)

具体的には以下の2つの業務を担当しました

  • Vueで実装されている画面をReact + TypeScriptへリファクタ
  • PHPを使い、実装済APIにレスポンスを追加

得られた学び

開発面とコミュニケーション面に分けてまとめます!

開発面

リファクタリングの経験

すでにVueで実装されている画面をReactへリファクタリングしました Vueの経験がほとんどなくて、<v-row><v-container>など独自記法のキャッチアップが少し大変でしたが、初めてリファクタリングの経験をすることができ、「再利用できるコードはあるか?」や「安定して動くAPIの処理、型定義はどうなっている?」等といった考え方を持ちながらコーディングをする事ができました。

コンポーネントの再利用

独自コンポーネントや、似た処理の再利用を常に意識しながらフロントエンド開発を行いました。 具体的には、以下の手順を踏みました

1.Figmaで作成画面をイメージする

2.dev環境に似た画面が無いか探索する

3.DevTools or IDEのgrepなどで特定

4.コードベースに潜りIDEの参照機能などから具体的な実装などを真似する

このやり方のお陰で、速い実装、大きなコードベースの理解に繋がったと思います。

フロントエンド開発側のバックエンドの理解

当初私が作成したフロントエンドで画面を作成するPRではAPIを何度も叩く処理が発生してしまい、アプリの仕様変更や大規模化に伴い、パフォーマンスにも影響が出るであろうということでAPIのレスポンスを1つにまとめる業務を行いました。

  • フロントエンドからでもAPI, DBの処理の理解
  • パフォーマンスに対する意識

を学ぶことができ、個人開発だけでは得られなかった考え方を経験できました。

積極的なAI活用

  • GitHubでPR作成時にGeminiのAIレビューを実行することでレビュワーの負担を軽減 & 変更の理解の促進につながる
  • フロント、バックエンドに別れているレポジトリを1つにまとめて、ドキュメントを整備することでAIへのインプットを効率化するなど

コミュニケーション面

フルリモートでの参加だったため、Slackなど文面のコミュニケーションがメインでしたが、リアクションや即レス、解釈の入れ違いが発生しないように意識しました。 チーム開発でのコミュニケーションの重要性を学ぶことができました。 また、インターンシップ期間中にオンラインイベントを複数開催していただき、普段触れない技術のキャッチアップや社員の方のLTを聞くことができました 会社の雰囲気を掴めて、とてもいい機会でした!

おわりに

今回のインターンで多くの知見を獲得し、学びながら楽しく働くことができました。 メンターさん、社員の方々、人事の方、関わっていただいた全ての皆さんに感謝申し上げます! 今後のエンジニアキャリアを加速される大きな経験をすることができました! ありがとうございました!