どうも、つよぽん(@tsuyopon_xyz)です!
今回の記事は、Webエンジニアを目指している人向けに、「身につけておくべきスキル」「知っておくべき開発用語」をまとめたものになります。
「必須スキル」と「差別化スキル」の2つに分けておりますが、必須スキルだけでも結構な数があり圧倒されるかもしれません。
必須スキルを押さえていないと、仕事で以下のような支障をきたす可能性が高くなります。
- 機能実装ができない
- 不具合が発生している時、原因の特定ができない
- チーム開発ができない
- 開発のコミュニケーションが円滑に進まない
最低でも必須スキルの内容は全て押さえておくことを強くおすすめします。
この記事の文字数は約3万文字ほどあります。
Webエンジニアに向けてすでに学習されている方、まだ未学習の方はそれぞれ以下のような読み方で進めることをおすすめします。
- 既に学習中の場合 : 必要なところをかいつまんで読む
- 未学習の場合 : 最初から順番に全部読む
必須スキル
必須スキルには「フロントエンド」と「バックエンド」の両方を含めていますが、人によっては「フロントエンドだけに特化する」「バックエンドだけに特化する」というのもありでしょう。
現役エンジニアの中でも「フロントエンドが得意」「バックエンドが得意」「インフラ周りが得意」といった感じで、人によって得意分野が分かれていたりします。
ただ、個人的な意見としては、これからWebエンジニアを目指すという場合は、フロントエンドとバックエンド両方の知識を身につけた方が良いと考えています。
理由は以下の通りです。
- Webアプリケーションの全体像を把握できるようになる
- フロントエンドとバックエンドの開発ができるようになる(スクラムと相性が良い)
- 個人でWebアプリ開発ができるようになる
「スクラム」という用語についてはここでは詳細には取り上げませんが、ここではチームで開発を進める手法の1つだと認識していただけたらと思います。
仕事では複数人のエンジニアチームで開発を進めることになりますが、チームで開発を進める際、あらかじめ実装する機能を洗い出して、手の空いた人が優先順位の高いものから開発タスクに取り組んでいきます。
このときの開発タスクは「フロントエンドの開発タスク」「バックエンドの開発タスク」が混ざっていることが多いです。
自社開発系で技術に対して理解のある企業(いわゆる今時のテック企業)では、このスクラム開発が一般的な印象です。
そのような理由から、これからWebエンジニアを目指される場合は「フロントエンド」「バックエンド」の両方の知識を身につけた方が良いと考えています。
それでは、ここから先は、仕事で求められる「スキル」「用語」をまとめていきます。
フロントエンド
HTML
Webページを作るにはHTML, CSSというものを使います。
HTMLとCSSの役割はそれぞれ以下の通りです。
- HTMLの役割 : ページの構造を定義
- CSSの役割 : ページの見た目の定義
HTMLの「Webページの構造を定義」についてもう少し具体例をあげたいと思います。
ここではこのサイト「Web白熱教室」のトップページを例に構造を考えてみましょう。
トップページを見ていただくと、大きく分けると以下の4つのパーツに分けることができます。
- ページの上部分(ヘッダー)
- ページの左部分(メインコンテンツ)
- ページの右部分(サイドバー)
- ページの下部分(フッター)
ページ上部分(ヘッダー)には、「サイト名」「メニュー」などがあります。
ページ左部分(メインコンテンツ)には、各ブログ記事のカードがあり、各カードをクリックすると対象のブログ記事に遷移するようになっています。
ページ右部分(サイドバー)には、「メルマガ」「外部リンク」「プロフィール画像」などがあります。
ページ下部分(フッター)には、プライバシーポリシーのリンクやコピーライトなどがあります。
このような感じで「Webページのどこにどのような表示パーツを置くか定義する」のがHTMLの役割となります。
HTMLはあくまでもページ構造の定義が主な役割で、ページの見た目を整える(デザインを反映させる)役割はこの後説明する「CSS」で行います。
最終的にWebアプリを作れるようになることが目標と考えた時に、まずは学習サイト「HTML&CSS速習教室」で解説している内容を理解できていれば問題ありません。(あとはここで身につけた知識をもとに都度ググれば良い)
CSS
先ほど、HTMLの終わりの方でも解説した通り、Webページの見た目を整える(スタイルをあてる)には「CSS」を使います。
ここでも「Web白熱教室」のトップページを例に、見た目の定義を考えてみます。
- ページの上部分(ヘッダー)
- ページの左部分(メインコンテンツ)
- ページの右部分(サイドバー)
- ページの下部分(フッター)
ページ上部(ヘッダー)では、サイト名の文字の大きさは他の文字よりも大きくなっています。また、背景色も横いっぱいに青くなっているのがわかると思います。
ページの左部分(メインコンテンツ)では、カードのような形で表示パーツ(カード型)がいくつも並んでいます。
また、このカードの中のスタイルに注目すると以下のようなスタイルで統一されているのがわかります。
- カードの上半分は画像が表示されている
- カード下半分の上の方にはブログ記事のタイトルが書かれている(文字サイズ大きめ)
- カード下半分の右下には日付が書かれている(文字サイズ小さめ)
サイドバー、フッター部分のスタイルについては省略しますが、いずれも色が付いていたり、文字サイズが異なっていたりしてデザインが整っているのがわかります。
このように、Webページの見た目を整える部分はCSSが担います。
CSSの学習に関しても、まずは学習サイト「HTML&CSS速習教室」で解説している内容を理解できていれば問題ありません。(あとはここで身につけた知識をもとに都度ググれば良い)
JavaScript
JavaScriptはWebページの表示内容(HTML, CSS)をリアルタイムで変更できる唯一のプログラミング言語です。
フロントエンドで使うプログラミング言語の現在の主流は次の説明するTypeScriptですが、TypeScriptは最終的にはJavaScriptに変換されるので、最終的にはJavaScriptを使うことになります。
「リアルタイムで変更できるとは?」となると思うので、YouTubeを例にJavaScriptで表示内容を変更される箇所を以下に挙げます。
- いいねを押すと「いいね数」が1増える
- 動画を流したままコメントを書き込んだら、ページの再読み込み無しにコメント一覧に自分のコメントが追加される
- チャンネルの登録・解除の切り替えができる(切り替えるたびに文字も切り替わる)
上記3つの事例の共通点は「ページの再読み込み無し」に表示内容に変更が発生しているところです。
YouTubeを例に出しましたが、TwitterでもFacebookでもWebアプリと呼ばれるものは「ページの再読み込み無しに表示内容に変更を加える」箇所が必ず存在します。
フロントエンド開発という観点で考えた時に、JavaScriptでまず身につけておくべき内容は「基礎文法」「DOM操作」「非同期処理」「Node.js周り知識」を身につけるところから始めると良いです。
「基礎文法」に関してはJavaScriptに限ったものではなく、どのプログラミング言語でも共通の知識となります。具体的には以下の通りです。
- 変数
- 条件
- ループ
- 関数
- データ構造(配列, オブジェクト, クラスなど)
「DOM操作」はフロントエンドJavaScript特有の操作で、HTMLやCSSの内容を変更して、Webページ上の表示内容をページの再読み込みなしで変更するものだと思っていただけたらと思います。
「フロントエンドJavaScript」という言葉は「バックエンドJavaScript」と区別するためにあえて使っています。
例えば、バックエンドのプログラミング言語にJavaScriptを選択した場合、Webブラウザ特有のJavaScript操作を行うことができません。具体的にはWebページの表示内容をリアルタイムで変更するDOM操作がそれにあたります。
「非同期処理」はイメージがつきづらい概念かと思います。ここでは「時間がかかる処理を別の場所で行うもの」という認識でも問題ありません。
何も考えずに時間がかかる処理を行うと、その処理が完了するまで他のことが何もできなくなってしまいます。
これの何が問題かというと、Webページを例にすると「ページが固まって動かなくなる」「スクロールもできなくなる」「ページを閉じれなくなる」という現象が発生してしまうことです。
この現象が発生してしまうと、アプリ利用者は「動かなくなった?!」「ページが閉じれない!」という気持ちになり、ストレスを与えることになってしまいます。
非同期処理というのを行うことで、このような問題を防ぐことができます。
「Node.js周り知識」については後ほどもう少し詳しく話しますが、今時のフロントエンド開発では「Node.js」は必須となります。
フロントエンドでNode.jsを使う理由としては「Single Page Application(SPA)の環境を整える」が一番大きなものになるかと思います。
SPAについても後ほど説明しますが、ここでいうSPAの環境とは「React」「Vue」「Next.js」「Nuxt」などを使ったフロントエンド開発だと思っていただけたらと思います。
「基礎文法」「DOM操作」「非同期処理」「Node.js周り知識」の知識の習得は、先ほど解説したHTML、CSSと比べると難易度があがります。
プログラミング自体が未経験という場合は、まずは基礎文法の学習から始めて、プログラミングに慣れるところから始めると良いでしょう。
僕の方でも出している「Front Hacks」という教材でも体系的に学ぶことは可能です。
その他にも、書籍, Udemy, 再生リストで体系的にまとめられたYouTube動画などご自身にあったものを探してみると良いかと思います。
「自分にあった教材が見つけられなくて相談したい」といった場合は、LINE公式アカウントもやっているので、そちらからご連絡いただけたらと思います。
TypeScript
JavaScriptの説明の冒頭でも書いた通り、フロントエンド開発で使うプログラミング言語の主流はTypeScriptです。
TypeScriptはざっくり言えばJavaScriptの上位互換のプログラミング言語となります。
具体的に言うと、JavaScriptは「動的型付け言語」と呼ばれるプログラミング言語に分類し、TypeScriptは「静的型付け言語」と呼ばれるプログラミング言語に分類します。
「動的型付け」「静的型付け」の詳細についてはここでは説明しませんが、ここでは一旦、静的型付け言語の方が厳格と理解してもらえれば問題ありません。
静的型付け言語の大きなメリットとしては、プログラミングを実行する前からおかしなコードがあるとエラーを知らせてくれる点です。
動的型付け言語の場合は、おかしなコードが含まれていもプログラムを実行するまでエラーを知らせてくれません。
静的型付け言語はプログラムの実行前にエラーに気づけるので、すぐに修正できるという点が大きなメリットになります。
基本的に動的型付け言語と比べると、静的型付け言語でプログラミングをするとコードの記述量は増えるのですが、長い目で見ると静的型付け言語を使った方が開発効率は良く、動的型付け言語で記述するよりも安心してコードが書けます。
TypeScriptの学習に関しては、まずは「サバイバルTypeScript」というサイトをご覧いただくと良いかと思います。
僕の方で「React × Redux Toolkit × TypeScript勉強会」というサイトの1日目で「速習TypeScript」というのを用意しているので、そちらも参考にしていただけると幸いです。
Node.jsの知識
Node.jsは元々はターミナル上で実行できるJavaScriptの実行環境で、主にバックエンド用に登場しましたが、現在はフロントエンドでなくてはならないツールになっています。
この後の「Single Page Application周りのスキル」でも取り上げますが、現在のフロントエンド開発では「Next.js(React), Nuxt(Vue)」を使うことが一般的です。
Next.js(React), Nuxt(Vue)を使う際に、「npm」「yarn」などのターミナルのコマンドを使うことになるのですが、これらのコマンドはNode.jsをインストールすることで使えるようになります。
厳密にいうとNode.jsをインストールすると「npm」コマンドが付属していますが、「yarn」コマンドは付属していません。
ただ、npmコマンドを使ってyarnをインストールすることができます。
Node.jsをインストールした後は、とりあえず以下のコマンドを理解できれば問題ありません。
- npm init
- npm install(-Dオプション含む)
- npm uninstall
- node -v
ターミナル操作に慣れている方は、Node.jsのインストールをする際は「nvm」というものを使ってインストールすると良いでしょう。
「nvm」を使うことで、複数のNode.jsのバージョンを管理することができます。
ターミナル操作に慣れていない場合は、Node.jsサイトのダウンロードページから安定版(LTSと付いているもの)の中から一番数字が大きいものを選んでおくと良いでしょう。
Single Page Application周りのスキル
現在のフロントエンド開発では「Next.js(React)」「Nuxt(Vue)」あたりを使うのが一般的です。
ReactやVueを使うことでSingle Page Application(SPA)と呼ばれるWebアプリを作ることができます。
React, Vueを使わず、素のJavaScriptでもSPAを実現できますが、React, Vueを使った方が実装が楽になります。
SPAはその名前の通り、Single Page(1つのページ)で作られたアプリケーションのことです。
SPAの反対はMPA(Multi Page Application)です。SPAを理解するにはMPAと比較した方がわかりやすいかと思うので、SPAとMPAの特徴を以下にまとめます。
- SPA
- 1つのHTMLでページが構成される
- Webアプリが3つのページで構成されていても、1つのHTMLを使い回して、表示の異なる部分だけDOM操作で切り替える
- MPA
- 複数のHTMLでページが構成される
- Webアプリが3つのページで構成されている場合、3つのHTMLを使う
SPAが流行る前までは、WebページのHTMLの構築もバックエンドで行っていました。
バックエンドでのHTML構築の例としては、Ruby on Railsのerbを使ったHTML構築があります。(MVCのViewの部分)
つまり、バックエンド側でフロントエンドで使うコードをがっつり実装していました。
現在は、ReactやVueなどSPAが一般的になり、フロントエンドとバックエンドの役割分担がより明確になりました。
具体的には、バックエンドからはJSONというデータ形式でフロントエンドにデータを返して、フロントエンドはそのJSON形式のデータを活用してDOM操作でWebページを構築するという形です。
まとめると以下のようになります。
- バックエンド : Webページに必要なデータをフロントエンドに返すところまで
- フロントエンド : バックエンドから返ってきたデータを使ってHTMLを構築する
React(Next.js), Vue(Nuxt)の学習は、まずは公式が出しているクイックスタートやチュートリアル見てみると良いかと思います。
以下に公式のリンクを貼っておきます。
公式で用意されているものが難しいと感じた場合は、UdemyやYouTubeなど体系的にまとめられた動画教材を観てイメージを掴むところから始めると良いでしょう。
僕の方でも「React × Redux Toolkit × TypeScript勉強会」の1日目の内容の内、以下の2つでもReactの実装イメージが掴んでいただけるかと思います。
Next.jsに関しては、少し古い内容となりますが、以下の「Next.js&TypeScript体験シリーズ」をご覧いただくとNext.jsに出てくる概念やイメージがなんとなくでも掴めるかと思います。
状態管理(React Context, Reduxなど)
Single Page Application(SPA)のおさらいになりますが、SPAではバックエンドからはページの表示に必要なデータをJSON形式で受け取り、そのデータを使ってフロントエンドでHTMLを構築します。
そこで以下のような場面を考えてみてください。
- ログイン必須のページに、非ログインユーザーが訪れたらログインページにリダイレクトさせる
- AmazonのようなECサイトで、どのページにいてもカートに入れた商品数や商品詳細を確認できるようにする
SPAで上記2つのことを実現させるには、フロントエンド側で「1. ログイン情報」「2. カート情報」をフロントエンド側で(JavaScriptを使って)管理する必要があります。
1と2の情報(データ)の共通点は、全ページにまたがって必要な情報になります。
SPAではなく、従来のMPAでWebアプリを作る場合は、データの更新がある度にページの再読み込みを行いバックエンドでHTMLの構築を行うため、フロントエンドでデータを管理する必要はありませんでした。
しかし、SPAでWebアプリを作る場合、Webページの構築(HTMLの構築, DOM操作)は全てフロントエンドのみで行います。
そのため、「ログインしているか否か」「カートに商品を入れているか否か」など、現在の状態によってWebページの表示の切り替えを行うには、フロントエンド側で状態を管理する必要が出てきます。
SPAで使う状態管理用のツールは色々とあります。Reactでいうと、Reactに標準で備わっている「Context」という機能であったり、「Redux」というライブラリなどでフロントエンドの状態を管理することができます。
ReactとReduxの組み合わせに関しては、僕が用意している「React × Redux Toolkit × TypeScript勉強会」の2日目に学ぶことの中にある以下2つでも学ぶことができるので、そちらも参考にしていただけたらと思います。
バックエンド
バックエンドのプログラミング言語(Ruby, PHP, TypeScriptなど)
フロントエンドと異なり、バックエンド(サーバーサイド)側では選択できるプログラミングはいっぱいあります。
その中でも使われることが多いプログラミング言語は以下の通りです。
- Ruby
- PHP
- Java
- TypeScript
- Go
基本的にバックエンドのプログラミング言語も単体で使うということはなく、次に紹介する「バックエンドのフレームワーク」と一緒に使うことになります。
就職・転職を希望されている場合は、希望する会社のプログラミング言語とバックエンドフレームワークを選択すると良いと思います。
もし、現時点では希望する会社はない、または希望する会社が使っているプログラミング言語・フレームワークがわからないといった場合は、以下の基準で判断して選択すると良いでしょう。
- 使い慣れているプログラミング言語(例: フロントエンドに慣れていればTypeScript)
- チュートリアルが充実している言語(例: Ruby on Railsチュートリアル)
- 使っている企業が多そうな言語(例: Ruby, PHP, Java)
- パフォーマンスに強い言語(例: Go)
仮に選択したプログラミング言語を就職・転職希望先の会社が使っていなかったとしても、大きな問題はありません。
というのも、基本的にプログラミング言語はいずれも似たような文法ですし、どの言語のバックエンドフレームワークも似たような機能を揃えているためです。
一つのプログラミング言語、バックエンドフレームワークのスキルが身につけば、2つ目以降の言語・フレームワークの学習ハードルは一気に下がります。
「とはいってもどれを選択すれば良いか判断できない!」
という場合は、とりあえず他の言語と比べて歴史も古く、教材や書籍が多そうなRuby, PHPあたりを選ぶのが良いかなというが個人的な意見です。
参考までに、僕が教える場合は、僕自身一番得意な言語であるTypeScriptで教えています。
不定期で学習サポートの案内をメルマガで出しているので、興味がある方はメルマガに登録して案内をお待ちいただけたらと思います。
バックエンドのフレームワーク(Ruby on Rails, Laravel, NestJSなど)
バックエンド開発で行うことはある程度決まったパターンがあります。
代表的なものを言えば「CRUD」というものがあります。
CRUDは以下の頭文字をとったものです。
- Create : 作成
- Read : 読み取り(取得)
- Update : 更新
- Delete : 削除
フロントエンドからのリクエストに応じて、バックエンドは何かしらのCRUD処理を行い、その結果をフロントエンドに返すのが基本的な流れです。(リクエスト→レスポンスの流れ)
このとき、フロントエンドからリクエストがきた際に、以下のことを考慮する必要があります。
- どんなURLでリクエストが来たか?
- リクエストURLを見て、バックエンドはどの処理を実行するか判断する
- リクエストにはどんなデータが入っているか?
- データの作成に必要な情報は全て含まれているか
- 一覧取得の場合、何ページ目の情報を求めているか
- どのデータを削除しようとしているか
- 不正なリクエストか?
- ログインしていないと見れない情報をログインしていない状態で見ようとしてるか?
- ログインしているが、他のユーザーの情報を削除しようとしていないか?
上記はあくまでも一例で、他にもバックエンド開発には考慮しないといけないことがいろいろあります。
これら全てをゼロから全て自分で実装しようとすると膨大な量の実装が必要になってしまいます。
このような、決まったパターンの実装を毎回ゼロから実装するのは効率が悪いため、フレームワーク側でよく使われるパターンの機能を用意して、実装を楽にするのがフレームワークを使う大きなメリットです。
フレームワークの利用者は、フレームワークの使い方のルールを覚える学習コストが発生しますが、ゼロから全て実装するのと比べると圧倒的に開発効率は良いです。
また、仕事での開発はチーム開発が基本となりますが、チーム開発の観点でも、フレームワークによって実装ルールが決まるので、誰が書いてもある程度似たようなコードになります。
プログラミング言語ごとにフレームワークは複数ありますが、いずれのフレームワークも「よく使われる機能をあらかじめ組み込んで、実装を楽にする」という点では共通なので、似たような機能が用意されています。
先ほど「バックエンドのプログラミング言語」のところでも書いたとおり、1つフレームワークを覚えれば、2つ目以降のフレームワークの学習ハードルは下がります。
つまり、学習に使ったフレームワークと就職・転職先の会社が使っているフレームワークが異なっていても、知識を流用することができるので、学習のキャッチアップ速度は1つ目のときよりも格段にあがるはずです。
バックエンドフレームワークを学習する際に、特に理解できるようになって欲しいのは「API開発」です。
ここでいうAPI開発とは「フロントエンドからのリクエストに対してJSON形式でデータを返す機能の実装」のことです。
厳密にいうと「API」という言葉は不正確・曖昧かもしれません。
ただ、これまでの仕事の経験からの個人的な感覚での話になりますが、開発のコミュニケーションの際に「動画一覧を取得するAPIの実装」と会話があった場合、
それは「特定のURLにリクエストを投げたら、動画一覧の情報をJSON形式で返す機能の実装」と認識でいます。
「Single Page Application周りのスキル」でも書いた内容ですが、現在のWebアプリ開発ではフロントエンドとバックエンドの役割がはっきりとしています。
- フロントエンドの役割 : バックエンドから受け取ったJSON形式のデータをもとにHTMLを構築(DOM操作)
- バックエンドの役割 : フロントエンドからのリクエストに応じた処理を行い、フロントエンドに必要なデータをJSON形式で返す
この章の最後に、各プログラミング言語の代表的なフレームワークを以下に挙げます。
- Ruby : Ruby on Rails
- PHP : Laravel
- Java : Spring Boot
- TypeScript : NestJS
- Go : Gin
あくまでも個人的な感覚ですが、Goに関してはフレームワークを使わず、Go言語標準の機能だけで実装することも一般的な印象はあります。
この件に関してChat GPTに質問した際の回答を以下に貼っておきます。
RDB(PostgreSQL, MySQLなど)
Webアプリで使うデータはデータベースに保存されます。
YouTubeを例にすると、以下のようなデータがデータベースに保存される内容となります。
- ユーザー情報
- チャンネル情報
- 動画情報
使われることの多いデータベースは大きく分けると「RDB(Relational DataBase)」と呼ばれる種類のものと、NoSQLと呼ばれるものの2つに分けられます。
特に会社で開発をする際にまず選択肢として挙げられるのは「RDB」の方です。
そのため、データベースの学習をする際には、まずはRDBの学習をすることから始めると良いでしょう。
RDBの学習に関しては、僕の方でも「RDB入門講座」という学習資料を用意しているので、そちらも参考にしていただけると幸いです。
ORM・DBマイグレーション
バックエンド開発をする際に、プログラムを通してデータベース操作をすることになります。
具体的には以下のような操作です。(CRUD操作)
- Create : データベースにデータを追加する
- Read : データベースから保存されているデータを取得する
- Update : データベースに保存されているデータを更新する
- Delete : データベースに保存されているデータを削除する
プログラムを通してデーターベース操作をする際、ORM(Object Relational Mapping)と呼ばれるツールを使うことが一般的です。
ORMの役割を簡単に挙げると以下のようなものがあります。
- データベースごとの方言を意識せず、データベース操作ができる
- データベースからデータを取得する際に、プログラムに扱いやすい形式(オブジェクト)に変換する
また、ORMとは別にDBマイグレーション(または単にマイグレーション)というものもあります。
こちらは、データベースのテーブルのスキーマの定義をデータベースに反映させるツールです。
「テーブル」「スキーマ」という言葉に聞き馴染みのない方に説明すると、それぞれは以下のようなものとなります。
- テーブル
- エクセルの各シートのようなもの
- 保存する種類ごとにテーブルを用意し、そのテーブルに実際のデータを保存する
- 例 : YouTubeに関する情報を保存する場合
- ユーザー情報の保存先 : usersテーブル
- チャンネル情報の保存先 : channelsテーブル
- 動画情報の保存先 : videosテーブル
- スキーマ
- テーブルごとにどんな情報を保持し、どんな制約をかけるか設定したもの
- 例 : usersテーブルの例
- 保存する情報
- id : 数値
- email : 文字列
- name : 文字列
- created_at : 作成日
- updated_at : 更新日
- 制限
- emailは他のユーザーと重複禁止(Unique制約)
- emailとnameはNULL禁止(NOT NULL制約)
- 保存する情報
ORMはDBマイグレーションに関しても、先ほど紹介した「RDB入門講座」で学習することができます。
認証
認証とは簡単に言えば「新規登録」「ログイン」のことだと認識していただいて構いません。
Webアプリではログインしているユーザーにしか許可していない操作があります。
Twitterを例にすると以下のような操作がそれにあたります。
- ポスト(ツイート)
- 自分のプロフィール情報の編集(他の人のプロフィールは編集できない)
- フォロー・アンフォロー
- ライク(いいね)
- ブックマーク
新規登録・ログインの機能はフレームワークで提供されているものもありますが、認証機能だけを提供しているサービスもあるのでそれを使うのが手軽で良いかと思います。(このような認証機能だけを提供しているサービス「IDaaS」と呼んだりします)
具体的なサービスとしては以下のようなものがあります。
この認証機能を使って、バックエンドフレームワークを使って実装するAPIの中に、ログイン済みのユーザーでないと使えないAPIの実装もしてみましょう。(おそらくフロントエンドの方でもIDaaSを使った実装が必要になるかと思います。)
ネットワーク周り
HTTP(メソッドの種類, ステータスコード)
HTTPをざっくりというと、PC、スマホ、バックエンドのサーバー間でデータのやりとりを行う手段の1つになります。
具体例を挙げると、以下のような場面で裏側でHTTPが使われています。
- 企業サイト・個人サイトに訪問してサイト情報を確認するとき
- YouTubeやTwitterなどのアプリケーションを使うとき(Webアプリ・スマホアプリ共通)
先ほどの「バックエンドのフレームワーク」の説明部分で、「特に理解できるようになって欲しいのはAPI開発です。」と言ったのを覚えているでしょうか?
ここいう「API開発」はフロントエンドとバックエンドのデータのやりとりを行う機能の実装を指しますが、このデータのやりとりにHTTPを使います。
API開発をする上でまず覚えておきたい概念としては以下の2つがあります。
- HTTPメソッド
- HTTPステータスコード
これら2つの関しては、以下のブログ記事で解説しているので、HTTPをざっくりと抑えておきたいという方は以下の記事をご覧いただけたらと思います。
API開発をする際に「REST API」「GraphQL」という言葉を聞くようになるかと思います。
いずれもHTTPを使ったデータやりとりの方法になります。 まずは、歴史もある「REST API」を理解するところから始めると良いでしょう。
(GraphQLは比較的最近の技術で、REST APIの方が比較的実装がしやすい印象)
CookieとSession
CookieとSessionは主に、Webサイトの利用者の情報や行動を追いかける目的で使われます。
CookieとSessionは使われる場所や概念が異なりますが、まずは以下のことを理解しておくと良いでしょう。
- Cookie
- クライアント側(Webブラウザなど)に保持される情報
- 使用例
- Webアプリのログイン情報の保持
- このログイン情報をバックエンドに送ることで、どのユーザーからのリクエストか判断できる
- 端末(PC, スマホなど)の特定
- アフィリエイトリンクを経由して商品を購入した際、購入時にCookieに保存されたアフィリエイト用のIDがあれば、紹介者経由で購入したと判断できる
- Webアプリのログイン情報の保持
- Session
- サーバー側で生成される情報
- この情報を「Session ID」と読んだりもします
- このSession IDをクライアントに渡しCookieに保存させることで、次回以降のリクエストでは、どのクライアントからのリクエストが判断できる
- サーバー側で生成される情報
少しややこしいかもしれませんが、混乱した場合は「とりあえずCookieとSessionを組み合わせることで、サーバーはクライアントを特定できる」くらいの認識でも問題ないと思います。
Cookieに関しては以下のドキュメントが参考になるかなと思います。
CORS(Cross-Origin Resource Sharing)
CORSの日本語訳は「オリジン間リソース共有」です。
「オリジン」「リソース」の意味は以下の通りです。
- オリジン : サイトのURLの組み合わせ
- リソース : サイトのデータ(APIのレスポンスデータ, 画像ファイル, CSSファイルなど)
オリジンのイメージが難しいと思うので、もう少し説明します。
オリジンとは「プロトコル」「ホスト」「ポート番号」の組み合わせを指します。
- プロトコル
- URLの一番左の部分
- 「https://tsuyopon.xyz」でいうと「https」がプロトコル
- ホスト
- ドメイン
- 「https://tsuyopon.xyz」でいうと「tsuyopon.xyz」がホスト
- ポート番号
- こちらの記事を参照
- Webブラウザでサイトに訪問する際にURLにはポート番号は書かれていないが、HTTPリクエストでは暗黙的に次のポート番号が使われている
- http : 80
- https: 443
- 「https://tsuyopon.xyz」はhttpsなので、より正確に書くと「https://tsuyopon.xyz:443」となる
- この443の部分がポート番号
つまり、上記の説明に出てきた「https://tsuyopon.xyz」を例にすると「プロトコル = https」「ホスト = tsuyopon.xyz」「ポート番号 = 443」ということになります。
オリジンの説明については以下の資料がわかりやすいので、そちらもご覧いただけたらと思います。
つまり、CORS(=オリジン間リソース共有)が意味することは「異なるオリジン間でのデータの共有」ということになります。
例えば、自分のサイト(例: https://tsuyopon.xyz)からYouTubeやTwitterのAPIを使う場合、異なるオリジンのAPIを使うことを意味します。これがCORSです。
CORSはAPI開発をする際に意識することなります。
CORSを意識する理由としては「セキュリティ」などが考えられます。
何も意識しないでどのサイトからでもAPIを使えるようにすると、膨大な数のリクエストを受ける可能性が高まります。
悪意のあるユーザーは、サーバーに負担をかけるために短期間に大量のリクエストを投げたり、外部に漏れてはいけないデータを取得しようとするでしょう。
これらの対策としては以下のようなものがあります。
- 1分あたりのリクエスト数を制限する
- 一部の人だけにAPIを公開する
- そもそも外部にAPIを公開しない
ここらへんをより詳しく知りたい方は「Rate Limit」「Client Key・Client Secret」「Same-origin policy(同一オリジンポリシー)」などのキーワードでググっていただけらと思います。
この章の最後にCORSやオリジンの理解の助けになる資料リンクを以下に貼っておきます。
その他
リクエストとレスポンス
「フロントエンド」と「バックエンド」という言葉の方が聞きなじめがあってイメージしやすいかもしれませんが、「クライアント」と「サーバー」という言葉も、開発の会話の中でよく出てくるので正しく理解しておきましょう。
それぞれの意味は以下の通りです。
- クライアント = サービスを利用する側
- サーバー = サービスする提供する側
Webアプリを例に考えると、Webブラウザ(パソコンやスマホ)がクライアントで、データを返却するバックエンド側がサーバーになります。
その他にも、バックエンドだけで見ても「クライアント」「サーバー」の関係が成り立っているところがあります。具体例の1つとしては「データベース」がそれにあたります。
このときは、データベースを利用する側(APIサーバー)などがクライアントになり、データベースソフト本体がサーバーということになります。
「フロントエンド = クライアント」ではなく「サービスを利用する側 = クライアント」、「バックエンド = サーバー」ではなく「サービスを提供する側 = サーバー」というのを認識していただけたらと思います。
クライアントとサーバー
「リクエスト」と「レスポンス」の概念は、先ほど説明した「クライアント」と「サーバー」の関係を理解しているとイメージしやすいです。
クライアントはサーバーに対して何かしらの処理を依頼します。
例えば、とあるWebサイトのトップページに訪れた際に、Webブラウザはトップページを表示するのに必要なデータ(HTML, CSS, 画像など)をサーバーから受け取る必要があります。
そのため、Webブラウザはサーバーに対して「トップページの表示に必要なデータをください」という依頼を投げます。
この「依頼を投げる」というのが「リクエスト」になります。
リクエストを受け取ったサーバーは、必要な処理を行いクライアントが求めるデータ(=結果)を返します。
この「必要な処理を行いデータ(=結果)を返す」というのが「レスポンス」になります。
「クライアントとサーバー」の説明にも出した「APIサーバー」と「データベース」とのやりとりを例にすると、リクエストとレスポンスの関係は以下のようになります。
- APIサーバーがデータベースにリクエストを投げる
- データを追加してください
- データを取得してください
- データを更新してください
- データを削除してください
- データベースはAPIサーバーにレスポンスを返す
- データの追加が完了しました(or 失敗しました)
- データを取得したので返します(or 失敗しました)
- データの更新が完了しました(or 失敗しました)
- データの削除が完了しました(or 失敗しました)
上記の例では、サーバーのレスポンスに「失敗しました」という言葉をあえて書きました。
クライアントがリクエストした内容は、常にサーバー側で無事完遂することができないこともあります。
そのときは、サーバー側で何かしらの原因で失敗したということをクライアントに返します。
つまり、ここまでの内容をまとめるとクライアントとサーバーのリクエスト・レスポンスの流れは以下のようになります。
- クライアントがサーバーにリクエストを投げる
- サーバーはクライアントから受け取ったリクエスト内容に従って必要な処理をする
- サーバーは
- 処理が無事完了したら、処理成功の情報とクライアントが求めているデータを返す(HTTPステータスコードで言うと200系)
- 処理中に異常が発生したら、処理失敗の情報をクライアントに返す(HTTPステータスコードでいうと400系 or 500系)
ポート番号
ポート番号の説明は以下の記事の見出し「ポート番号とは」にも書いているので、そちらをご確認いただけたらと思います。
JSON
JSONはデータ形式の1つで、形としてはJavaScriptのオブジェクトに似ています。(JSONはJavaScript Object Notationの頭文字をとっている)
JSONはプログラムから操作しやすいデータです。
Webアプリを開発する際、フロントエンドとバックエンドがAPIを介してデータのやり取りを行う際は、JSONでデータのやりとりを行うことが一般的です。
そのためWeb開発する上でJSONの理解は必須となります。
JSONの具体的なデータ形式については以下の記事の「JSONの例」の部分をご覧いただくとわかります。
REST API
バックエンドのAPI開発を行うとき、2024年4月現在だと「REST API」「GraphQL」のいずれかで実装することが一般的です。
一番最初に取り組む場合は、REST APIから取り組むと良いです。
REST APIから取り組んだ方が良い理由は以下の通りです。
- GraphQLと比べてREST APIの方が実装しやすい
- GraphQLと比べてREST APIはWebエンジニアだったら知っていることが前提の知識
- GraphQLは比較的新しい技術で、GraphQLが出る以前のAPI開発はREST APIで実装していた
REST APIの詳細は以下の記事の見出し「REST APIはHTTPメソッドを活用したもの」のところで説明しているのそちらをご覧ください。
テスト
プログラミングの「テスト」とは、プログラムが意図通り動くことを確認する作業のことを言います。
テストと一言で言ってもいろんな種類のテストがありますが、まずは「単体テスト(=ユニットテスト)」を覚えるところから始めると良いでしょう。
単体テストとは、クラスや関数といった単位で、実装した機能が意図通り動くか確認する作業のことを言います。
テストをする際に毎回、手動でテストを行うのは時間がかかるのと、入力ミスなどのヒューマンエラーが起こり得るので、テストコードと呼ばれるものを書いてテストを自動化するのが基本です。
テストコードを書いてテストを自動化することで以下のメリットがあります。
- 機能追加や修正によって、既存のコードが壊れるのを未然に防げる
- 安心してリファクタリングできる
1点目のメリットから見ていきます。
機能追加・修正を行なったら本番にリリースすることになりますが、このとき不具合が含まれている場合、本番のWebアプリは動かなくなる可能性があります。
個人開発だとそこまで気にならないかもしれませんが、会社のサービスだとそれなりのお金が絡んでくるので、本番での不具合は結構な痛手となります。
このとき、事前に用意していたテストコードにより、リリース前にエラーが発生しているのに気づけたら、不具合のあるコードを本番にリリースせずに済みます。
もちろん、テストコード自体、人の手で実装するものなので、テストの実装漏れ・実装ミスの可能性もあり、その実装漏れや実装ミスに気づかず、テストが全て成功したと判断してしまうミスもありえます。
ただ、それでもテストコードがない時と比べると、事前にエラーに気づける回数が劇的に増えることには変わらないので、仕事レベルの実装ではテストコードはあった方が無難です。
次に、2点目のメリット「安心してリファクタリングできる」について見てみます。
リファクタリングとは「機能の振る舞いを変えずに、より読みやすい形にコードを整理する作業」のことを言います。
実装したコードは後から見返すと、「ここのコードもっと綺麗にかけるな」「ここのコード読みにくいな」などという気持ちになることが多々あります。
このような気持ちになったときはリファクタリングをすると良いでしょう。リファクタリングをすることで以下のようなメリットがあります。
- コードが読みやすくなると理解しやすくなる
- コードの保守・運用の効率があがる
ただ、リファクタリングをすると言うのは現在動いているコードをいじることになるため、リファクタリングのミスによってコードが動かなくなる可能性もあります。
このとき、テストコードがあれば安心してリファクタリングできます。
具体的にいうと、リファクタリング前に成功していたテストが、リファクタリング後に失敗するようになったら、それはリファクタリングにミスがあったことを意味するからです。
これが、テストがあると安心してリファクタリングできる理由です。
仕事では1つのサービスのコードを長い時間かけて運用することがよくあります。
このときテストがあるコードと、テストがないコードどちらが安心して開発を進められるでしょうか?
上記までの内容を理解していると、テストがある方が安心して開発できることがわかっていただけたかと思います。
Git
Gitは「ファイルのバージョン管理」を行う開発ツールです。
ここでいう「ファイルのバージョン管理」とは「ファイルの変更履歴の記録の管理」と読み替えていただくとイメージしやすいかなと思います。
例えば、index.htmlという名前のHTMLファイルがあったとします。
このindex.htmlは、これまでに3回以下のような変更を行なってきたとします。
- HTMLの雛形を作成(bodyの中身が空のHTML)
- bodyの中にh1要素を1つ追加
- bodyの中にmain要素を1つ追加
このとき、バージョン管理をしている場合、3回の変更記録をとることになります。(=3つのバージョンの記録が取れている状態)
Gitで変更記録を取る(=バージョン管理をする)ことのメリットは以下のとおりです。
- 過去の好きなバージョンにコードを戻すことができる
- 誰が修正したか判断できる
このようなメリットがあるため、実装にミスがありコードが動かなくなった場合は、動いていたときのバージョンまですぐに戻すことができます。
つまり、本番でコードが動かなくなっていることが判明した場合は、すぐに前のバージョンに戻して、とりあえず動いている状態に戻せることを意味します。
また、過去のコードを誰が実装したか判断できることから、実装でわからないところや、実装意図が汲み取れない箇所があれば、実装者本人に確認とることもできます。(実装者自身が覚えていないことも多々ありますが^^;)
Gitはここまで説明してきたようにファイルのバージョン管理を行うことができるツールですが、それ以外にもとても重要な機能があります。
それは「マージ」と呼ばれる機能で、他の人が実装したコードを自分のコードに取り込むことができます。
仕事ではチーム開発になるため、複数人のエンジニアが同時並行でさまざまな機能の実装を行います。
例えば、開発メンバーが4人いて、Todoアプリの以下の機能を実装していたとします。
- Aさん : Todo1件を新規作成するAPIの実装
- Bさん : Todo一覧を取得するAPIの実装
- Cさん : 既存のTodo1件を更新するAPIの実装
- Dさん : 既存のTodo1件を削除するAPIの実装
最終的にはAさん, Bさん, Cさん, Dさんが実装した機能を1つにまとめることになるのですが、Gitを使わないと、それぞれの人が実装したコードを目視で確認してコピー&ペーストなどで手動でマージすることになります。
手動でのマージは正直面倒な作業で、コピー&ペーストにミスが発生する可能性もあります。
このマージ作業を楽にする機能がGitにはついていて、全員が同じ環境のGit(=リポジトリと呼ぶ)を使っていれば、「git merge」などのコマンドを使うことで、Gitが良い感じに自動でマージしてくれます。
ただし、別々の人が同じファイルに修正を加えた場合、Gitはどのコードを取り込めば良いか判断できないため「コンフリクト」という状態が発生してしまいます。
このときは手動でのマージ作業(コンフリクトの解消作業)が発生するので、このときは慎重に手動マージする必要があります。
Gitの学習をしたいと言う方は、Gitの基本的な操作、マージ、コンフリクトの解消法などについては「Front Hacks」の中でも解説しています。
他にも、過去に書いた以下の記事でも、Gitをインストールした後にまず最初に覚えておきたいコマンドや概念を解説しているので、そちらも参考にしていただけたらと思います。
GitHub
GitHubとはGitで管理しているファイルをリモートで管理できるWebサービスです。
ここでは「リモート」「ローカル」「リポジトリ」という用語を使っていきますが、それぞれ以下のような意味だとここでは認識いただけたらと思います。
- リモート : インターネット越しの向こう側のこと(ここではWebサービスのGitHubを指す)
- ローカル : 自分自身の環境(ここでは自分自身のパソコンを指す)
- リポジトリ : Gitでバージョン管理の対象としているディレクトリ(フォルダ)
1つ前のGitの説明では、主に「ローカル」でのバージョン管理を指していました。
つまり、自分のパソコンの特定のディレクトリ(フォルダ)をGitを使ってバージョン管理対象とすることで、そのディレクトリ内にファイルを作成・修正した際、Gitのコマンドで変更記録をとることができました。
Gitはチーム開発でこそ真価を発揮します。(マージで同時並行で進めてた作業を1つにまとめることができるため)
ただ、自分のパソコン内で変更した作業をどのようにして他の開発メンバーに共有すれば良いでしょうか?
そこで出てくるのが「リモートリポジトリ」となります。
リモートリポジトリはその名前の通り、「リモートにあるリポジトリ」のことを指します。
先ほどの用語の説明でも書いた通り「リモート」はインターネット越しの向こう側のことで、今回の例で言うとGitHubがそれにあたります。
GitHubはローカルのGitリポジトリをオンラインで管理・共有できるWebサービスです。
ローカルのGitリポジトリに変更があった場合、GitHubにその変更した分をアップロードすることで、ローカルリポジトリとリモートリポジトリの同期がとれます。(git pushコマンドを使う)
また、他のメンバーが実装した機能をリモートリポジトリにアップロードした後に、自分の環境にその機能を取り込みたいときは、リモートリポジトリから自分のローカルリポジトリにダウンロードすることで同期がとれます。(git pullコマンドを使う)
リモートリポジトリの選択肢はGitHub以外にもいくつかありますが、仕事で使うリモートリポジトリとして一番代表的なものはGitHubなので、まずはGitHubを覚えれば良いでしょう。
GitHubの基本的な操作も「Front Hacks」の中で解説しています。
Git Flow
Git FlowとはGitを使って開発フローの1つです。
Git Flowというツールもありますが、ツールを使わなくてもGit Flowの概念を取り入れた開発のことをGit Flowと呼んだりもします。
ここで説明するGit Flowもツールのことではなく、概念を取り入れば開発フローを指します。
先ほど、チーム開発ではGitを使って同時並行して開発を進めると言いました。
その時に使うGitの機能の1つに「ブランチ」というものがあります。
このブランチというものをうまく活用することで、効率的に同時並行で開発を進め、最終的にコードをマージするというのができるようになります。
Git Flowの詳細は以下の記事が参考になると思うのでそちらをご覧いただけたらと思います。
コマンド(ターミナル操作)
「ターミナル」とは何かわからない方は、ハッカー(厳密にはクラッカー)が使っている黒い画面のことをイメージしていただけたらと思います。
ここでいう「コマンド」とは、ターミナルに文字を打ち込んで、何かしらの操作を行うことを指します。
Webアプリ開発、スマホアプリ開発など、開発全般でコマンド操作は何かしら行うことになるので、コマンド操作全般に慣れておくことはとても重要です。
このサイトでも以下のリンク先のように、コマンドに関する解説記事や学習スライドを用意しているので、コマンドの学習がしたい方は以下のリンクを参考にしていただけたらと思います。
Docker・Docker Compose
Dockerは「コンテナ型の仮想化ソフト」です。
「コンテナ?」「仮想化ソフト?」と思われた方は、自分のパソコン上に仮想的に別のパソコンを立ち上げるようなものだとイメージしていただけたらと思います。(厳密には正しくない説明だが、イメージは大きく外れていないはず)
Dockerを使うメリットは、どの環境でも同じ開発環境を構築できるところです。
例えば、Aさん、Bさんが同じプロジェクトの開発をしているとします。
プロジェクトでは「Ruby on Rails(バージョン7.1.3)」「MySQL(バージョン5.7.44)」を使ったバックエンド開発を思い浮かべてください。
Aさんのパソコン環境にはRuby on RailsとMySQLの両方ともインストールされていないとします。
Bさんのパソコン環境にはRuby on Rails(バージョン7.1.3)とMySQL(バージョン8.3.0)がインストールされているとします。
Aさんに至ってはどちらもインストールされておらず、Bさんは両方インストールはされていますが、MySQLのバージョンが異なっています。
開発をする上で、一番無難なのは全員のバージョンを揃えることです。
このとき、Dockerの両方がインストールされていればDockerの設定ファイルに「どのソフトを使うか」「どのバージョンを使うか」というのを指定することで、Dockerを使って求めている開発環境を自分のパソコン上に用意することができます。
Dockerの設定ファイルさえ作ってしまえば、あとからCさん、Dさんと開発メンバー増えたとしてもDockerの設定ファイルを共有するだけで、全員同じ環境をすぐに構築できるようになります。
またDockerは開発時だけでなく、本番リリースでも利用することができて、本番でもDockerで指定したソフト・バージョンを準備できるので、自分のパソコン環境とインターネットに公開する本番環境のソフトやバージョン情報を揃えることができます。
これにより、環境の違いによる問題をなくすことができます。
Docker, Docker Composeのもう少し詳細な説明や実際の使い方などは別資料として配布しています。
資料の受け取り方に関しては、以下の記事に書いているのでそちらをご確認いただけたらと思います。
リンター・フォーマッター(ESLint, prettierなど)
リンター(Linter)、フォーマッター(Formatter)はそれぞれ以下のようなツールとなります。
- リンター : コードの記述ルールを設定したり、ルールに従っていないコードがあったらエラーとして教えてくれるツール
- フォーマッター : コードを設定に従って自動的に整えてくれるツール
コードは綺麗に整っていた方が読みやすいです。
また、コードが綺麗に整っていると、文法的におかしな書き方をしているところも見つけやすくなります。
上記のように、コードが綺麗に整っているだけでも開発効率があがります。(逆に言えば、コードが整理されていない場合、不具合も見つけづらく開発効率が悪くなる)
リンターやフォーマッターは言語ごとに用意されているので、開発を進める際はまず最初にリンター・フォーマッターの準備をすると良いでしょう。(特にチーム開発のときはなおさら必要)
フロントエンド開発ツールで有名なもので言うと「ESLint」「Prettier」「Biome」などがあります。
以下のリンク先では実際にPrettierを使っている様子を動画で紹介しています。ごちゃごちゃになっているコードが一瞬で整理される様子がわかります。
ビルド
「ビルド」とは、本番環境用のコードを生成する作業のことを指します。
例えば、Next.jsでフロントエンド開発をする際は、複数のTypeScript(JavaScript)ファイルを作ってフロントエンドの実装を行います。
ローカル開発時では基本的にビルドは行いません。ビルドは時間のかかる作業だからです。
ビルドしていないローカル開発時のコードは、開発しやすいように基本的に開発で書いたコードをそのまま使います。
ここでいう「そのまま使う」と言うのは、改行、スペース、変数名などがそのままという意味です。
プログラムは改行・スペースなどが無くても動きますし、変数名なども極論1文字でも動きます。
ただし、改行・スペース・長い変数名が多ければ多いほど、ファイルサイズは大きくなります。
ビルドでは、ファイルサイズの最適化(=サイズを小さくする)を行うので改行・スペースがなくなり1行の長いコードになります。変数名もファイルサイズを小さくするために文字数が少なくなったりもします。
その他にも、ビルドでは「バンドル(bundle)」と呼ばれる、複数ファイルを1つにまとめる作業も行うこともあります。
開発の会話では「ビルドする」という言葉が使われたりするので、ビルドとはどう言うものか知っておきましょう。
デプロイ
「デプロイ」は開発したアプリを「本番にリリースする」ことを意味します。
開発してから本番リリースするまでのざっくりとした流れは以下のような感じです。
- 機能の開発
- テスト
- ビルド
- デプロイ
「差別化スキル」の中に「CI・CD」が説明しますが、上の流れを自動化したものを「CI・CD」と呼びます。
差別化スキル
設計周り
アーキテクチャ設計
開発での「アーキテクチャ設計」は文脈によって意味が異なってきます。
ここで取り上げる「アーキテクチャ設計」は、プログラムレベルのアーキテクチャ設計となります。
今回取り上げない「アーキテクチャ設計」で、他にもよく思い浮かべられるものとしては、「Webサービス全体のアーキテクチャ設計」もあります。
主にバックエンドのパフォーマンス最適化が目的で、一例ですが以下のようなことを行います。
- バックエンドのAppサーバー, DB, キャッシュの関係性を考える
- バックエンドをマイクロサービス化する
- ジョブキューというのを取り入れて、リアルタイムで処理する必要のないものは非同期で処理を行うようにする
ここでいうと「プログラムレベルのアーキテクチャ」とは、以下のようなことをイメージしていただけたらと思います。
- クラスが役割ごとにうまく分割されている
- クラスがテストしやすい形に実装されている
- 疎結合な実装がされている(あるファイルを修正しても、他のファイルに影響を与えない)
上記はあくまでも一例ですが、ここで言いたいことは「アプリのプログラム全体が綺麗に整備されていて、保守・運用がしやすい形で実装されている」ことです。
これを実現する手段に「アーキテクチャ設計」という考え方があり、アーキテクチャ設計の方法はいくつかパターン化されています。
以下に代表的なプログラムのアーキテクチャ設計を3つほどあげておきます。
- レイヤードアーキテクチャ
- ヘキサゴナルアーキテクチャ
- クリーンアーキテクチャ
プログラムのアーキテクチャ設計周りの学習には以下の書籍が比較的とっつきやすいかと思います。
僕の過去に書いた記事で、クラス間を疎結合にしてテストしやすい形の実装方法について解説しているものがあるので、以下の記事も参考にしていただけたらと思います。(サンプルコードと図を交えて解説しています。)
デザインパターン
プログラミングには「デザインパターン」と呼ばれるものがあります。
デザインパターンは「オブジェクト指向プログラミング」で使われる実装テクニックをまとめたものです。
デザインパターンは常に使うというものでもありませんが、知っておくと便利なテクニック(プログラミング設計の手段)くらいに思っていて問題ありません。
例えば、先ほども紹介した以下の記事では、テストを書きやすくする手法として「DI(Depencency Injection) = 依存性の注入」という実装テクニックを使っています。
デザインパターンは種類がいっぱいあるので、全てを覚えるのは大変ですが、一度まとまったものを見ておくことで「こんな実装方法があるんだ」「たしかにこの実装は綺麗だ」と実装の引き出しが増えるかと思います。
デザインパターンを見てみたいと言う方は以下のサイトや書籍が参考になるかと思います。
- TECHSCORE > デザインパターン(サイト)
- Java言語で学ぶデザインパターン(書籍)
上記のサイトや書籍で紹介されているコードはJavaで書かれていますが、クラスをプログラミング言語(TypeScript, Ruby, PHPなど)を使った経験がある方であれば読めるかと思います。
開発フロー
CI・CD
CI・CDはそれぞれ「Continuous Integration(継続的インテグレーション)」「Continuous Delivery(継続的デリバリー)」の頭文字をとった言葉です。
CI、つまり継続的インテグレーションでよくあるものとしては、「実装したコードに問題がないかの確認(=テスト)」の自動化があります。
自動化の方法はいろいろとありますが、GitHubを使っている場合は「GitHub Actions」という機能を使うのも1つの手でしょう。
仕事ではGitHubのプルリクエストという機能を使って、他の人が実装したコードを確認し問題があれば指摘します。(=コードレビュー)
コードレビューの際は、テストにエラーが発生していないことが前提とするのですが、テスト自動化の仕組みを構築していないと、コードレビューする人は毎回以下の作業をする必要が出てきます。
- 自分のパソコンにレビュー対象のコードをダウンロードする
- 手動でテストを実行する
たった2つの作業だけと思われるかもしれませんが、この作業が積み重なるとかなりの時間の消費となります。
CIの自動化をするだけでも、仕事の開発(チーム開発)の効率はかなりよくなります。
次にCDの説明にはいります。
CD、つまり継続的デリバリーが意味するのは、継続的に最新のアプリを本番にリリースする作業の自動化を指します。
例えば、CDを実現する一例としては以下のようなものがあります。
前提として、Git Flowを使ってチーム開発を進めていて、複数のエンジニアが実装したコードが全部developブランチにマージされている状態とします。
- developブランチを本番用ブランチであるmainブランチにマージする
- mainブランチにコードがマージされたら、テストを実行する
- テストが問題なく完了したら、ビルドを実行して本番用のコードを生成する
- ビルドが問題なく完了したら、本番環境のサーバーに本番用コードをアップロードする
- 5が完了したら、ユーザーは最新のアプリを利用できる
ここまで色々と説明を書いてきましたが、とりあえず、CI・CDは「開発効率を上げる自動化プロセス」ということがわかっていただけば現状は問題ありません。
アジャイル・ウォーターフォール
「アジャイル」と「ウォーターフォール」はいずれも開発の進め方の手段になります。
ざっくりとそれぞれの違いを説明すると以下のようになります。
- アジャイル
- 2週間前後の開発サイクルを繰り返す
- サイクルごとに開発スケジュールを立てる
- ウォーターフォルと比べて、開発途中の仕様変更に対応しやすい
- 細かい仕様決めや設計は、開発メンバーに委ねられる
- 柔軟性が高い
- 主に小・中規模開発向け
- ウォーターフォール
- 開発開始から完了までのスケジュールを最初にたてる
- 全体の仕様決めやドキュメント作成に時間がかかる
- 設計はトップが行い、開発メンバーは用意された仕様・設計に従って実装を進める
- 最初にスケジュールを決めているので、開発途中の仕様変更が難しい
- 柔軟性が低い
- 主に大規模開発向け
アジャイルの最後の方に「主に小・中規模開発向け」と書きましたが、有名な開発企業はアジャイル開発を選択している印象があります。
アジャイル開発を選択している理由としては、「開発の柔軟性」があるからだと個人的に考えています。
今の時代、ユーザーの行動が追いやすくなっているので、いろんな仮説・検証を短いサイクルで行い、サービスを早いサイクルで改善することが可能となってきています。
仮説・検証を短いサイクルで行うには、開発までに時間がかかり、途中で仕様変更が難しいウォーターフォール開発よりも、比較的早く開発に取り掛かれて、仕様変更にも柔軟に対応しやすいアジャイル開発の方が今の時代にあっていると考えています。
アジャイル開発で開発を進める際、「スクラム」という手法で開発を進めることが一般的な印象なのです。
スクラムについてざっくりイメージを掴みたい方は、以下の書籍が参考になるかと思います。
その他
クラウドサービスの知識(AWS, GCPなど)
現役のWebエンジニアでもAWSやGCPの求められるスキルは人それぞれ異なります。
インフラエンジニア寄りの人であれば、AWSやGCPの知識はそれなりに持っていた方が良いと思います。
しかし、アプリ開発寄りのWebエンジニアの場合、ゼロからクラウドサービスでシステムを構築することはそこまで多くありません。
一番最初にシステムを構築する際は、全体の設計を考えるところから始めて、クラウドサービスのどの機能を使うか決めますが、そういった作業は大抵、インフラにも強いエンジニアが最初に構築して、他のエンジニアはその仕組みを利用することが多いです。
それでも、その仕組みを利用するにはクラウドサービス(AWS, GCPなど)の操作は知っている必要があるので、多少なりともクラウドサービスは触っておくと良いでしょう。
とはいっても、クラウドサービスを使って、Webサービス全体の設計を考え、実際に構築まで行い、Webアプリの運用までできている場合は、他のWebエンジニアとかなりの差別化になります。
正直な話、僕自身そこまでがっつりクラウドサービスを使ったシステム構築を行ったことがないので、現役エンジニアにも「ここまでできてすごい!」と思われる部分になります。
個人的な感覚になりますが、ここまで出来る人であればWebエンジニア就職・転職に困ることはないと思います。
他のWebエンジニアと強い差別化ポイントを持ちたい人は、AWSやGCPといったクラウドサービスのスキルを身につけてみてはいかがでしょうか?
GraphQL
「GraphQL」はフロントエンドとバックエンドがデータのやりとりをする1つの手段です。
似たようなものに、必須スキルのパートでも説明した「REST API」というものがあります。
REST APIでは、データのやりとりの種類ごとにURLを用意して、CRUD操作の種類に応じて、異なるHTTPメソッドを使うのが特徴です。
つまり、異なる種類のデータのやりとりを行うには、その種類の数だけリクエストが発生していしまいます。
例えば、1つのページ内に「ブログ記事一覧」「ニュース一覧」があるとして、それぞれを厳密にREST APIのルールに従って分けると以下のリクエストを送ることになります。
- ブログ記事一覧の取得 : GET /posts
- ニュース一覧取得 : GET /news
上記の例では2つのデータの取得だけを行いましたが、他にも取得したいデータが増えれば増えるほどリクエスト数は増えていきます。
それに対してGraphQLでは、取得したいデータが何個あったとしても、リクエストは1つだけで済みます。
どのようにしてそれを実現しているかについては、ドキュメントや記事などを参考にしていただけたらと思いますが、簡単に仕組みを説明すると以下のような方法で実現しています。
- APIのエンドポイントは1つだけ用意する
- クライアントはAPIリクエストを投げる際に、リクエストボディの中に欲しいデータの詳細を書く
- 例えば、「ブログ記事一覧」と「ニュース記事一覧」が欲しい場合は、リクエストボディの中に「posts」「news」という文字を含める
- サーバーはクライアントから送られてきたデータを確認し、クライアントが求めている情報を返す
GraphQLの全体像を把握したい場合は、以下の記事が参考になるかと思います。
オリジナルアプリの開発
書籍や動画教材の中で紹介されているアプリを作るだけでは、開発スキルが実はそこまで身についてないパターンがよくあります。
いわゆる写経だけでアプリを作っても、それは自分で考えて実装したわけではないので、「ゼロから自分で実装をしてください」となった場合、手が止まってしまうという感じです。
その問題を解決するには、「オリジナルアプリをゼロから作る」というのが実践的なスキルを身につけるのに良いでしょう。
ここでいうオリジナルアプリとは「必須スキル」で取り上げた内容を一通り盛り込んだアプリを指します。
また、可能であれば、現役エンジニアにGitHubのプルリクエストを使ってコードレビューしてもらうのもおすすめします。
コードの指摘を受けてプログラミングスキルが向上するだけでなく、仕事でも行われる以下の実践(擬似体験)もできるからです。
- ブランチを活用した開発(Git Flow)
- GitHubの操作(プルリクエストの作成や、プルリクエスト上のコメントのやりとり)
- ローカルリポジトリとリモートリポジトリの同期(git push, git pull)
- (オプション)テストの自動実行(CI環境の構築)
コードレビューの依頼をするのに必要なスキルは、教材では中々身に付けられないスキルですが、現場では絶対に必要なスキルです。
実践的なコードレビューのやりとり経験があると、就職・転職したあとにチーム開発にすんなり参加しやすくなるかと思います。
Webエンジニアを目指している人向けの学習サポートを、不定期でメルマガにて案内しております。
この学習サポートの中ではコードレビューも行なっています。
この学習サポートに興味がある方は、以下のメルマガにご登録してお待ちいただけたらと思います。
さいごに
以上、2024年版のWebエンジニアを目指す人が身につけておくべきスキルを色々とまとめてきました。
必須スキルだけでも結構なボリュームでこれから学習を始められる方には、もしかしたら心を折ってしまう内容になったかもしれません。
ただ、現場で求められるスキルや知識を一通り洗い出すと、これは大袈裟な内容ではありません。
基本的に、今回書き出した内容は、今後もWebエンジニアなら求められるスキルなので、一度身につければ長いこと使えることでしょう。
みなさんの学習を応援しております。
学習に関して質問や相談がある方は、以下のLINE公式アカウントにメッセージをいただけたらと思います。
また、不定期でメルマガでも学習サポートの案内や、相談受付の案内を流したりしているので、メルマガの方もご登録いただけると幸いです。