Zettelkasten Inbox / ブロック詳細
1〜11が「何をするか」なら、ここは「それがどこで動いて、どうやって画面が出るか」。サーバーが返すのは枠だけのHTMLで、中身は1件も入っていない。実行環境が要求ごとに変わるという性質が、他のブロックの弱点の根っこになっている。
抽象度 Lv.4(技術用語+システム上のやりとりまで/製品名・ライブラリ名は書かない)ここまでの11ブロックが「何をするか」だとすれば、このブロックは「それがどこで動いて、どうやって画面が出てくるか」。 利用者がURLを開いてから、操作できる画面が立ち上がるまでの間に起きていることをまとめている。
いちばん大事な性質は1つ。 サーバーが返すのは「枠だけのHTML」で、中身のデータは1件も入っていない。 画面が立ち上がってから、ブラウザが改めて1〜11のAPIを呼んで中身を埋める。 だから受信箱を開いた直後、一瞬「受信箱を整えています」という読み込み中の表示が出る。
置かれている場所も特徴的で、利用者に近い場所に散らばって置かれた実行環境で動く。 この性質が、8番などで使っている「順番待ちの鍵」の効き方に直接効いてくる。
利用者(URLを開く) → 12. 画面の組み立てと配信 → 1. アクセス確認 → 2〜11
/(受信箱)・/map(全体マップ)・/lab/recompose(再構成ラボ)の
3つの画面そのものがこのブロックの出口なぜ中身の入っていないHTMLを返すのか。 受信箱の中身を作るには、Notionの3つのデータベースを全件取る必要がある(2番)。 これをHTMLを組み立てるときにやると、画面が真っ白のまま数秒待たされる。 枠だけ先に返しておけば、「受信箱を整えています」という読み込み中の表示をすぐ出せて、 利用者は少なくとも「動いている」と分かる。
なぜ毎回作り直すのか。受信箱の中身は「いま何が残っているか」そのもの。 前に作ったHTMLを使い回すと、処理済みのノートがもう一度出てくる。 ただし実際には中身が入っていないので、使い回しても実害は無いはず―― それでも指定を付けているのは、あとで中身をHTMLに入れる作りに変えたときに事故らないようにする用心と読める。
なぜナビがページ全体の読み込み直しなのか。 ここには珍しく、コードの中に理由が書き残されている。 「配信環境で、それぞれの画面が確実に初期化されるようにするため」。 部分的な切り替えのほうが速いが、速さより確実さを取ったということ。 受信箱と全体マップは持っている状態がまったく違うので、 切り替え時に前の状態が残ると分かりにくい壊れ方をする。
接続情報を毎回写している理由。この実行環境では、設定値が
プログラムの一般的な置き場所(環境変数)に自動では入らない。
だから要求のたびに、渡された設定を自分で環境変数へ写す。
これをやらないと、Notionを呼ぶ部分が「接続情報がありません」と 503 を返す。
| 工程 | 主体 | やりとりの内容 | 方向 |
|---|---|---|---|
| 12-1 | ブラウザ → 配信の入口 | 画面のURLへの要求 | → |
| 12-2 | 配信の入口(内部) | Notionの接続情報を環境変数へ写す | ↻ |
| 12-3 | 配信の入口(内部) | 画像加工の専用パスかどうかの判定 | ↻ |
| 12-4 | 配信の入口 → 画面の組み立て | 3つの画面のどれかへの振り分け | → |
| 12-5 | 画面の組み立て(内部) | 宛先から題名・説明・OGPを組み立て | ↻ |
| 12-6 | 画面の組み立て → ブラウザ | 枠だけのHTML(中身のデータは空) | ← |
| 12-7 | ブラウザ → 静的ファイル置き場 | 文字・スタイル・画面の部品の要求 | → |
| 12-8 | 静的ファイル置き場 → ブラウザ | 1年間保存してよい印つきの部品 | ← |
| 12-9 | ブラウザ(内部) | 画面の起動と、1〜11のAPIの呼び出し開始 | ↻ |
12-1 利用者がURLを開くと、要求は利用者に近い場所に置かれた実行環境に届く。 1台の大きなサーバーではなく、世界中に散らばった小さな実行の場が、要求ごとに割り当てられる。
技術的には エッジ実行環境(利用者の近くで動く、 起動が速く軽い実行の仕組み)。1つの要求ごとに独立して立ち上がり、終われば片付けられる。 これが8番の「順番待ちの鍵」の効き方を決めている―― 鍵はその実行環境のメモリの中にしか無いので、 別の実行環境に割り当てられた同時操作には効かない。 同じ理由で、2番の30秒の控えや6番の6時間の控えも「運が良ければ効く」程度のものになる。
12-2 まず、この環境に設定されているNotionの接続情報を、 プログラムが読める場所へ写し替える。
技術的には 写すのは4つ:接続用のトークンと、
3つのデータベースの識別子。要求のたびに毎回実行される(1回だけではない)。
この実行環境では設定値が渡され方の都合で環境変数に自動で入らないため、手で橋渡ししている。
写す前に値があるかを確認するので、設定されていない項目は上書きされない。
この4行が無いと、Notionを呼ぶ処理はすべて 503 で止まる。
12-3 画像を小さく作り直すための専用の入口だけ、先に横取りする。
技術的には /_vinext/image というパスへの要求だけを
別扱いにし、決められた幅の一覧の中でのみ画像を変換して返す。
ただしこのアプリは、この仕組みを使っていない。
添付画像の表示も、原典プレビューの代表画像も、素の画像表示で書かれている
(そのことを示す注記がコードに残っている)。
土台の雛形に最初から付いていた機能が、使われないまま残っている形。
12-4 それ以外の要求は、3つの画面のどれか、または12本のAPIのどれかへ振り分けられる。
技術的には 振り分けはフォルダの構成がそのままURLになる方式。
画面は3つ:/(受信箱)、/map(全体マップ)、/lab/recompose(再構成ラボ)。
3つとも「毎回サーバーで作り直す」指定が付いている。
なおAPIのほうは、ここを通ったあと 1番の門に入る。
12-5 画面の題名・説明文・共有したときに出るカードの絵を組み立てる。 このとき、いま自分がどのアドレスで呼ばれたかを見て決める。
技術的には 要求ヘッダの
x-forwarded-host(間に立つ機器が「本来の宛先はここです」と伝えるための項目)と
x-forwarded-proto を読んで、絶対URLの基準を組み立てる。
どちらも無ければ host を使い、それも無ければ手元の開発用アドレスにする。
つまり、置き場所を変えてもOGPのURLが自動で追従する。
題名は「Zettelkasten Inbox」、説明は
「Notionを正本に、Literature NoteをTagからABC Noteへ迷わず知識化する受信箱。」で固定。
全体マップの画面だけは別の題名を持つが、こちらは要求に関係なく固定値。
12-6 枠だけのHTMLが返る。受信箱の一覧も、Tagも、ABC Noteも、まだ1件も入っていない。
技術的には 返るのは、画面の外枠と読み込み中の表示だけを含むHTML。 中身を担当する部分は「ブラウザ側で動く」印が付いていて、 サーバーでは実行されない。だから HTMLの中を覗いても、Notionのデータは1文字も入っていない。 これは検索や共有に対しては不利(外から中身が見えない)だが、 このアプリは個人用で外に見せる必要が無いので問題にならない。
12-7 HTMLを受け取ったブラウザは、続けて文字(フォント)・見た目の指定・ 画面を動かす部品を取りに行く。
技術的には 文字は外部の配信元から読み込まない。 必要な字形だけを取り出したファイルが、このアプリと同じ置き場所から配られる。 外部の配信元に取りに行くと、電波の悪い所で文字だけ遅れて表示される(一瞬別の字体で見える)ので、 それを避けている。画面の部品は用途ごとに分かれていて、 受信箱の部品・全体マップの部品・再構成ラボの部品は別々。 受信箱しか開かない人は、全体マップの部品を受け取らずに済む。
12-8 これらの部品には「1年間そのまま保存してよい」という印が付いている。 2回目からは通信すら起きない。
技術的には Cache-Control: public, max-age=31536000, immutable。
31,536,000秒=365日。immutable は「中身は絶対に変わらないので、
確認の問い合わせすら不要」という意味。
こんな強い指定ができるのは、ファイル名に中身から計算した文字列が入っているから――
中身が変われば名前も変わるので、古いものを使い回す事故が起きない。
HTMLのほうには一切この印を付けない。
部品は永久保存、画面は毎回取り直し、という使い分けになっている。
12-9 部品が揃うと画面が動き出し、そこで初めて1〜11のAPIが呼ばれる。 ここから先が、これまでの11ブロックの話になる。
技術的には 受信箱なら 2番(一覧の取得)、
全体マップなら 10番、再構成ラボなら 11番が最初に呼ばれる。
画面上部のナビ(受信箱/全体マップ)は、部分的な切り替えではなく
<a href> によるページ全体の読み込み直しで移動する。
つまり切り替えるたびに 12-1 からやり直す。
コードにはその理由が「配信環境で各画面が確実に初期化されるようにするため」と
書き残されている。速さより確実さを取った判断が、理由付きで残されている珍しい箇所。
← 図は横にスクロールできます
503 +「Notion接続情報が設定されていません。」となり、
「Notionを読み込めませんでした」という画面に落ちる。
設定漏れは画面が出た後にしか分からない。※ 2026年8月14〜15日時点の zettelkasten-inbox のプログラムを読んで作成しました。過去の設計資料は参照していません。
※ 番号は全体図・この解説・シーケンス図で共通です。工程番号は「ブロック番号-連番」で書いています。