Hapi 框架中 DAO 及 Repository 的最佳实践

现代 web 开发中,采用 MVC 模式的应用程序使用 DAO (Data Access Object) 和 Repository (数据仓库) 是很常见的,这个概念也适用于使用 Hapi 框架开发的程序。本文将讨论如何在 Hapi 框架中使用 DAO 和 Repository,以获得最佳实践。

DAO 的定义及作用

DAO 是负责与数据库进行交互的对象,它们通过 CRUD (Create, Retrieve, Update, Delete) 操作来完成这个任务。通过 DAO 构建,可以使应用程序的代码更加清晰,并且可以将数据访问相关的逻辑从控制器中剥离出来,更好地实现职责分离。

在 Hapi 框架中,DAO 可以使用数据库插件(如 hapi-sequelize 或 hapi-mongodb)中提供的模块来进行实现。下面是一个使用 hapi-sequelize 实现的例子:

const { DataTypes } = require('sequelize');
const db = require('./db');

const User = db.define('user', {
  id: {
    type: DataTypes.INTEGER,
    primaryKey: true,
    autoIncrement: true
  },
  name: {
    type: DataTypes.STRING,
    allowNull: false
  }
});

module.exports = User;

Repository 的定义及作用

Repository 是一个抽象层,提供了简单的 API 来访问 DAO 对象,并与其进行交互。这个额外的层次使代码更易于维护和测试,使我们能够更容易地实现单元测试、mock 和 stub 等。

在 Hapi 框架中,使用 Repository 可以通过创建一个简单的类来实现。下面是一个 example 的实现:

const User = require('./models/user');

class UserRepository {
  async getAllUsers() {
    return await User.findAll();
  }

  async getUserById(id) {
    return await User.findByPk(id);
  }

  async createUser(name) {
    return await User.create({
      name
    });
  }

  async updateUser(id, name) {
    const userToUpdate = await User.findByPk(id);
    userToUpdate.name = name;
    return await userToUpdate.save();
  }

  async deleteUser(id) {
    const userToDelete = await User.findByPk(id);
    return await userToDelete.destroy();
  }
}

module.exports = UserRepository;

如何使用 DAO 和 Repository

在 Hapi 框架中使用 DAO 和 Repository 的一种最佳实践,是在路由处理程序中使用它们。下面是一个使用上述 DAO 和 Repository 的范例:

const Joi = require('@hapi/joi');
const UserRepository = require('./repositories/userRepository');

module.exports = [
  {
    method: 'GET',
    path: '/users',
    handler: async (request, h) => {
      const userRepository = new UserRepository();
      return await userRepository.getAllUsers();
    }
  },
  {
    method: 'GET',
    path: '/users/{id}',
    options: {
      validate: {
        params: Joi.object({
          id: Joi.number().required()
        })
      }
    },
    handler: async (request, h) => {
      const userRepository = new UserRepository();
      return await userRepository.getUserById(request.params.id);
    }
  },
  {
    method: 'POST',
    path: '/users',
    options: {
      validate: {
        payload: Joi.object({
          name: Joi.string().required()
        })
      }
    },
    handler: async (request, h) => {
      const userRepository = new UserRepository();
      return await userRepository.createUser(request.payload.name);
    }
  },
  {
    method: 'PUT',
    path: '/users/{id}',
    options: {
      validate: {
        params: Joi.object({
          id: Joi.number().required()
        }),
        payload: Joi.object({
          name: Joi.string().required()
        })
      }
    },
    handler: async (request, h) => {
      const userRepository = new UserRepository();
      return await userRepository.updateUser(request.params.id, request.payload.name);
    }
  },
  {
    method: 'DELETE',
    path: '/users/{id}',
    options: {
      validate: {
        params: Joi.object({
          id: Joi.number().required()
        })
      }
    },
    handler: async (request, h) => {
      const userRepository = new UserRepository();
      return await userRepository.deleteUser(request.params.id);
    }
  }
];

总结

通过以上方法,使用 DAO 和 Repository,可以更容易地在 Hapi 框架中实现数据访问和查询逻辑。这种模式使代码更加模块化和可重用,同时使我们更容易进行单元测试和模拟操作。在设计 Hapi 应用程序时,应该考虑使用这种模式,以获得最佳实践。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65b8704badd4f0e0ff0fdbe1