この記事は Flutter Advent Calendar 2025 16日目の記事です。
(私用が忙しすぎて1週間遅刻しましたごめんなさい)
はじめに
初めまして。最近よくFlutterいじいじしているlessと申します。
今回は、技術書典19出展にあたり2日で開発した同人誌DLシステムのお話をしたいと思います。
対象読者
- 同人誌即売会に出展するまで時間がないけどダウンロードシステムを爆速で作りたい人(サーバー側のコードはありません)
- Flutter/Dartに興味がある人
注意事項
- 素人が書いたものなので不備などがある場合があります。真似をされる際は自己責任でお願いします。
- 感想・ご指摘などがありましたらコメント欄にお願いします。大変参考になります🙇
概要
技術書典19出展にあたり自前でキャッシュレス決済に対応したのでその場合に渡す電子版を用意するために2日で開発しました。
Flutter製の自作POS「taruPOS」からサーバーに購入品リストを送信すると、DLサーバーの中で閲覧用キーの発行処理がされ、その情報を元にPOS側でQRコードを印字するものです。1つの閲覧用キーには複数のDLキーを紐付けられるようになっています。
Cloudflare Tunnel経由で公開するとポートを解放しなくて良いのとオリジンを隠蔽できるのでセキュリティ的にも安心度が上がります。
構成
システムの構成は以下のような感じです。
フロントエンドのFlutterアプリはCloudflare Pagesでデプロイし、バックエンドのDart ShelfサーバーはConoHa VPS上のDockerで動かしたものをCloudflare Tunnel経由で公開しています。
完成したもの
ダウンロードを押すと、データベース上の残りダウンロード回数を減算した上で、サーバー上のPDFデータを返す仕組みです。
レシートはFlutterのpdfパッケージで作っています。レシートの一部分のコードを以下に載せます。
pw.SizedBox(height: 30),
pw.Center(
child: pw.Container(
width: 150,
child: pw.Center(
child: pw.Column(
children: [
pw.Text(
'電子書籍DL',
style: pw.TextStyle(
fontSize: 30,
font: font,
color: PdfColors.black,
),
),
pw.SizedBox(height: 20),
pw.BarcodeWidget(
color: PdfColors.black,
barcode: pw.Barcode.qrCode(),
data:
(ダウンロードURL),
width: 100,
height: 100,
),
pw.SizedBox(height: 20),
pw.Text(
'注意事項:本サービスは試験提供のため、ダウンロードができなかったり、予告なくサービスの提供を中止したりする場合がありますので、予めご了承ください。',
style: pw.TextStyle(font: font),
),
],
),
),
),
),
pw.SizedBox(height: 30),
メリット
- フルDartなのでPOS側と同じ言語でかけるのでとても楽
- 自作POSで会計処理をすれば勝手に電子版の発行処理も行われるので手間がなく楽
- 別にダウンロードカードを作る必要がない
- キーごとのダウンロード制限ができるのでタダ乗りのリスクが少ない
デメリット
- イベント会場の電波が悪いと発行に時間がかかりタイムアウトしてしまうことがよくあった
- 通信方法の確保はちゃんとやることをお勧めします。技術書典の会場ではR社とK社の回線を利用しましたがどちらも遅かった印象...
- Dart Shelf自体の情報が少なくて困る
- もっとみんな使いましょう!!
改善案
- 通信環境をより良いものにする
- 送受信するデータ量を削減する
最後に
初めてこういう記事書いたので読みにくかったりするかもしれません...ごめんなさい...
あとコードを載せようと思いましたが到底インターネットの海に放流できるものではなかったのでサーバーサイドのコードはありません...ごめんなさい...


