いきなりWebアプリケーションエンジニアになった未経験者に最低限知っておいてほしいこと

# あらすじ

サラリーマンをしていると、自分の望まない仕事もしないといけません。
今までWebアプリケーション開発に携わったことがないけれど、仕事でやることになったので急遽知識が必要になった方向けの記事です。

# Webアプリケーションとは

Microsoft EdgeやGoogle ChromeやFirefoxなどのウェブブラウザでアクセスしてログインしてポチポチして登録とか更新とか閲覧とか削除とかするソフトウェアです。
ヤフーにしろグーグルにしろアマゾンにしろ楽天市場にしろ、ウェブブラウザを使って利用するソフトウェアはWebアプリケーションです。
特徴としては、クライアント/サーバーシステム（いわゆるクラサバ）と違い、**クライアント端末（パソコン）に特定のアプリケーションをインストールする必要がありません。**
つまり、ウェブブラウザとインターネット環境さえあれば誰でも利用でき、基本的にはクライアント端末のOSや性能による制約を受けることが少ないことが特徴です。

# Webアプリケーション概略図

めっちゃ適当に書くとこんな感じ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179043/9a38fe6f-a55c-1316-aac7-a1d806c72994.png)

Webアプリケーションを構成する技術には様々なものがあります。
難しい話は抜きにして、最低限理解しておきたいところを説明します。

# クライアントサイドとサーバサイド

Webアプリケーション開発でまず知っておきたいのが、クライアントサイドとサーバサイドという考え方です。
これは簡単に言うと、クライアントサイドは自分のPCやスマホといったユーザー側で、サーバサイドはWebページを表示するためにPCやスマホにデータを送ってくれる相手側のことです。
まずはサーバサイドから。

## サーバサイド

ユーザーからの要求（リクエスト）に応じて処理をして応答（レスポンス）する役割を持ったものがサーバサイドです。
実装については、JavaやC#やVB.NETやPHPやRubyやPythonやPerlやGoなどのプログラミング言語を使用します。
データベースからデータを取り出したり保存したりする処理はこちらで行います。
2層アーキテクチャや3層アーキテクチャといった言葉を聞いたことがあるかもしれません。
リクエストを受け付ける「Webサーバー」、処理を実行する「アプリケーションサーバー」、データを保存する「データベースサーバー」というような分け方をしたりしますが、これらはすべてサーバサイドの技術です。
サーバーは、クライアントからのリクエストがあった時に処理を実行してクライアントに結果を返します。
クライアントからのリクエストがなければ基本的には何もしません。

## クライアントサイド

ユーザー（クライアント）側の処理のことです。
ウェブブラウザでネットサーフィンをしていると、Cookieの使用許諾が出てきたり、いきなり画面全体に広告が出たり、Google翻訳で文字を入力しているだけで勝手に翻訳が始まったりしますよね。
あれはクライアントサイドの技術になります。
HTMLというマークアップ言語で構造を定義し、CSSという見た目を定義する言語（言語じゃない気がする）で見た目を調整し、JavaScriptという言語で動きを加えます。
JavaScriptは基本的にクライアントサイドで動作します。
つまり、**ユーザーのPCスペックやスマホのスペックの影響を受けます。**
とはいっても、昔ほど意識する必要はないと思います。
クリックや入力やタップなど、何かしらの操作によってイベントというものが発生します。
ゲームで言うところのエンカウントみたいなイメージです。
これによってプログラムが動作します。
このように、ユーザーによる特定の操作に応じてプログラムを実行することをイベントドリブンと言ったりします。

# HTTP通信

クライアントサイドとサーバサイドのイメージが付いたところで、それぞれの橋渡しになるものの説明をします。
クライアント側からサーバー側にリクエストを送ったり、サーバー側からクライアント側にレスポンスを返すときに用いるものがHTTP通信になります。
送る方法は、HTMLで記述されたsubmitもしくはJavaScriptで行います。

## 同期通信と非同期通信

クライアントとサーバー間のHTTP通信において、同期通信と非同期通信があります。
同期通信では、クライアントからサーバーへリクエストを送信した際、サーバーからのレスポンスがあるまで待機します。
ウェブブラウザのタブがくるくる回っていたら同期通信です。
また、同期通信では画面がリフレッシュされます。
F5を押して再読み込みするのと同じようなことです。
HTMLでいうsubmitは同期通信です。

非同期通信では、クライアントからサーバーへリクエストを送ってもクライアント側は別の処理を実行できます。
レスポンスがあったらそれに応じて処理を続行します。
ウェブブラウザ上で動的にデータの取得や更新を行う際に非同期通信を利用します。
非同期通信では画面の一部のみを差し替えたりできます。
JavaScriptで実装します。

## メソッド

HTTP通信の際、メソッドというものがあります。
HTMLでは、formタグのmethod属性で指定します。

### GET

GETメソッドでは、URLの後ろにクエリストリング（クエリパラメータ）というものが付きます。
URLの後ろに？マークを付け、その後ろにキーと値の組み合わせで記述されます。
クエリストリングには長さ制限があったりするので大量のデータをGETメソッドで送ることはありません。
また、パラメータがURLに乗るので秘匿すべき情報はGETメソッドでは送らないのが一般的です。

### POST

POSTメソッドではHTTPリクエストのボディにデータが乗ります。
ウェブブラウザに表示すべきHTMLもレスポンスのHTTPボディに入っています。

## ヘッダーとボディ

話が前後しますが、HTTPにはヘッダーとボディがあります。
URLはヘッダーにあります。
POSTした際のデータはボディにあります。
データの形式がなんであるかは、ヘッダーで指定します。
リクエスト時もそうですが、レスポンス時もヘッダーで指定されています。

# 終わり

端折りすぎたかもしれない。
ここから先は、より具体的なお話です。

---

# Appendix

## JavaScriptでの非同期通信とサーバサイドの処理

JavaScriptでform要素内のデータをsubmitすることもできますが、昨今は非同期通信を当たり前のように利用します。
Twitterをウェブブラウザで開いている際に下にスクロールするとその都度データを取得して表示していますよね。あれです。
JavaScriptでの非同期通信のことをAjaxと呼びます。
昔はXML形式でデータのやり取りをしていましたが、今はJSON形式でデータのやり取りをするのが一般的です。

同期通信と非同期通信で、サーバサイドの実装も変わります。
同期通信ではウェブブラウザ上に描画するためのHTMLをレスポンスとして返す必要がありますが、非同期通信では必要なデータのみを返します。
そのため、JSON形式のデータを作成してレスポンスとして返すことになります。
サーバサイドで利用するプログラミング言語が何であっても、その言語のフレームワークを使用して開発するでしょうからそのフレームワークにJSON形式でレスポンスを返す機能が大抵あります。

## JavaScriptでの非同期通信における注意

JavaScriptで非同期通信を行う際、非同期処理のため、実行結果を受け取る前に処理が進んでいきます。
そのため、実行結果を受け取ってから処理する必要があるものについては**コールバック関数**というもので処理したりします。
jQueryで説明すると、以下のような感じです。

```js

$.get('/foo/bar', function(data) {
    // /foo/bar というURLに対してリクエストを送った際に、レスポンスが data に入っている
    console.log(data);
});
// こっちの処理は上のconsole.logより先に実行される
console.log('hello, world!');
```

上記の例で、`function(data)`の関数定義は**無名関数**というものです。
この無名関数内の処理が、非同期通信の結果を受け取った後に処理されます。
JavaScriptの関数は**第一級関数**というもので、関数自体を変数に代入したりすることが出来ます。
つまり、`$.get`は以下のような実装イメージだと思うと理解できます。

```js
function get(arg1, arg2) {
    // 以下はただのイメージです
    var response = http.get(arg1);
    arg2(response);
}
```

第二引数で受け取った変数を関数実行し、その前に受け取っているレスポンスを引数としてセットしています。
無名関数として定義している`function(data)`の`data`はいわゆる**仮引数**なので、`get`メソッド内で引数として渡している`response`が`data`として無名関数内で利用される、というイメージです。
このイメージが理解できていないと、非同期通信後に行う処理を先に実施してしまったりといった不具合を引き起こしてしまいます。

---

ひとまずこのあたりで。
後日追記するかもしれません。