【Webアプリとは?】実は単純、Pythonで簡単Webアプリを作ってみよう

what-is-webapp

Webアプリケーション。なんだかものすごく複雑そうなイメージがありますが、

Webアプリなんて、その本質は、実に単純なものです。PythonでかんたんWebアプリを作って、本質を学びましょう。

目次

Webアプリとはなにか?

Webアプリとはなにか?その本質はズバリ、

Webアプリとは

テキストを、作り出して、表示する、ソフトウェア

これだけです。

Webアプリには様々な技術がありますが、そのすべては、この単純なやりとりを補完しているだけです。

WebブラウザとWebサーバ

Webアプリに登場するのは、WebブラウザとWebサーバ、このふたつ。やっていることは、

Webアプリの登場人物
  • Webブラウザ テキストを表示する
  • Webサーバ ブラウザが表示するためのテキストを作る

本質を言えば、ただこれだけ。

Webブラウザ:テキストを表示するソフトウェア

Webブラウザ=ふだん使っている ChromeEdge のこと。

ブラウザはテキストを表示します。ただし、テキストに装飾の指定があれば装飾してくれます。「文字を太くして」「赤くして」「真ん中にして」という指定があれば、それに従った表示にします。

このような「文字を太くして」「赤くして」「真ん中にして」といった装飾指定のルールを取り決めているのが、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アプリを作るプログラミング言語」として、以下をよく見ます。

Webサーバを作れる主なプログラミング言語
  • HTML
  • CSS
  • Java
  • JavaScript
  • Python
  • PHP
  • Ruby
  • Go

ここで、プログラム初心者のかたは、次のような質問をするかもしれません。

Webアプリについての疑問
  • Webアプリを作るには、HTMLPHP、RubyPythonJavaJavaScript、どれがおすすめですか?

ここまで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サーバを作るときの、代表的な言語とフレームワークをあげます。

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アプリの本質を正しく理解しておけば、言語やフレームワークの仕組みもしっかり理解できます。本質を押さえておきましょう。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

CAPTCHA


目次