Webアプリケーション。なんだかものすごく複雑そうなイメージがありますが、
Webアプリなんて、その本質は、実に単純なものです。PythonでかんたんWebアプリを作って、本質を学びましょう。
Webアプリとはなにか?
Webアプリとはなにか?その本質はズバリ、
テキストを、作り出して、表示する、ソフトウェア
これだけです。
Webアプリには様々な技術がありますが、そのすべては、この単純なやりとりを補完しているだけです。
WebブラウザとWebサーバ
Webアプリに登場するのは、WebブラウザとWebサーバ、このふたつ。やっていることは、
- Webブラウザ テキストを表示する
- Webサーバ ブラウザが表示するためのテキストを作る
本質を言えば、ただこれだけ。
Webブラウザ:テキストを表示するソフトウェア
Webブラウザ=ふだん使っている Chrome や Edge のこと。
ブラウザはテキストを表示します。ただし、テキストに装飾の指定があれば装飾してくれます。「文字を太くして」「赤くして」「真ん中にして」という指定があれば、それに従った表示にします。
このような「文字を太くして」「赤くして」「真ん中にして」といった装飾指定のルールを取り決めているのが、HTML と CSS です。
画像や動画といったものも、HTMLで「ここに画像を表示するよ」と書いておけば表示してくれます。
Webサーバ:テキストを生成して送るソフトウェア
Webブラウザでは、HTML と CSS の形式で書かれたテキストを表示します。
このテキストを作り出すのが、Webサーバです。
Webサーバという言葉は「Webサーバというソフトウェア」「Webサーバソフトが動いているハードウェア」どちらの意味でも使います。ここではソフトウェアを指しています。
Webアプリを作ってみよう
テキストを作る、表示する。これだけだったら、Webアプリを作れそうな気がしてきませんか?
作るのは、Webサーバ
Webアプリには、WebブラウザとWebサーバがあるわけですが、このうちWebブラウザはChrome や Edge のことなので、既にあります。
なので、これから作るのは、Webサーバです。
使うのは、Python
Webサーバを作れるプログラミング言語はいろいろあります(後述)が、ここではPythonを使います。
Pythonは、特別なフレームワークやライブラリがなくてもWebサーバが作れます。(フレームワークもありますが)
なのでWebサーバがお手軽に作れます。
PythonでWebサーバを作る(1)基本のHello,Word
まずは、はじめてのプログラミングの基本、Hello,Worldです。Hello,Worldを表示するだけのシンプルWebサーバです。
コードを書こう
Pythonで書きましょう。特別なライブラリは不要。素のPythonだけでできます。
server.py という名前で保存します。
from http.server import HTTPServer
from http.server import BaseHTTPRequestHandler
# リクエストハンドラ
class CustomHTTPRequestHandler(BaseHTTPRequestHandler):
# Get
def do_GET(self):
# レスポンスコード
self.send_response(200)
self.send_header('Content-type', 'text/html; charset=utf-8')
self.end_headers()
# コンテンツ
html_context = '<html lang="ja">' \
' <head>' \
' <meta charset="UTF-8">' \
' <title>はじめてのWebサーバー</title>' \
' </head>' \
' <body>' \
' <p>Hello,World</p>' \
' </body>' \
'</html>'
self.wfile.write(html_context.encode())
# アドレス
server_address = ('localhost', 8080)
# Webサーバー起動
with HTTPServer(server_address, CustomHTTPRequestHandler) as server:
server.serve_forever()
実行しよう
書き終わったら、プログラムを起動します。以下のコマンドで起動。
python server.py
これでWebサーバが起動され、ブラウザからの要求を待っている状態になります。
ブラウザ(ChromeやEdge)を立ち上げましょう。アドレス欄に以下を打ち込みます。
http://localhost:8080
これで、ブラウザに、Hello,Worldが表示されます。
なにが行われているのか
この過程では、以下のことが行われていいます。
- Webサーバを起動 Webブラウザからの要求をじっと待っている
- WebブラウザでURL入力 WebブラウザからWebサーバに、要求が届く
- Webサーバ実行 Webサーバで処理が実行され、できたテキストをWebブラウザに返却
- Webブラウザ表示 届いたテキストの内容をWebブラウザが表示
コード解説
プログラムでは、なにが行われているのでしょうか。
プログラムが起動すると、まっさきに動くのはこの部分。
# アドレス
server_address = ('localhost', 8080)
# Webサーバー起動
with HTTPServer(server_address, CustomHTTPRequestHandler) as server:
server.serve_forever()
- server_address(localhost の 8080) という要求があったら
- CustomHTTPRequestHandlerを呼び出すよ
- それまでずっと要求を待ってるよ(serve_forever)
このあと、ブラウザからアクセスされるまで、じっと待っています。
ブラウザからのアクセスがあったら、CustomHTTPRequestHandler の do_GET が動きます。
重要なのは、コンテンツ(html_context)の部分。
# Get
def do_GET(self):
# レスポンスコード
self.send_response(200)
self.send_header('Content-type', 'text/html; charset=utf-8')
self.end_headers()
# コンテンツ
html_context = '<html lang="ja">' \
' <head>' \
' <meta charset="UTF-8">' \
' <title>はじめてのWebサーバー</title>' \
' </head>' \
' <body>' \
' <p>Hello,World</p>' \
' </body>' \
'</html>'
self.wfile.write(html_context.encode())
ここで設定しているテキストの内容が、HTMLテキストとしてWebブラウザに送られます。
こういうHTMLテキストが送られるわけです。(正確にいうと、送られるのはこれだけではないですが)
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>はじめてのWebサーバ</title>
</head>
<body>
<p>Hello,World</p>
</body>
</html>
このテキストに従い、ブラウザが表示します。
これが、いちばんシンプルなWebサーバプログラムです。
PythonでWebサーバを作る(2)時計アプリ
Hello,Worldだけだと、いつも同じ表示でさびしいですね。
次は、表示が変わるアプリケーションとして、時計アプリを作ってみましょう。
コードを書こう&実行しよう
コードは、Hello,Worldとほとんど変わりません。違うのはコンテンツを作る部分。
実行のしかたも同じです。
from http.server import HTTPServer
from http.server import BaseHTTPRequestHandler
import datetime
# リクエストハンドラ
class CustomHTTPRequestHandler(BaseHTTPRequestHandler):
# Get
def do_GET(self):
# レスポンスコード
self.send_response(200)
self.send_header('Content-type', 'text/html; charset=utf-8')
self.end_headers()
# 現在時刻文字列
dt_now = datetime.datetime.now()
dt_string = dt_now.strftime('%Y/%m/%d %H:%M:%S')
# コンテンツ
html_context = '<html lang="ja">' \
' <head>' \
' <meta charset="UTF-8">' \
' <title>時計</title>' \
' </head>' \
' <body>' \
f' <p>時刻:<strong>{dt_string}</strong></p>' \
' <form id="myform method="get">' \
' <input id="submit" type="submit" value="時刻表示">' \
' </form>' \
' </body>' \
'</html>'
self.wfile.write(html_context.encode())
# アドレス
server_address = ('localhost', 8080)
# Webサーバー起動
with HTTPServer(server_address, CustomHTTPRequestHandler) as server:
server.serve_forever()
コード解説
まず、現在の時刻をテキストとして作り出しています。
# 現在時刻文字列
dt_now = datetime.datetime.now()
dt_string = dt_now.strftime('%Y/%m/%d %H:%M:%S')
この現在時刻テキストを、返却するテキストに埋め込みます。フォーマット済み文字列リテラルの形式で埋め込んでいます。
# コンテンツ
html_context = '<html lang="ja">' \
' <head>' \
' <meta charset="UTF-8">' \
' <title>時計</title>' \
' </head>' \
' <body>' \
f' <p>時刻:<strong>{dt_string}</strong></p>' \
' <form id="myform method="get">' \
' <input id="submit" type="submit" value="時刻表示">' \
' </form>' \
' </body>' \
'</html>'
またここでは、ボタンをひとつ追加しています。このボタンを押すと、ページが submit されます。
# コンテンツ
html_context = '<html lang="ja">' \
' <head>' \
' <meta charset="UTF-8">' \
' <title>時計</title>' \
' </head>' \
' <body>' \
f' <p>時刻:<strong>{dt_string}</strong></p>' \
' <form id="myform method="get">' \
' <input id="submit" type="submit" value="時刻表示">' \
' </form>' \
' </body>' \
'</html>'
submitとは、ページ更新要求です。これが起こると、Webサーバに要求が飛び、かえってきたHTMLテキストでページが更新されます。
Webサーバでは、要求を受け付けると、そのときの現在時刻でテキストを作って返却します。結果として現在時刻で表示が更新されます。
Webブラウザに送られるのは、以下のようなHTMLテキスト。
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>時計</title>
</head>
<body>
<p>時刻:<strong>2023/6/1 12:34:56</strong></p>
<form id="myform method="get">
<input id="submit" type="submit" value="時刻表示">
</form>
</body>
</html>
dt_string が、実際の時刻文字列に置き換えられた状態で、Webブラウザに送られます。
時計アプリケーションの欠点
さてこの時計アプリケーション、重大な欠点があります。
自動的に更新するなら、Webブラウザから、一定間隔で要求を出す必要があります。
しかしこれは、Webサーバ側ではどうにもできません。Webサーバは要求を待っているだけなので。
Webブラウザ側に制御を入れる、JavaScript
時計を自動的に更新するには、Webブラウザ側に仕掛けを組みこむ必要があります。
ここで登場するのが、JavaScriptです。JavaScriptを使うと、Webブラウザ側に仕掛けを入れることができます。
PythonでWebサーバを作る(3)時計アプリ改良版JavaScriptつき
時計が自動的に更新されるように改良します。JavaScriptが登場です。
コードと実行の仕方
Webブラウザ側に、JavaScirptを使って、Webサーバに一定間隔で要求を出す仕掛けを作ります。
とはいっても直すのは、Python側のコンテンツ部分。動かし方も同じです。
# コンテンツ
html_context = '<html lang="ja">' \
' <head>' \
' <meta charset="UTF-8">' \
' <title>時計</title>' \
' </head>' \
' <body>' \
f' <p>時刻:<strong>{dt_string}</strong></p>' \
' <form id="myForm" name="myForm" method="get">' \
' <input id="submitButton" type="submit" value="時刻表示">' \
' </form>' \
' <script>' \
' function submitForm() {' \
' document.myForm.submit();' \
' }' \
' setInterval(submitForm, 1000); ' \
' </script>' \
' </body>' \
'</html>'
PythonのなかにJavaScriptが入っているような、なんだか不思議なコード。
Webブラウザに送られるのは、以下のようなHTMLテキスト。JavaScriptコードがそのまま入ってますね。
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>時計</title>
</head>
<body>
<p>時刻:<strong>2023/6/1 12:34:56</strong></p>
<form id="myForm" name="myForm" method="get">
<input id="submitButton" type="submit" value="時刻表示">
</form>
<script>
function submitForm() {
document.myForm.submit();
}
setInterval(submitForm, 1000);
</script>
</body>
</html>
JavaScript はどう動くのか
このJavaScript部分は、以下のような動きをします。
- Webサーバの中では実行されません
- JavaScript部分も、そのままテキストとしてWebブラウザに送られます。
- Webブラウザに送られてから、WebブラウザのなかでJavaScript部分が実行されます。
JavaScript部分を見てみましょう。
function submitForm() {
document.myForm.submit();
}
setInterval(submitForm, 1000);
やっているのは、以下のこと。
- setIntervalで、Webブラウザに対し、submitFormを1000ミリ秒(=1秒)間隔で呼び出すことを指示する
- Webブラウザは、1秒間隔でsubmitFormを呼び出す
- submitFormは、submitを実行。これによりページが更新される。
この仕掛けで、Webブラウザ側で、1秒ごとにsubmitが動き、時計が更新される、というわけです。
実際のWebアプリはどう作るのか?
ここまで、PythonでWebサーバを実装してみました。ただPythonでなくてもWebアプリは作れます。
Webアプリはどのようなプログラミング言語で作るのか?
「Webアプリを作るプログラミング言語」として、以下をよく見ます。
- HTML
- CSS
- Java
- JavaScript
- Python
- PHP
- Ruby
- Go
ここで、プログラム初心者のかたは、次のような質問をするかもしれません。
- Webアプリを作るには、HTML、PHP、Ruby、Python、Java、JavaScript、どれがおすすめですか?
ここまでWebサーバを作ってきたところで、この質問はちょっと的を得ていない、ことがわかるでしょう。
使うプログラミング言語は、択一ではない
かんたんWebアプリ開発でも、PythonとJavaScriptというふたつの言語が、入り混じって出てきました。
- PHP、Ruby、Python、Javaなどは、Webサーバを作る言語。なのでこれは択一選択となります。
- HTMLやJavaScriptは、Webブラウザを動かす言語です。なのでWebサーバ側と別に使います。
つまり、どれかひとつを選ぶわけではなく、HTMLやJavaScriptは、PHP/Ruby/Python/Javaなどと組み合わせて使うのです。
フロントエンドとバックエンド
「じゃあ、すべての言語を覚えないといけないの?」というと、そうでもありません。
実際の開発では、「Webブラウザ側」と「Webサーバ側」で、たいていチームが分かます。
この区別はよく「フロントエンド」「バックエンド」と言われます。
- フロントエンド : Webブラウザ側。HTML,CSS,JavaScriptを組み合わせて表示処理を開発
- バックエンド : Webサーバ側。PHP,Ruby,Javaなどで裏方処理を開発
フロントエンドエンジニア、バックエンドエンジニア、は、上記のそれぞれの領分を開発する人になります。
いやいや、どうやって分けて開発するの?
フロントエンドとバックエンドに分ける、というけれど、いままでのコードだと、
- PythonとJavaScriptに分けるったって、おなじソースファイルに書いてるよ!
- どうやって分けて開発するの?
Webブラウザ側の開発といっても、そのコードはWebサーバ側に埋め込まないといけないのです。
フロントエンドとバックエンドをいかに分離するか、これがWebアプリケーション開発における大きな課題です。
これを解決するのが、Webアプリケーションフレームワークです。
Webアプリケーションフレームワークとは?
Webアプリケーション開発で、フロントエンドとバックエンドをうまく分離するのが、フレームワーク。
フレームワークはなにをやっているのでしょう?
フロントエンドとバックエンドの分離
時刻アプリケーションを見てみると、フロントエンド側で開発するのは、以下のコンテンツの部分。
# コンテンツ
html_context = '<html lang="ja">' \
' <head>' \
' <meta charset="UTF-8">' \
' <title>時計</title>' \
' </head>' \
' <body>' \
f' <p>時刻:<strong>{dt_string}</strong></p>' \
' <form id="myForm" name="myForm" method="get">' \
' <input id="submitButton" type="submit" value="時刻表示">' \
' </form>' \
' <script>' \
' function submitForm() {' \
' document.myForm.submit();' \
' }' \
' setInterval(submitForm, 1000); ' \
' </script>' \
' </body>' \
'</html>'
バックエンドがそれ以外の部分です。
ただ、フロントエンドとバックエンドが両方絡む部分があります。「時刻を埋め込む部分」です。
f' <p>時刻:<strong>{dt_string}</strong></p>' \
Webアプリフレームワークは、この動的変更部分が分離できるよう、工夫がされています。
PHPの例
例えば、PHPで時計アプリをつくると、このようになります。
<!DOCTYPE html>
<html>
<head>
<title>時計アプリケーション</title>
<style>
body {
text-align: center;
font-size: 48px;
margin-top: 200px;
}
</style>
</head>
<body>
<?php
// 現在の時刻を取得
$currentTime = date('H:i:s');
// 時刻を表示
echo $currentTime;
?>
</body>
</html>
<?php~?> のところで、実際のPHPプログラムが動き、内容を処理結果で置き換えています。
この<?php~?>の部分を、別モジュールの呼び出しに切り替えると、分離ができるわけです、
おもなWebアプリフレームワーク
Webサーバを作るときの、代表的な言語とフレームワークをあげます。
- Java JSP / JSF / Thymeleaf (SpringBoot)
- Python Django / Flask
- PHP Laravel
- Ruby Ruby on Rails
「ブラウザからの要求に応答する」という、基本的な動作は、どの言語/フレームワークでも一緒です。
Webブラウザ用の言語は、JavaScript一択
Webブラウザ用は、JavaScript一択です。ブラウザは、JavaScriptしかサポートしていないので。
ただし、以下のようなトレンドがあります。
- WebAssemblyが使える。WebAssemblyはC++やRustで開発可能
- TypeScriptもブラウザ標準になる可能性あり
まとめ
Webアプリの本質は
- テキストを、作り出して、表示するソフトウェア
これだけです。
これだけなのですが、
- テキストの中に、必要な情報を埋め込む(Webサーバ処理)
- テキストの中に、装飾する指示を入れる(HTML)
- テキストの中に、ブラウザで動かすコードを入れる(JavaScript)
といったことが必要になるため、話がややこしくなっています。
このややこしさを解消するため、様々な言語やWebフレームワークが登場した、のです。
Webアプリの本質を正しく理解しておけば、言語やフレームワークの仕組みもしっかり理解できます。本質を押さえておきましょう。
コメント