alex4answ
@alex4answ

Подход «Сервис — Репозиторий» в express?

Добрый вечер, использую подход с слоями - Сервис, Репозиторий (не знаю как правильно называется такая организация)

Суть в том, чтобы обработчик маршрута не был большой простыней с обращениями к бд и тп, а был простой и использовал API сервисов/репозиториев:
Router

const router = express.Router();

router.get('/', async (req, res) => {
  const posts = await PostService.getAll(req.query.page);
  res.json({
    count: posts.count,
    results: posts.rows,
  });
});

router.post('/', async (req, res) => {
  const post = await PostService.create(req.body);
  res.json(post);
});
// и тд

PostService

Очень примерно так, Сервис работает с репозиторием, в случае если тот выбросил исключение - откатывает транзакцию.

const PostRepository = require('./PostRepository');

class PostService {
  async static getAll(page) {
    const limit  = 15;
    const offset = page > 0? +page : 0;
    return await PostRepository.getAll(limit, offset);
  }

  async static create(post) {
    const transaction = db.beginTransaction();
    try {
      const newPost = await PostRepository.create(post);
       // какие-то еще действия с newPost
       transaction.commit();
    } catch(err) {
      transaction.rollBack();
      return false;
    }
    return newPost;
  }
}

module.exports = PostService;

PostRepository

Очень примерно, это слой для работы с бд, в случае ошибки выбрасывает исключение.
const Post = require('./PostModel');

class PostRepository {
  static getAll(limit, offset) {
    return Post.findAndCountAll({ limit, offset });
  }

  static create(body) {
    let result = Post.create({ title: body.title, ...});
    if(!result) {
      throw new Error('ошибка создания записи');
    } else {
      return result;
    }
  }
}

module.exports = PostRepository;


Роутер вызывает сервис, тот запускает транзакцию, и работает с репозиторием, если репозиторий выбросил исключение, сервис откатывает транзакцию, если нет - успешно завершает ее, возвращая данные в роутер.

Вопросы:
1. Не избыточен ли такой подход ? (на express проектах не видел такого, обычно все либо в роутере, либо максимум сервис создают)

Я привык инкапсулировать методы в класс, например PostService, но если честно в js я не очень понимаю зачем я это делаю (ведь я не использую this, не создаю объект, все методы статические), вполне можно обойтись module.exports, тут скорее просто привычка и "так надо".

2. Избыточна ли моя инкапсуляция статических методов в класс ?
  • Вопрос задан
  • 118 просмотров
Пригласить эксперта
Ответы на вопрос 1
@Nc_Soft
Ваш Post.create({ title: body.title, ...}) итак кинет ексепшен (я так понимаю используется sequelize), проверка if(!result) мне кажется избыточной.
Я тоже агрегирую статичные функции в класс, так не надо писать кучу module.exports
Транзакции удобнее делать колбеком, так не надо писать rollback и коммит
С учетом всего вышесказанного получается PostRepository не нужен, с этим справляется модель.
Ответ написан
Ваш ответ на вопрос

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

Похожие вопросы