TECH LEAD Blog

IT・WEBエンジニアのキャリア相談/転職支援サービス【TECH LEAD(テックリード)】が、エンジニアキャリアに関する記事やtwitterアンケート企画「エンジニア世論調査」の結果を投稿しています。

【アーキテクチャー編】TECH LEADの技術を惜しげも無く公開します!React × PHP Laravel × BEAR.Sunday × SSR

こんにちは、@TECH LEADです。

現在TECH LEADでは、IT/WEBエンジニアのキャリアアップに関する3つのサービスを開発・運営しています。

IT/WEBエンジニア専門の求人サービス|TECH LEAD Job

IT/WEBエンジニア専門の転職支援サービス|TECH LEAD Agent

TECH LEAD Resume|IT・WEBエンジニア向けレジュメ管理サービス

現在はキャリア・転職関連のサービスを中心に展開していますが、今後は全てのIT/WEBエンジニアの皆さんに利用されるようなエンジニアリングのスキル・キャリアプラットフォームへと成長させていく事を目指しています。

2018年3月から本格的に自社サービスであるTECH LEADの開発がスタートしたのですが、スタート時にはサービスをどのように設計し、開発していくかについてとても悩みました。(今も悩んでます)

そんな時に他のサービスを参考にしたいと思い、いろいろなサービスを調べていく中で下記のようなことを強く感じました。

  • どのように設計されているのだろうか?

  • どのように実装されているのだろうか?

  • 中身を見てみたい

色々な会社のテックブログなどで使われている技術などの紹介をしていることは多いものの、詳細なアーキテクチャーや実装が書いてあるサービスはとても少ない印象でした。もちろん、セキュリティー上見せられないということもあるかと思いますが、もう少し詳細なところを知りたいな・参考にしたいなと思いました。

そこで「人がどうやっているのか教えて欲しい!」と言う前に、まず自社のサービスがどのように実装されているのか公開したいと思います。なるべく全体像や詳細な実装がわかるように詳しく書いていきたいと思いますので、よろしくお願いします。

今回を第一回として、今後以下の順番でブログを連載していきます。

  1. アーキテクチャー編 ←いまここ
  2. フロントエンド編
  3. サーバーサイド(アプリケーション層)編
  4. サーバーサイド(内部API層)編
  5. インフラ編

新規でサービスを作ろうとしている方も既存サイトがある方も、少しでもこの記事が参考になればと思っています。

第1回となる今回は、TECH LEADサービス全体のアーキテクチャについて説明したいと思います。

開発の基本コンセプト

プラットフォームサービスを作っていくにあたって以下のようなことを基本コンセプトとして設定し、設計・開発を行っています。

  • 1つのアカウントですべてのサービスを利用できる

  • 登録されたリソースを無駄なく全サービスで活用できる

  • スケールしやすく作る

  • メンテナビリティが高い

主な技術 

インフラ・ミドルウェア

Amazon EC2

Amazon Aurora

Amazon S3

Elasticsearch 6.4

nginx

PHP-FPM

デプロイ

Deployer

インフラツール

Terraform

Ansible  

サーバーサイド

PHP 7.2

フレームワーク

Laravel 5.6

BEAR.Sunday

フロントエンド

React 16.4

Typescript 2.6

Sass

webpack 4

TECH LEADのアーキテクチャー
TECH LEADのアーキテクチャ

インフラに関して

  • EC2:アプリケーション用とElasticsearch用の2つ

  • データベース:Amazon Aurora

  • ストレージ:Amazon S3

Amazon Elasticsearch Serviceを使うこと検討しましたが、Kuromojiのユーザー定義辞書を使うことができないため見送りました。

オーケストレーションツールとしてTerraformを用い、サーバ・DNSなどの設定を全て行なっています。

Ansibleでミドルウェアのインストール・nginxの設定などのサーバ構成管理を全て行なっています。

現状は、全サービス同一サーバに乗っているので、1台のNGINXで全てのアプリケーションを動かしています。

サーバーサイドに関して

ディレクトリ構成

.
|                   # 内部API層
├── api/            # [BEAR.Sunday]ミドルウェアの操作・メール送信
├── db/             # [Laravel] データベースのマイグレーション・シードを管理
└── web/                  # アプリケーション層
    ├── site-common/      # 共通で利用できるものを配置
    |                     # シンボリックリンクで各アプリケーションで使用
    ├── site-mypage/      # [Laravel] TECH LEAD共通部分
    |                     # アカウント設定・パスワード変更など
    ├── site-agent/       # [Laravel]TECH LEAD Agent
    ├── site-job/         # [Laravel]TECH LEAD Job
    └── site-resume/      # [Laravel]TECH LEAD Resume

TECH LEADサービスのサーバーサイドプログラム(PHP)は、大きく内部API層とアプリケーション層の2つに分かれています

内部API層では、データベース・Elasticsearchの操作、メール送信処理などに直接アクセスし、それらの処理をラップ(抽象化)しています。

各アプリケーションは、直接データベースなどを操作することはなく、内部API層へリクエストすることでデータを作成・取得・更新をしています。データベースなどを考える必要がなく、基本的にはフロントからのリクエストを内部API層にリクエストし、結果を受け取り、フロントに返すことに専念できます。

また、アプリケーション層と内部API層を分けることで、サービスが追加された時や変更があった時でも、ほかのサービスへの影響を最小限に抑え、対応ができるようこのような構成になっています。

データベースのマイグレーションとシードに関しては、dbディレクトリ配下に配置しているLaravelのマイグレーション機能を利用しています。 ここでは、マイグレーションとシード以外のことは行なっていません。

※現状、同一サーバ上で全てのサービスが動いていますが、今後サービスが成長していくにつれて各サービスを分離していこうと考えています。

フロントエンドに関して

ディレクトリ構成

.
├── common/             # `web/site-common/js`へのシンボリックリンク
|                       # 各サービス共通で使用する関数やコンポーネントを配置
├── components/         # ステートレスコンポーネントを配置
├── containers/         # renderされるメインのステートフルコンポーネントを配置
├── modules/            # api通信用の関数を配置
├── pages/              # SSR時に使用するコンポーネントを配置
├── const.d.ts          # Typescriptの型定義ファイル
├── index.tsx           # CSR用のエントリーポイント
├── index_csr.tsx       # SSR後にCSRする用のエントリーポイント
└── index_ssr.tsx       # SSR用のエントリーポイント

PHPのviewテンプレートはTwig、フロントエンドはReact × Typescriptを使っています。

TECH LEADサービスでは、ほとんどのページがCSR(クライアントサイドレンダリング)でコンテンツを描画しています。

PHPからはheadやjs・cssエントリポイント、利用するコンポーネントの指定をしたHTMLだけを返し、CSRでページを描画しています。

しかし、SEO的にページへアクセスした時点でDOMが作られていないのはよくないので、ログイン前に見れるページはSSR(サーバーサイドレンダリング)で作っています。

SSRPHPのエクステンションのV8jsを使用して行なっています。

弊社では以前、別プロジェクトでSPA(シングルページアプリケーション)を作成した経験があります。 「ReactでSPAを作ろう!(作ってみたい!)」と意気込んだものの、開発中に下記のようなこと思いました。

  • 本当にSPAである必要があったのか?

  • Reduxを使う必要があったのか?

  • もっと簡単に書けるのでは?

そんなことを思った経験からTECH LEADサービスでは、まずは最小限で実装し、フロントエンドをどう実装するのがいいのかを考えながら開発をしていこうと思っています。

※最近、「モダンなフロントエンドはSPAがベストプラクティス」というような記事をみかけ、やはりSPAにしようかなと検討中です。

まとめ

ここまでインフラからフロントエンドまで、非常にざっくりとではありますが全体の構成を説明させていただきました。

TECH LEADサービスのアーキテクチャーで一番特徴的なところをあげると、フロントエンド、アプリケーション層(プログラム)・内部API層(プログラム)でやることを切り分け・限定しているところになると思います。各層をAPIでやり取りすることによって、共通のリソースを使うことができ、それぞれの依存関係を低くすることでメンテナビリティを高められていると思います。

今後の課題として、アプリケーション側で共通部分をシンボリックリンク使って各サービスで使用しているコードを、サーバを分ける際にどのようにまとめるかなどの検討していかなければならないですが、基本的には上記のような形を維持しつつうまくパッケージ化して各サービスで使用することができたらなと思っています。(結構大変だと思いますが。。。)

エンジニアの皆さんへお願い

今回は、TECH LEADサービスのアーキテクチャや全体像の説明をさせて頂きました。 次回以降のブログでは、フロントエンドからサーバーサイド、インフラまでもう少し具体的な実装や、開発時の課題などを公開していこうと考えていますが、もし、「ここをもっと聞きたい」「うちではこうやっている」と言ったご意見・アドバイスなどありましたら、@TECH LEADまでリプライやDMにてお気軽にお知らせください!

よろしくお願いします!

次回予告

次回は【フロントエンド編】で、フロントエンドの実装ついてもう少し深く話したいと思います。

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

PR

「今は具体的な転職を考えていないよ」と言う方も、是非一度TECH LEADの各サービスを触ってみていただけると嬉しいです。

TECH LEAD Job

IT/WEBエンジニア専門の求人サービス|TECH LEAD Job

TECH LEAD Resume

TECH LEAD Resume|IT・WEBエンジニア向けレジュメ管理サービス

TECH LEAD Agent

IT/WEBエンジニア専門の転職支援サービス|TECH LEAD Agent