3

我使用 CouchDB,我希望我的所有用户都拥有独特的电子邮件。当我尝试复制电子邮件时,我希望数据库返回状态 400(错误请求)。

但是由于没有办法在 CouchDB 中定义约束,我应该自己实现它,我的问题是:

这条规则应该站在我的应用程序的哪一层?

(1)领域对象层
这个层 我还真不知道怎么实现

(2) 交互层
这个约束可以在交互器中实现,因为这里有业务规则所在的地方。但是,如果单个文档有多个规则,则可能会增加不必要的复杂性...

function createUser(userData)  {
  let email = userData.email;
  let exist = await userDB.userExist(email);

  if(exist) {
    // return status 400
  } else {
    // create user
  }    
}

(3) 数据库网关层
约束也可以在数据库网关层实现。通常我们会为每个特定实体设置一个网关。但这是否意味着外部服务适配器包含一些业务逻辑?

class userDB()  {
  constructor(opts) {
    this.db = opts.db.connect();
  }

  async userExist(email) {
    return await this.db.fetchByView('email', email);
  }

  async create(email) {
    let exist = await this.userExist(data.email);
    if(exist) {
      // throw error
    } else {
      // create the user
    }
  }
}
4

2 回答 2

2

Unique email address是一个非常古老的 DDD 主题。它与集合验证有关。最简单的(从我的角度来看也是最好的)是在数据库级别放置一个约束。

据我所知,在 CouchDB 中创建唯一约束的唯一方法是使用该_id字段,以便您可以使用此解决方案。这个想法是将电子邮件放在_id字段中。

让存在 = 等待 this.userExist(data.email);

if(exist) { // 抛出错误 } else { // 创建用户 }

这种方法对于并发更新是不安全的。可以同时创建两个用户。想象一下,对于这两个请求,this.userExist(data.email)都返回 false。

于 2017-12-18T05:02:41.703 回答
1

我不是 CouchDB 专家,但从纯粹的清洁架构的角度来看,确保唯一的电子邮件地址是应该在交互器中实现的业务规则。

使用这种方法,即使您曾经决定用其他一些细节(另一个存储系统)替换细节 CouchDB,您的业务规则也将保持不变。

于 2018-03-04T19:40:01.943 回答