Web開発
Select * from Internet.blogposts
Select * from Internet.blogposts (pfrazee.leaflet.pub)
要約
この記事は、Twitter/XのNitterに対する法的措置を例に、かつてオープンだったAPIが閉鎖的なエコシステムへと移行する「壁に囲まれた庭」問題を論じています。著者は、APIが提供する限定的なデータアクセスでは現代のアプリケーション開発に必要な柔軟性や網羅性が得られないと指摘し、 Brewster Kahle氏の「Webを開いたままロックする」という提唱に触れています。そして、atproto(Blueskyの基盤)が、個人データサーバーのネットワークとデータのローカルレプリケーションを通じて、インターネット上の全データを取得・操作できるような仕組み(SELECT * FROM internet)を実現することを目指していると説明しています。
全文翻訳
2007年、Tim Berners Leeはエッセイ「The Giant Global Graph」を書きました。引用:「文書やサイトを超えて、友情、他者との関係性を求める心の叫びがある…そうすれば、他のサイトやプログラムもその情報を使用できる。」XがNitterに停止勧告書を送っていることを考えると、TBLのエッセイを思い出すのは適切でしょう。Nitterは、ユーザーがログインせずにツイートを表示できる、Xのシンプルなフロントエンドでした。ページをプロキシするだけの小さな利用でさえ、法的な措置の脅迫を受けるには十分でした。
2007年のTwitterのAPIは非常にオープンで、何千もの開発者が無料でクライアント、ツール、分析ツールを構築していました。では、何が起こったのでしょうか?なぜそれが引き上げられたのでしょうか?理由は簡単です:ネットワークが勝ったのです。開発者は資産ではなくなり、APIは徐々に閉じられました。レート制限、価格設定、ログイン要件、そして回避策に対する技術的なブロック、そして今では弁護士からの手紙です。Metaも10年前に同じようなやり方をしましたが、かつてFacebookやInstagramのAPIが構築する価値があったことを覚えているのは今では難しいです。
だからこそ、Internet Archiveの創設者であるBrewster Kahleは、10年以上にわたり、私たちがWebを開いたままロックすることを求めてきました。
NitterはXのAPIから始まりました。それが閉じられたとき、公開されているWebページを読み取りました。そして、閉じるものが何も残らなくなった今、ソースコードを削除せよという要求が来ています。公開投稿を表示するプログラムが、コンピューター犯罪法の下で回避装置として扱われています。
私たちは「壁に囲まれた庭」問題を抱えています。それは変わることはなく、私たちの前に残された唯一の選択肢は、ゼロから始めることです。
良いニュースは、atprotoは成長を続け、activitypubは回復力を保っており、私たちのコミュニティはオープンなソーシャルWebの信奉者と構築者で満ちているということです。私はatprotoに取り組んでいるので、次にそれについて話します。
SELECT * FROM internet.blogposts による相互運用
「壁に囲まれた庭」問題は、単純な質問のさらに下流にあります:インターネットからSELECT *を実行するにはどうすればよいでしょうか?
データベースコードを書いたことがないなら、SELECT * FROM users は、データベースがユーザーについて知っているすべてを尋ねる方法です。一度取得すれば、それをフィルタリング、ソートし、持っている他のものと結合できます。
Webは歴史的にそのようには機能しません。Webは、それぞれファイルキャビネットを持ち、それぞれ前に受付係を配置した数十の企業です。彼は、あなたが名前を付けられるファイルだけを、彼が読みたいと思う速さで、そして彼のボスが許可する限り、一度に1つのファイルを読んでくれます。
Nitterは軽量なXリーダーでしたが、Xが依存していたアクセスをオフにするまで正常に機能していました。すべてのAPI(「受付係」)は、まだ覆されていないビジネス上の決定です。
しかし、永続性のなさだけが問題ではありません。永続的で、無料の、寛大なレート制限付きのAPIでさえ十分ではありません。アプリケーションは、APIが提供できるよりもはるかに意味のあるアクセスを必要とします。
あなたは、誰かがすでに答えることを考えた質問にしか尋ねることができません。APIは固定メニューです。それはあなたにgetPosts(user)とgetFollowers(user)を与えます。もしあなたの製品アイデアが「フォロワーがフォローしている人々からの投稿を、引用される頻度でランク付けしたもの」を必要とするなら、そのためのエンドポイントはなく、その会社であなたの製品のために誰も構築していないので、決して存在しないでしょう。
正しい質問でさえ、間違った形で返ってきます。フォロワーは一度に100人ずつ来ます。200万人のフォロワーを持つアカウントは、20,000回の往復です。礼儀正しいレート制限であっても、それは1人のユーザーに関する1つの質問に答えるのに何時間もかかる作業です—つまり、インタラクティブなもの、即時性を感じさせる必要があるものは、始める前に除外されます。
あなたは「キャビネット」をまたいで結合することはできません。興味深い質問は、ほとんどの場合、サービスをまたぎます:この人物の投稿と、あの人物の写真と、3番目のサービスのレビュー。2つの建物の2人の受付係は何も相互参照できませんし、あなたもできません。
あなたは、自分が持っていないデータをインデックス化することはできません。検索、ランキング、レコメンデーション、フィード、モデレーションツール—これらすべては、製品が要求する特定の質問のために配置された、コーパス全体のインデックスの上に構築されています。鍵穴を通してインデックスを構築することはできません。
実際にサービスを構築するには、ビューではなく、データセット全体が必要です。ポーリングするのではなく、変更されるたびに到着するライブデータが必要です。製品の要求に応じてデータをインデックス化する必要があります。それに書き戻す必要があります。そして、単一の会社の四半期ごとの優先順位によって取り消されることのない方法で、それらすべてが保証される必要があります。
デスクトップアプリはファイルシステムを共有することでこれを処理します。インターネットアプリはファイルを使用しません。データベースを使用します。私たちはデータベースを共有する必要があります。
ユーザーとして、私は車に閉じ込められるのと同じくらい、アプリに閉じ込められたくありません。私は実際の自由市場を望んでいます。
では、別のニーズのセットがあります。
アイデンティティの永続性。
私の存在と人間関係は私のアイデンティティを中心に構築されています。それは私がサインアップしたアプリよりも長生きする必要があります。
サービス間の生きた(死んだものではない)データの輸出。
アカウント移行ソリューションとしてツイートのアーカイブをエクスポートすることは無意味です。なぜなら、データは孤立して存在するわけではないからです。
データがもはやオペラブルでなくなった場合(ネットワークの参加者による追加操作が可能でなくなった場合)、それは静的なアーカイブであり、別のアプリケーションには役に立ちません。
ツイートを印刷して見ることができるでしょう、たぶん。
データが元のサービスの外でもオペラブルであり続けることを望むなら、データベースを共有する必要があります。
これらはすべて、atprotoが解決するために設計された問題であり、オープンデータアクセス、アカウント移行、ネットワークアクティビティのライブファイアホースが含まれます。
atprotoはどのようにSELECT * FROM internetを実現するか
データベースをどう共有するか?共有しません。たくさんのデータベースを共有します。アプリケーションがやり取りする個人データサーバー(PDS)のネットワーク全体を作成します。
アプリケーションが個人データサーバーに複雑なSELECT *クエリを送信した場合、どう処理するか?処理しません。ログにデータをレプリケートします。各アプリケーションがデータのコピーを集約してローカルでクエリできるようにします。
アプリケーションがそれらのデータベースに書き込むにはどうするか?この場合、私たちが行います!アプリケーションはPDSに書き込みを送信し、それが他のアプリケーションにレプリケートバックします。
この最後が、atprotoに関する直感の核です:書き込み/取り込みループ。ほぼすべてのatprotoアプリには、次のようなコードがあります。
// write
pds.putRecord(post)
// ingest
onPut(‘app.bsky.feed.post’, evt => {
mydb.put(‘posts’, {...})
})
取り込みがワイヤーを介して戻ってくるのを待つのではなく、「ショートサーキット」を使用して、アプリのデータベースをより迅速に更新できるようにします。PDSからの200 OKは、トランザクションの承認です。
したがって、より効率的なパターンは次のようになります。
// write
pds.putRecord(post)
mydb.put(‘posts’, {...}) // ← optimistic
// ingest
onPut(‘app.bsky.feed.post’, evt => {
mydb.put(‘posts’, {...})
})
機能するか?
はい。ネットワークは存在します。ライブで、公開されており、現在すべてを読み取ることができます—ラップトップから、誰にも許可を求めずに。これは、Bluesky、Tangled、Leaflet、その他多くのものが現在機能しているのと同じ方法です。
いくつかの統計を見てみましょう。執筆時点では、次のようになっています。
atproto上の46.1Mアカウント
24.5Bレコード
そのうち3.15Bは投稿
そのうち17.4Bはいいね
毎秒500〜1000の書き込みイベント
5000以上の個人データサーバー
そして、かなり良いアプリストアサイトを作成するのに十分なアプリ
新しいjetstreamサービスでデータにアクセスするのがこれまで以上に簡単になりました。
import { Jetstream, isCreate } from '@bsky/jetstream';
import { app } from '@bsky/sdk/lexicons';
const jetstream = new Jetstream('https://jetstream.us-east.bsky.network');
const collections = [
app.bsky.graph.follow,
app.bsky.feed.repost,
app.bsky.feed.post
];
for await (const event of jetstream.live({ collections })) {
if (isCreate(event, app.bsky.graph.follow)) {
console.log(`🌱 ${event.did} follows ${event.commit.record.subject}`);
} else if (isCreate(event, app.bsky.feed.repost)) {
console.log(`♻️ ${event.did} reposts ${event.commit.record.subject.uri}`);
} else if (isCreate(event, app.bsky.feed.post) && event.commit.record.reply) {
console.log(`💭 ${event.did} replies ${event.commit.record.reply.parent.uri}`);
}
}
迅速に始めたい場合は、ここで試してみてください。
停止勧告書を受け取るのをやめましょう。代わりにSELECT * FROM internet.blogposts を使用してください。
そして、ああ、もしあなたがl