「そうだ、Webサービス作ろう」と思ったらエンジニアが自分だけだった人のための最低限の要素技術まとめ

仕事で、趣味で、何かコンシューマー向けのWebサービスをまったくの0から作ろうと思った時、理解してると全体像がイメージできて具体的に手を動かし始めやすいであろう要素技術や知識のまとめです。技術的な詳しいところの考察というよりは、こんな領域の理解が必要になるよ、という紹介の記事です。

なお、紹介する技術が多岐に渡りますので、各技術の参考リンクはあえて貼りません。詳しくは記事内のワードを元にネットなり書籍なりで調べていただければと思います。

想定読者としては、「システムの一部分を担当して開発・運用してはいるけれど、担当以外の各技術についてはあまり詳しくない」という感じのエンジニアの方です。


では書いていきます。

# ユーザーが触れる部分を作る（アプリ）
何はなくともユーザーが触れる部分が必要です。一般の、エンジニアではない方々が触る機器と言ったら今はPCのブラウザかスマートフォンアプリでしょう。まずはここを作る技術についてまとめます。
（ガラケー向けサービスは作ったことがないので省略します。。。すみません。。。）

## スマートフォンアプリを作る
+ Android
    + Java
+ iOS
    + Objective-C
    + Swift

一般的にAndroidならJavaを、iOSならObjective-CかSwiftでアプリを作ります。実際はKotlinやGo言語でのAndroid開発、Javascriptでの両プラットフォーム向けのアプリ開発等、他にもアプリ開発の手段はありますが、まずは基本として上記の言語での開発をしてみると良いでしょう。

また、携帯端末はPCに比べてスペックが劣り、用途も限定されているという特性上、Android、iOSの各プラットフォーム特有の事情や制約があります。アプリが安定して動作し、ユーザーが操作しやすいアプリにするためにはそれらの事情を考慮した開発が必要になります。Google、Appleから出ているガイドラインを読みながら開発を進めましょう。

## Webアプリを作る
+ 必要となる言語
    + HTML
    + CSS
    + Javascript
+ PCサイトの公開
    + サーバーのレンタル

まずはHTMLでページの大枠を作り、CSSで綺麗にレイアウトを整えます。
「クリックしたらこの画像がふわっと切り替わって...」などのような「動き」をつけたい場合にはJavascriptが登場します。決まった文字とリンクだけの「Webサイト」ではなく、ユーザーの入力やサーバーでストックしているデータを元に適切な情報を提供する「Webアプリケーション」を作りたいのであればJavascriptも必須でしょう。

また、PCサイトを公開するにはサーバーが必要です。
自前で物理的にサーバを用意するのは金銭的、時間的なコスト面で現実的ではないためレンタルサーバの利用がオススメです。さくらVPS、Amazon EC2などがあります。

## アプリのまとめ
これで、ユーザーが触れる部分が作成可能になりました。

ただし、これだけではサービスとしては非力です。アプリやWebアプリだけではユーザー間の情報の共有、リアルタイムに変化する情報の配信、大規模なデータの提供など、Webサービスを作る上で欠かせない要件が実現できないからです。

次に、それを実現するためのサーバーの技術を見ていきます。

# 共通のデータを管理する（データベース）
例えば、twitterのように「Aさんが投稿した内容をBさんも見られるようにしたい」と思った場合、どうすれば良いでしょうか。

投稿した内容がAさんの携帯の中に保存されていてはBさんの携帯でそれを見ることはできません。どこか、AさんもBさんもアクセスできる場所に保存する必要が出てきます。で、その「AさんもBさんもアクセスできる場所」がサーバ上のデータベースです。

どの端末からでもアクセスできるサーバーとそこで動作するデータベースを用意し、そのデータベースに投稿を保存することで、他のユーザーも保存された投稿を閲覧することができるようになります。

一言に「データベース」と言っても、RDB、KVS、全文検索などいろいろと種類がありますが、データベースを初めて勉強する方はまずはRDBのMySQLを試してみると良いと思いますので、そちらを説明します。

## RDB（Relational DataBase）
RDBは、「データベース」として一番よく使われる形式で、列と行の形式でデータをまとめ、「この列の値が○○のデータを取得する」のように検索します。列と行、という意味ではエクセルのようなイメージが近いでしょうか。実際のデータの操作はSQLという言語を使います。

RDBは工夫次第で幅広い要件のシステムで活用でき、かつSQL自体がRDBの製品でほぼ共通の汎用的な技術であるため、初めてデータベースを使ってみるのであれば最適です。また、幅広く使われる汎用的な技術ということは、先人たちのノウハウがネット上にいくらでも上がっており、書籍等も豊富ですので、何かに困った時に頼る先が多いことも一人で初めて勉強する際に大きな助けになる要因です。

製品としては以下のようなものがあります。

+ Oracle
+ MySQL
+ PostgreSQL

まずは、まずは情報量が多く、無料で使え、多くのプログラミング言語で操作できるMySQLを使ってみると良いでしょう。サーバーがすぐに用意できない、という方はとりあえず自分のパソコンにインストールして使ってみることも可能です。自分の好きな言語とMySQLで簡単なTODO管理アプリケーションを作ったりすることで、データの追加、検索、削除、更新等の一通りの基礎が身につくはずです。

## データベースのまとめ
複数のユーザーがアクセスできる場所にデータベースを用意し、そこにデータを保存していくことで、一気に「Web」のメリットを活かせるサービスを作ることができます。

しかしながらデータベースには様々な種類があり、その用途（googleのようにユーザーからの検索・参照が多いのか、それともtwitterのように更新が多いのか、等）によって最適な製品も異なります。自分の製品を「ちゃんと」作ろうと思ったしっかりとそれぞれの製品の違いを把握し、要件によって最適な製品を判断しなければなりません。

そのような製品や検索技術の違いを理解するためにも、まずは土台としてMySQLに慣れておくことをオススメします。MySQLを基準として他の技術を比較することで、その技術を0から勉強しようとするよりも理解が格段に早くなるからです。

# アプリとデータベースをつなぐ（Webサーバー）
さて、これでユーザーが目にする部分と、ユーザーと他のユーザー（及び開発者）が接点を持つためのデータ保存の仕組みが見えてきました。

しかしこれだけではまだサービスとしては動かせません。アプリが直接データベースにアクセスすることができないからです。（正確には「できない」というよりもアプリが直接データベースにアクセスできてしまうとデータベースへの負荷やセキュリティ面など、様々な問題が発生するからです）

それを解消するために「Webサーバー」が必要になります。アプリからの通信リクエストを受け取り、その内容を解釈して実際にデータベースを操作するシステムです。
単純に検索した結果をそのままアプリに渡すだけでなく、「このリクエストってことはこれとこれのデータをそれぞれ検索してくっつけて、あ、これはiPhoneからのリクエストだからこの情報もくっつけて、アプリバージョンはこれだからこの情報は不要だな」というような複雑な処理もここで何とか制御します。限られた人しか使えないようなサービスなのであれば、ユーザーの認証の仕組みもここで作らなければなりません。

何かとやることが多く、目に見えない部分であるサーバーは難しく考えられがちですが、システム的な流れはとても単純です。

1. アプリがリクエストを送信する
2. サーバーがそのリクエストを受信する
3. 受診した内容を元に、適切なプログラムを実行する
4. プログラムの実行結果（レスポンス）を、アプリへ返却する
5. アプリがレスポンスを受信する

これだけです。

それぞれの工程を実現するために

* 受信したリクエストを解釈し、適切なプログラムを実行する仕組み
* 実際に処理を行うプログラム

の２つの要素が必要になりますので、それぞれ説明します。

## 受信したリクエストを解釈し、適切なプログラムを実行する仕組み
僕の知る限り、この仕組みはapacheというソフトウェア一択です。
apacheをサーバーにインストールし、作りたいシステムに合わせて設定ファイルを書くことによってアプリから受け取ったリクエストがどの処理を実行すべきものなのかを判断できるようにします。

IP制限などの「そもそも処理を実行すべきでない」の判断や、「誤ったリクエストが来た場合は一律このエラー画面を表示する」、というようなリクエスト自体のエラー処理もapacheの設定で行います。

簡単なリクエストの振り分けだけであればapacheでなくても後述するWebサーバープログラム自体がその役割を持っている場合があるのですが、一つのWebサービスとして運用するのであればリクエスト自体の処理を専門とするapacheを入れておくことをオススメします。汎用マシンであるサーバーは何でもできてしまう特性上、考えてシステムを作り上げないとすぐに複雑になり、どこで何をしているのかが分からなくなってしまいます。
apacheはリクエスト自体の処理を、後述のサーバープログラムは自分がコーディングした処理を、という役割分担を明確にしておくことで、後々の機能追加やバグ修正等が楽になります。

## 実際に処理を行うプログラム
さて、最後にサーバープログラムについてですが、これは動作するサーバー自体が汎用マシンであるという都合上、とても多くの選択肢があります。また、最終的なアウトプットが「データ」なのか「Webページ」なのかによっても選択肢が変わってきます。

というわけで、一般的に広く使われていて情報も多く、とっつきやすい技術の観点でいくつか列挙してみます。

* アプリとのデータのやり取りのみの場合
    * Java（Servlet）
    * Javascript（Node.js）
    * Python
* ブラウザにWebページを表示したい場合
    * PHP
    * JSP（Servletと組み合わせ）
    * Ruby on Rails
    * Python（Django）
 
おそらく「アプリとのデータのやりとり」という用途では一番世の中で広く使われているのがJavaで書けるServletなのではないかと思います。（僕も普段の仕事ではServletを使っています）
また、「ブラウザ上のWebページ」の用途であればPHPかRuby on Railsではないでしょうか。

どちらも「処理の結果文字列データを返却する」という点では同じで、その文字列の形式がJSONやXMLであればアプリとサーバーとのデータのやりとりに使われ、HTMLであればブラウザで表示する用途で使われることになります。「ブラウザにWebページを表示したい場合」で紹介した技術は、処理の結果をHTMLに反映させやすくしてくれる技術だと考えると良いでしょう。

何かしらの処理をする、という点ではどちらも共通していますので、ここでは基本となる「アプリとのデータのやり取りのみの場合」のサーバープログラムを作ってみることを考えてみます。

とりあえずデータベースにアクセスして簡単なデータ追加と検索をしたいのであれば、Pythonがオススメです。
Servletはプログラムを書いたらビルドして.warファイルを作り、それを予めtomcatというソフトウェアをインストールしたサーバー上にアップロードして.warファイルを展開する（デプロイする）、という面倒な手順が発生する一方、pythonはサーバーにpythonさえインストールされていれば、書いたソースファイルをそのまま実行するだけでサーバープログラムとして動作するためです（サーバーとして使うであろう多くのLinuxマシンでは初期状態でpythonがインストールされています）。修正も、ソースファイルを書き直して保存したら再度そのプログラムを実行し直すだけというお手軽さです。

サービスとして動作させたい場合は、サーバー操作をやめても（ログアウトしても）プログラムが動き続ける仕組みやプログラムが異常終了しても自動で再実行される仕組み等の安定運用の仕組みが必要になりますが、それはサーバープログラムに慣れたころにまた検索してみると良いでしょう。

なお、「サーバープログラム」とは言っても、「リクエストをきっかけにプログラムがスタートし、最後はレスポンスを返却して終了する」という点を除けば普通のコンソールアプリケーション（自分のPC上だけで動作するプログラム）と同じです。例えばデータベースの操作なんかはサーバーだから特別なことをしなければならない、ということはありません。何か調べたりする際も「サーバーだから」というフィルターをかける必要はないでしょう。

## Webサーバーのまとめ
データベースに蓄積したデータを使って、サービスとして価値のある情報をユーザーへ届けるためにWebサーバーが必須となります。
しかしながら、サーバーと言うとインターフェイスが文字のみであるために何が起こっているのか理解しづらく、また汎用マシンであるために選択肢が幅広いことから何かと理解するのが難しい部分であるのも事実です。

難しくしようと思えばいくらでも難しく、簡単にしようと思えばいくらでも簡単にできるのも特徴ですので、まずは簡単にapacheとpythonとmysqlで簡単なWebアプリケーションを作ってみて、そこからその他の技術に理解を広げていくのが良いでしょう。「LAMP」という言葉にもある通り、これがWebアプリケーションのテンプレートのひとつと考えていても差し支えないはずです。

リクエストを受け取り、それをきっかけにプログラムが実行され、プログラムの結果何かしらの文字列をリターンする、というざっくりとした流れを抑えたうえで、また紹介したそれぞれの技術がその流れのどの部分を担当しているのかを理解した上でシステムを作っていけば、少しは理解が楽になるのではないかと思います。

# 全体のまとめ
以上で、一つのサービスを構成する一連の技術を大雑把に説明してきました。

しかしながら、この記事ではサービスの構成要素の全体像をざっくりと理解するという目的のため、それぞれの技術の使い方や勉強のし方を説明しているわけではありません。実際にそれぞれに手を付け始めるときに、今回紹介したワードを元に改めて調べていただけると良いでしょう。なるべく一般的で参考になる情報が豊富なものを選んだつもりですので、「調べても誰もやってないし何も情報がないよ」という事態になることは少ないはずです。

なお、この記事では意図的に「Linux自体の理解」という要素を割愛しました。
この記事で紹介した技術は、アプリ開発以外はすべてLinuxの操作を理解していることが前提となっているのですが、それを説明していると記事が長くなりすぎてしまい、また「サービスの構成要素の紹介」のスタンスでは説明が難しいためです。
需要があれば「とりあえずWebサービスを作るために必要なLinux操作の知識」という感じで別記事にまとめたいと思いますので、コメントを頂ければと思います。

また、一般によく使われるフレームワークの紹介も省略しています。（Ruby on RailsやDjangoは書いちゃいましたが）
これは、目的によって最適なフレームワークが全くことなることと、最初からフレームワークありきで各構成要素を理解してしまうと、できること・できないことの理解等がそのフレームワークに依存してしまうのではないかと思ったからです。
フレームワークは特定の状況での開発には大きな手助けとなりますが、そもそものサービスの構成要素の役割を理解する、という点では不要だと判断しましたので、あえて省略している次第です。

# さいごに
今までなんとなくのサービスであれば自力で作れると思っていたのですが、実は人に説明できるほど理解できていない部分がとても多いことにこの記事を書いていて気づかされました。おそらく書いてある内容も見る人が見たら変な部分が多々あるかと思います。用語についても一般的な使われ方とは違うものがあるかもしれません。
また、説明の粒度もとても悩ましく、細かなところまで説明しすぎだったり、逆に説明が不足していて理解不能な部分もあるかと思います。
そのような場合はぜひコメント欄にご指摘をいただければと思います。できる限り加筆、修正します。

とても長くなってしまった気がしますが、最後まで読んでいただき、ありがとうございます。
これを読んで、自分の得た技術を使ってユーザーに何かを発信したいと思える（そして実際に行動に移せる）方が一人でもいらっしゃれば嬉しいです。