Featured image of post 第8回-短縮URLへアクセス! — URL短縮サポーターを作ってみよう

第8回-短縮URLへアクセス! — URL短縮サポーターを作ってみよう

短縮URLにアクセスされたときの処理を実装します。Mojoliciousの動的ルーティングでURLパスからパラメータを取得する方法を学びましょう。

@nqounetです。

連載「URL短縮サポーターを作ってみよう」の第8回です。

前回の振り返り

第7回では、INSERT文とプレースホルダを使って、短縮URLをデータベースに安全に登録する方法を学びました。

前回学んだ内容を簡単に振り返ります。

  • INSERT文でテーブルにデータを追加できる
  • プレースホルダ(?)を使うことでSQLインジェクション攻撃を防げる
  • $dbh->prepare($sql)でステートメントを準備し、$sth->execute($値1, $値2)で実行する
  • 簡易バリデーション(if (!$url) { ... })で空文字入力を防げる

今回は、登録した短縮URLに実際にアクセスされたときの処理を実装します。

今回のゴール

第8回では、以下を達成することを目標とします。

  • プレースホルダルーティングの仕組みを理解する
  • /:code形式の動的なURLパスからパラメータを取得する
  • 短縮コードをログ出力して動作確認する

/abc123にアクセスしたらどうなる?

タカシさんの疑問

短縮URLの登録ができるようになったタカシさん。次の疑問が湧いてきました。

「登録した短縮コードabc123にアクセスするには、/abc123というURLにアクセスすればいいんだよね?でも、そのルートはどう定義すればいいの?」

良い質問です。これまで学んだルーティングでは、get '/'post '/shorten'のように、固定のパスを指定していました。しかし、短縮コードは登録するたびに変わります。abc123def456xyz789…これらすべてに対して個別にルートを定義するのは現実的ではありません。

ここで登場するのが、プレースホルダルーティングです。

プレースホルダルーティングとは

プレースホルダルーティングは、URLパスの一部を変数として受け取る仕組みです。Mojolicious::Liteでは、パスの中で:名前の形式で指定します。

例えば、/:codeと定義すると、/abc123へのアクセスでも/xyz789へのアクセスでも同じルートで処理できます。そして、実際にアクセスされたパス(abc123xyz789)は、codeという名前のパラメータとして取得できます。

これにより、無限に存在しうる短縮コードに対して、たった1つのルート定義で対応できるのです。

プレースホルダルーティングの実装

コードを書いてみよう

プレースホルダルーティングの基本形を見てみましょう。以下のコードをapp.plに追加します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
#!/usr/bin/env perl
# app.pl(抜粋)
# Perl: 5.20以上(サブルーチンシグネチャ使用)
# 依存: Mojolicious
use Mojolicious::Lite -signatures;

get '/:code' => sub ($c) {
    my $code = $c->param('code');
    $c->app->log->info("アクセスされた短縮コード: $code");
    $c->render(text => "短縮コード: $code");
};

app->start;

コードの各部分を解説します。

プレースホルダの定義

1
get '/:code' => sub ($c) { ... };

この:codeがプレースホルダです。コロン(:)から始まる部分は、URLパスの任意の値にマッチします。

  • /abc123にアクセスすると、codeabc123が入る
  • /xyz789にアクセスすると、codexyz789が入る
  • /helloにアクセスすると、codehelloが入る

パラメータの取得

1
my $code = $c->param('code');

第3回で学んだ$c->param()メソッドは、フォームデータだけでなく、プレースホルダで定義した値も取得できます。プレースホルダ名(code)をキーとして渡すことで、実際にアクセスされたパスの値を取得します。

これは、第3回で予告していた「ルート定義のプレースホルダ」の活用例です。

ログ出力で動作を確認する

開発中は、どのような値が渡されているかを確認したいことがよくあります。Mojoliciousには便利なロギング機能が備わっています。

1
2
3
4
5
#!/usr/bin/env perl
# app.pl(抜粋)
# Perl: 5.20以上(サブルーチンシグネチャ使用)
# 依存: Mojolicious
$c->app->log->info("アクセスされた短縮コード: $code");

このコードは、アクセスされた短縮コードをサーバーのログに出力します。$c->app->logでロガーオブジェクトにアクセスし、infoメソッドでINFOレベルのログを記録します。

ログレベルには以下の種類があります。

  • debug: デバッグ情報(開発時の詳細情報)
  • info: 一般的な情報(処理の進行状況など)
  • warn: 警告(問題の可能性があるが処理は継続)
  • error: エラー(問題が発生したが処理は継続)
  • fatal: 致命的エラー(処理を中断すべき問題)

開発サーバー(morbo)では、これらのログがターミナルに出力されます。

動作確認

morboで起動する

ファイルを保存したら、morboで起動しているサーバーが自動的にリロードされます。もしサーバーを停止していた場合は、再度以下のコマンドを実行してください。

1
morbo app.pl

ブラウザで確認する

いくつかのURLにアクセスして、動作を確認してみましょう。

  1. http://localhost:3000/abc123にアクセスします
  2. 画面に「短縮コード: abc123」と表示されることを確認します
  3. ターミナルのログに「アクセスされた短縮コード: abc123」と出力されていることを確認します

別の短縮コードでも試してみましょう。

  1. http://localhost:3000/test456にアクセスします
  2. 画面に「短縮コード: test456」と表示されます
  3. ログにも「アクセスされた短縮コード: test456」と出力されます

どんな文字列でアクセスしても、同じルートで処理され、その文字列がパラメータとして取得できることがわかります。

ルートの優先順位に注意

プレースホルダルーティングを使う際には、ルートの定義順序に注意が必要です。/:codeは非常に広範囲にマッチするため、他のルートより後に定義することをお勧めします。

1
2
3
4
5
6
# 固定パスを先に定義
get '/' => 'index';
post '/shorten' => sub ($c) { ... };

# プレースホルダルーティングは最後に定義
get '/:code' => sub ($c) { ... };

Mojoliciousは定義された順にルートをマッチングするため、/:codeを最初に定義すると、/shortenへのGETアクセスも/:codeにマッチしてしまう可能性があります。

まとめ

今回学んだこと

第8回では、以下のことを学びました。

  • プレースホルダルーティング(/:code形式)で動的なURLパスを処理できる
  • $c->param('code')でプレースホルダの値を取得できる
  • $c->app->log->info(...)でサーバーログに情報を出力できる
  • プレースホルダルーティングは他のルートより後に定義すべきである

次回予告

次回は「元のURLを探そう — SELECT文でデータ取得」をテーマに、短縮コードに対応する元のURLをデータベースから検索する方法を学びます。いよいよURL短縮サービスの核心部分に入っていきます。お楽しみに。

comments powered by Disqus
Hugo で構築されています。
テーマ StackJimmy によって設計されています。