Как эффективно использовать 'сервисы' для обращения к БД?

У меня сейчас, слишком много сервисов получаются (под сервисами я имею в виду файлы в которых функции обращаются к БД).

К примеру,

Для того чтобы проверить существет аккаунт с таким email приходиться делать одну функцию
export const findUserByEmail = async (
  email: string
): Promise<boolean> => {
  try {
    const users = await db
      .query('SELECT email FROM accounts WHERE email = $1', [email])

    return users.rows.length !== 0
  } catch (error) {
    console.error(error)
    throw error
  }
}


И их очень много
createUser
findUserByEmail
getUserByEmail
createUserToken
deletePreviousUserTokens
getRefreshToken


Их можно как то оптимизировать:
1. Нормально ли создавать столько функции, каждый под свои нужды ? (Что-то мне кажется что я не так их использую, а по другому как понятия не имею)
2. В каждом из функции все повторяется кроме самого запроса, (и везде try-catch еще), можно как то это оптимизировать ?
3. Подскажите, как вы делайте что-то подобное, чтобы пример увидеть, желательно разные подходы.
  • Вопрос задан
  • 459 просмотров
Пригласить эксперта
Ответы на вопрос 3
mayton2019
@mayton2019
Bigdata Engineer
По поводу смыслов. Обычно с БД работают сущностями (entities). Я не специалист в Node и я не знаю
как у вас принято. Кажется в новых ecma-спецификациях уже ввели понятие класса.

В данном коде идет проверка на то что email существует. Но полезный эффект - слабый.
Я-бы сразу возвращал сущность пользователя. Чтоб не бегать потом в базу еще
раз когда надо поискать имя или дату регистрации. Ну идея такая что
если вы уж пошли в базу (это сетевой round-trip) то постарайтесь
за этот трип собрать максимум информации.

Вот это более рационально
export const findUserEntityByEmail = async (
  email: string
): Promise<User> => {
  try {
    const users = await db
      .query('SELECT * FROM accounts WHERE email = $1', [email])


Тоже самое относится к выборкам множества строк по множеству ключей.
Лучше сделать 1 callback который вернет коллекцию чем для коллекции
ключей дергать один несчастный метод который по штучке что-то достает.

Еще важне - join. Если соединяете сущности - то соединяйте сразу в БД
без попыток соединять в приложении. Это кстати еще бонус к компетенции
в части ACID.

Тоесть идеальный вариант работы с БД - запросить пакетом всю информацию
что может потербоваться на ближайшие несколько секунд. Это рациональнее
чем потом что-то подтягивать.
Ответ написан
@historydev
Валера, настало твоё время
Для того чтобы проверить существет аккаунт с таким email приходиться делать одну функцию


Используй самый простой паттерн - facade.

Создай класс под работу с базой, создавай методы, а не функции и обращайся к ним, а ещё лучше создавай по классу-фасаду на сущность: User, Chat, News и т.д.

2. В каждом из функции все повторяется кроме самого запроса, (и везде try-catch еще), можно как то это оптимизировать ?


Оберни в метод, принимай строку запроса в параметрах.
Ответ написан
MDiMaI666
@MDiMaI666
Талантливый программист
Как раз нормально так делать! Если их слишком много станет они сами сложатся как паззл.
Можно загнать в объект но это просто сахар. Функциональный стиль тоже хорошо.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы