В atproto нет объектов-экземпляров

22.06.2026 · 5 мин

Каждый раз, когда на Hacker News всплывает пост про ATProto, кто-то обязательно спрашивает: «А где все инстансы Bluesky?». И каждый раз кто-то объясняет: их нет. Эта фраза звучит странно, если ты привык к миру Mastodon или обычному объектно-ориентированному программированию.

Суть проблемы — категориальная ошибка. Мы пытаемся уложить новую распределённую систему в старую ментальную модель и удивляемся, почему не складывается.

Давайте разберёмся, что именно означает «нет инстансов» и почему это не недостаток, а осознанное архитектурное решение.

Хостинг и агрегация — это разные вещи

Вспомним эпоху RSS и Google Reader. Это был золотой век личных блогов:

Блог Алисы   Блог Кота    Блог Боба     
    │             │            │        
    └─────────────┼────────────┘        
                  ▼                     
         ┌─────────────────┐            
         │  Google Reader  │            
         │     Feedly      │            
         └─────────────────┘            
Посты живут на своих серверах, а агрегатор только собирает ленты

Посты публикуются на своём собственном сервере (хостинг), а приложения типа Google Reader или Feedly просто собирают ленту из всех подписок (агрегация). Ваши записи не «живут» в Feedly — приложение лишь проецирует данные из блогосферы.

Это разделение критически важно понять: хостинг ≠ агрегация.

Эволюция: Facebook и другие силосы

┌──────────────────────────────────┐
│     Facebook / Twitter / etc     │
│                                  │
│  [Запись] [Запись] [Запись]      │
│        ▲                         │
│        └── Единственное место    │
└──────────────────────────────────┘
Платформа объединяет хранение и чтение данных в одном месте

Компания берёт всю эту красоту, оборачивает в коробку ради рекламы и оставляет только одно приложение (альтернативные клиенты живут недолго). Твои данные существуют только внутри платформы.

ATProto делает шаг назад к модели RSS — но с современным уровнем сложности.

Что такое «нет инстансов» на практике?

В традиционной системе у тебя есть объект:

// Привычный мир OOP/ORM
const user = await User.findById(123);
user.name = "Новое имя";
await user.save();

Здесь user — это объект-экземпляр с идентичностью во времени.

В ATProto всё иначе. Данные адресуются через записи (records) по URI:

at://did:plc:abc123/app.bsky.feed.post/xyz789
├── Протокол (at)
├── Идентификатор аккаунта (did:plc:abc123)
├── Коллекция записей (app.bsky.feed.post)
└── Уникальный ключ внутри коллекции (xyz789)
АДРЕС ЗАПИСИ В ATPROTO
───────────────────────
at://did:plc:megatrack/app.bsky.feed.post/k3l44j8q
  
  at://              ← Протокол  
  did:plc:mega...    ← Кто создал (Decentralized ID)  
  app.bsky...        ← Тип данных  
  k3l44j8q           ← Конкретный экземпляр записи  
Структура URI записи в ATProto

Что тут принципиально важно?

Запись immutable — она либо есть, либо её нет. Если ты хочешь её изменить, ты создаёшь новую версию со своей историей изменений (com.atproto.repo.listRecords).

Не существует «живого объекта», который можно обновить in-place. Есть только адрес данных.

Репозиторий как источник данных

Каждый пользователь владеет репозиторием — хранилищем всех своих записей:

РЕПОЗИТОРИЙ ПОЛЬЗОВАТЕЛЯ DID:PLCLIVEKITTY 
═════════════════════════════════════════

Репозиторий ──▶ Коллекции записей
  
  ┌─────────────────────────────────────┐ 
  │ did:plc:livekitty                   │ 
  ├─────────────────────────────────────┤ 
  │ app.bsky.feed.post/                 │ 
  │   ├── k3l44j8q                      │ 
  │   ├── b7qp9mnx                      │ 
  │   └── r1z8v2kl                      │ 
  ├─────────────────────────────────────┤ 
  │ app.bsky.actor.profile/             │ 
  │   └── self                          │ 
  └─────────────────────────────────────┘ 

Адрес профиля:
at://did:plc:livekitty/app.bsky.actor.profile/self   
Репозиторий содержит записи всех типов под одним идентификатором

Ты можешь запросить любую запись напрямую по URI без привязки к конкретному серверу или «инстансу». Репозиторий самодостаточен — он знает всё о своих данных.

Почему это лучше для распределённых систем?

Традиционные инстансы Mastodon требуют сложной синхронизации между серверами при federation:

В ATProto вопрос «где?» решается через DID (did:) — децентрализованный идентификатор. Аккаунт не привязан к домену сервера!

## Mastodon:
// mastodon.social/users/alice <- зависит от сервера

## Atproto:
// did:plc:megatrack          <- независимый идентификатор через реестр PLC!

При смене хостинга DID остаётся неизменным, а данные мигрируют между репозиториями прозрачно.

Результат: federation становится проще математически — ты всегда знаешь «чей этот контент» по URI без дополнительного lookup’а.

Выводы для практики

Эта модель странная для тех, кто вырос на ORM’ах и монолитных API-шках. Но именно она делает возможной настоящую federated соцсеть без координационного хаоса между серверами.

Знание того, что «инстансов нет», экономит час спора на Hacker News.

Ссылки

Дмитрий Полухин — продуктовый дизайнер. Пишу про разработку, AI и дизайн интерфейсов. Обо мне, контакты и профили.