Рефакторинг кода для сервисов и архитектуры на основе контроллеров node.js

У меня мое приложение структурировано, как показано ниже,

Routes -> Controllers -> Services

Таким образом, для /bookings есть BookingController и BookingService

Роль контроллера — принимать запрос и распределять задачи между одной или несколькими службами.

Теперь давайте посмотрим на код ниже.

BookingService.js

const {
  Customer,
  CustomerB2c,
} = require('config');

const models = require('../models');
const NewOrderService = require('./NewOrderService');
const AuthService = require('./AuthService');
const TaxAndDiscountService = require('./TaxAndDiscountCalculationService');
const CartService = require('./CartService');
const RequestService = require('./RequestService');
const LocationService = require('./LocationService');

module.exports = async (users) => {
  const promises = users.map((user) => models.sequelize.transaction(async 
    let userId;
    let cartValue;
    const notes = {};
    const existingUser = await AuthService.isUserExist({ mobile: user.mobile });
    if (!existingUser) {
      const loginData = await models.Login.create({
        mobile: user.mobile,
        email: user.email,
        is_blocked: false,
        username: user.customer_name,
        user_role_id: Customer,
        user_type_id: CustomerB2c,
      }, { transaction: t });
      const userData = await models.UserDetail.create({
        Wallet: {
          coin_balance: 0,
        },
        first_name: user.customer_name,
        login_id: loginData.id,
        city_id: user.city_id,
      }, {
        include: [models.Wallet],
      }, { transaction: t });
      userId = userData.id;
    } else {
      userId = existingUser.user_id;
    }
    const locations = await LocationService.doGetSuggestedLocations({
      currentLat: user.lat,
      currentLng: user.lng,
    });

    const address = await models.UserAddress.create({
      ...user.address,
      user_id: userId,
      location_id: locations[0].id,
    }, { transaction: t });
    const vehicle = await models.UserVehicle.create({
      is_default: true,
      user_id: userId,
      vehicle_id: user.master_vehicle_id,
      registration_number: user.reg_num,
    });
    const { cartId } = CartService.getUserCart({ userId });
    CartService.addItemToCart({
      itemId: user.item_id,
      cartId,
      itemQuantity: 1,
    });
    const cartItems = await NewOrderService.doGetCartItemsByUserId(userId);
    if (user.coupon_code) {
      const userCartValue = await NewOrderService.doApplyCoupon({
        userId,
        zoneId: locations[0].zoneId,
        slotId: user.slot_id,
        cartItems,
        couponCode: user.coupon_code,
      });
      cartValue = userCartValue;
      notes.couponCode = user.coupon_code;
      notes.couponDiscount = cartValue.coupon_discount;
    } else {
      cartValue = TaxAndDiscountService.calculateCartValue(cartItems);
    }
    const item = await models.Item.findOne({
      where: {
        item_id: user.item_id,
      },
      include: {
        model: models.Service,
        attributes: ['id'],
      },
      attributes: ['id'],
    });
    const services = [{
      service_id: item.Service.id,
      slot_id: user.slot_id,
      vehicle_id: vehicle.id,
      booking_date: user.booking_date,
      customer_address_id: address.id,
    }];
    const order = await NewOrderService.doCreateBookingOrder({
      notes,
      userId,
      services,
      cartItems,
      cartValue,
      transaction: t,
    });
    const bookings = await RequestService.doCreateServiceRequest({
      userId,
      transaction: t,
      orderId: order.id,
      requestedServices: services,
    });
    order.bookings = bookings;
    NewOrderService.doSendBookingNotification({
      userId,
      orderId: order.id,
      bookingId: order.bookings[0].id,
    });
    return order;
  }));
  return Promise.all(promises);
};

Код создает users оптом также создает свои wallet, vehicle, address и наконец order.

Здесь много чего происходит.

Я всегда прихожу в такую ​​ситуацию, и я расстраиваюсь и чувствую себя так плохо из-за кода. Понятия не имею, как его реорганизовать.

Но у меня есть некоторые мысли:

Создавайте отдельные функции вроде bulkCreateUserWithWallet, createUserVehicle и createUserAddress и так далее, и вместо этого используйте эти функции.

Но все же эти функции будут использоваться только один раз, они мне больше нигде не нужны, потому что здесь им может потребоваться меньше аргументов, а в некоторых других местах мне нужно вставить больше данных в поле адреса таблицы i.ie.

Кроме того, они должны быть в одной транзакции.

Я также подумал об использовании шаблона репозитория, поэтому между сервисами и моделями у меня будет еще один уровень под названием Repository.

Но я не знаю, как это реализовать, используя sequelize.

Я также знаком с такими шаблонами, как функции высшего порядка и чистые функции. Могу я как-нибудь использовать их здесь?

Наконец просьба, пожалуйста, не закрывайте его! Я готов терпеть отрицательные голоса без проблем.

Я не знаю, где еще задать этот вопрос.

0

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *