amon2でTinyURL

参考1参考2

amon2をセットアップして、MyAppを作成した後、下記手順。

sql/sqlite.sql

create table tinyurl (
    key varchar(20) primary key,
    url text
);

$ sqlite3 development.db < sql/sqlite.sql


lib/MyApp/Web/Dispatcher.pm に下記を追加

get '/tinyurl' => sub {  # / にたいする GET リクエストをフックする
    my $c = shift;
    return $c->render('tinyurl.tt'); # tinyurl.tt を描画してかえす
};

post '/create' => sub { # /create にたいする POST リクエストをフックする
    my $c = shift;
    my $src = $c->req->param('url') || return $c->redirect('/');

    my $key = sub {
        # dup check
        {
            my $key = $c->dbh->selectrow_array(q{
                SELECT key FROM tinyurl WHERE url=? LIMIT 1
            }, {}, $src);
            return $key if $key;
        };
        # create new one.
        {
            my @chars = ( 'A'..'Z', 'a'..'z', '0'..'9' );
            my $key;
            for (1..6) {
                $key .= $chars[int rand @chars];
            }
            $c->dbh->do(q{INSERT INTO tinyurl (key,url) VALUES (?, ?)}, {}, $key, $src);
            return $key;
        }
    }->();
    return $c->render('result.tt', {tinyurl => $c->req->base . 'g/' . $key});
};

get '/g/{key}' => sub {
    my ($c, $args) = @_;
    my $key = $args->{key} || die "oops";
    my $url = $c->dbh->selectrow_array(q{
        SELECT url FROM tinyurl WHERE key=? LIMIT 1
    }, {}, $key);
    if ($url) {
        warn $url;
        return $c->redirect($url);
    } else {
        return $c->res_404();
    }
};


tmpl/tinyurl.tt を作成

<!doctype html>
<html>
<head>
    <met charst="utf-8">
    <title>TinyURL</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
    <h1>tinyurl</h1>
    <form method="post" action="/create">
        <input type="text" name="url" />
        <input type="submit" value="tiny!" />
    </form>
</body>
</html>


tmpl/result.tt を作成

<!doctype html>
<html>
<head>
    <met charst="utf-8">
    <title>TinyURL</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
    <h1>tinyurl</h1>
    <div>[% tinyurl %]</div>
    <a href="/">back to top</a>
</body>
</html>


$ plackup して、http://0:5000/tinyurl にアクセスします。