Transport-agnostic API
Принцип: код, который вызывает API, ничего не знает о транспорте. WebSocket, HTTP, WebRTC, MessagePort — взаимозаменяемы без правок UI или бизнес-логики.
Проблема mainstream-подхода
- REST: код вызывает
fetch('/api/users/123')→ намертво вшит HTTP, путь, метод. - GraphQL: вызов через
client.query(...)— привязан к транспорту GraphQL. - gRPC: protobuf-схема и stub — нельзя просто заменить транспорт.
Поменять REST → WebSocket → пришлось бы переписать всё.
Идея transport-agnostic
const result = await api.module.method(args);
Это вызов:
- может пойти по WebSocket к серверу;
- может пойти через MessagePort к Service Worker;
- может пойти через WebRTC к peer'у;
- может быть локальной заглушкой в unit-тесте.
UI этого не знает. Transport — деталь конфигурации.
Реализация в Metacom
- Introspection — клиент спрашивает у сервера: «какие у тебя интерфейсы и методы?»
- Proxy-объект — на основе ответа строится клиентский SDK:
api.users.get(123). - Транспортный адаптер — реализует
send(packet) / on(packet). Меняется в одной точке.
Стратегия как паттерн
«Эти интерфейсы можно подменять, и таким образом мы можем реализовывать разные стратегии. Стратегии транспортов, стратегии сториджа, стратегии запуска бизнес-логики.»
Это GoF Strategy на уровне сетевой архитектуры.
Изоморфность
Тот же API-объект работает:
- В браузерной вкладке (WebSocket к серверу).
- В Service Worker (WebSocket к серверу, прокси к вкладкам через MessagePort).
- На сервере (локальный вызов в том же процессе).
- В тесте (mock-транспорт).
Бизнес-логика пишется один раз, исполняется в любой среде.
Чем это лучше REST/GraphQL
| REST | GraphQL | Transport-agnostic (Metacom) | |
|---|---|---|---|
| Сигнатура вызова в UI | fetch(url) | client.query(gql) | api.x.y(args) |
| Замена транспорта | переписать всё | переписать клиент | поменять адаптер |
| Локальный вызов | имитировать сервер | имитировать резолверы | подменить адаптер |
| Тестируемость | моки HTTP | моки клиента | прозрачно |
Where it leads
Это фундамент для:
- Local-first архитектуры (хочешь — иди в сервер, хочешь — в локальный CRDT).
- P2P (WebRTC заменяет WebSocket — UI не заметил).
- Изоморфизма (тот же код на клиенте и сервере).
🎓 Источники
- 🎓 Metacom — сеть прозрачна для API · 2025-12-11
- 🎓 Local-first — Как изменится фронтенд и бекенд · 2025-12-26
- 🎓 JSTP — JavaScript Transfer Protocol · Алексей Орленко · 2019-12-28
- Цитата: «TCP и WebSockets для общения приложений с сервером, Unix Domain Sockets для IPC. И при этом всё происходит с одинаковым интерфейсом, унифицированным и полностью абстрагирует от вас реальный транспорт.»