Как в мессенджерах реализовано подключение контактов?
Пишу API для нового мессенджера, остановился на моменте подключение контактов. Не совсем понимаю, как реализовать сами чаты теперь.
Без контактов всё просто: есть таблицы users, chats, participants, messages. И когда пользователь просматривает сам чат, через таблицу participants достаю объект пользователя. И уже отображаю указанные юзером имя, ник и аватар. Теперь встал вопрос, что делать с contacts.
Изложу свои предположения:
Создать таблицу contacts, где сохранять owner_id, и name, surname, phone. Затем когда отдаю на фронт объект user, добавлять в него коллекцию contacts (то есть все записи из таблицы contacts WHERE owner_id={user->id}). И уже на фронте, разработчику нужно будет сравнивать chat.participants с каждой записью из user.contacts и при совпадении свойства phone выводить имя и тд. из соответсвующего объекта из contacts.
Мне такая логика кажется слишком усложнённой. Подскажите более удобный вариант интеграции контактов. Может кто-то знает, как это реализовано в популярных мессенджерах, вроде Telegram, WhatsApp?
Опишите вашу схему базы данных подробнее, указав в особенности, как использованы первичные ключи, и налажена связь между таблицами с использованием внешних ключей.
с каждой записью из user.contacts и при совпадении свойства phone выводить имя и тд. из соответсвующего объекта из contacts.
По этой формулировке прослеживается, что у вас есть некоторые архитектурные проблемы по части использования ключей.
А, теперь вас понял.
Для каждого пользователя-собеседника вы хотите дозапрашивать у бэкенда некоторые дополнительные данные, в частности, список контактов собеседников.
Тут зависит от того, насколько перегружен объектами текущий просматравиемый отчет и насколько востребованными будут дополнительные данные.
Если какая та часть данных отображается возле ника собеседника постоянно, например, основной контактный телефон или основной email, то такие данные, должны запрашиваться вместе со списком собеседников.
А если пользователь, например, наводит мышкой на собеседника и хочет увидеть дополнительные свойства контакта, то в такой момент можно делать еще один запрос на бэкенд (дай мне все номера телефонов, почт вон того чувака с user_id таким-то). Результат этого запроса можно кэшировать на фронтенде, и если повторно запросили эту инфу, то отдавать из кэша.
Если мы не хотим, чтобы при наведении мыши происходили задержки, то мы должны загрузить доп. инфу сразу для всего списка контактов. Фраза "для всего списка контактов" тут тоже может иметь оттенки нюансов. Список контактов всего-всего чата (в котором over 9000 сообщений), или только видимой части отчета в пределах 100... 500 сообщений, а может еще в режиме скользящего окна (+100 сообщений вверх, -100 сообщений вниз).
Все вопросы подгрузки доп. инфы нужно решать отталкиваясь от того, какие ограничения у вас имеются, и что вы хотите избежать в процессе работы приложения.
Ваша логика вполне правильная: отдельно присылать сообщения чата с айдишниками, отдельно справочники айдишников юзеров и их контактных данных. Лучше переложить задачу матчинга участников чата и их профилей на клиента, который сможет хранить эту таблицу контактов у себя в локальной базе (localstorage) и периодически синхронизировать. Само собой, в первый раз синк займёт больше времени.
- Чаще всего популярные мессенджеры сразу создают юзера для каждого человека из контактов. И да, хранят личную таблицу имён контактов для каждого пользователя. Например, так сделано в Skype и Whatsapp. В Телеграме не создают юзера, пока он сам не зарегается, но там и не дают возможности "переименовывать" свои контакты — как пользователь себя назвал, так и будет отображаться.
- Для таких задач используются NoSQL базы, что ускоряет запросы и убирает необходимость кэширования.
- Базы данных шардируются по user_id, чтобы получать все данные юзера максимально быстро, включая его контакты, чаты и тп.