繁体   English   中英

Node.js的域驱动设计

[英]Domain Driven Design for Node.js

我目前正在构建基于Node.js微服务的应用程序,我想利用Domain Driven Design作为构建单个服务的指南 我对此有几个问题如下:

  1. 据我所知,域层通常应包含存储库接口,然后应在基础结构层中创建这些接口的特定实现。 这会从您的域层中抽象出底层存储/技术问题。 在我的项目的情况下,看到的JavaScript 本身并不支持之类的接口,一个人如何会去实现类似的效果?
  2. 特别是一项服务将通过OAuth处理身份验证。 通常会将OAuth相关逻辑归类为应用程序服务吗? 或者它会属于基础设施层? 我的理解是它不是与基础设施相关的,也不是与核心域相关,但仍然需要作为向客户提供应用程序的一部分。 因此,我现在把它放在应用程序层中。
  3. 从第2点开始,OAuth相关的实体/存储库(即令牌/客户端)最好放在哪里? 我很想将它们与我的其他实体/存储库一起保留在域层中,即使它们在技术上不是业务问题。

添加到上面的一些注意事项:

  1. 并不热衷于使用TypeScript(如此处所示 )。
  2. 我完全清楚有些人可能认为JavaScript不适合DDD类型的方法。 我熟悉一些陷阱,再一次,我使用DDD作为指导。

在一个侧面说明,我想出了下面的项目结构,这是深受启发在Laravel基于DDD项目的很好的例子:

app/
----app.js
----package.json
----lib/
--------app/
------------service/
----------------oauth.js
----------------todo.js
--------domain/
------------list/
----------------model.js
----------------repository.js
----------------service.js
------------task/
----------------model.js
----------------repository.js
----------------service.php
--------http/
------------controller/
----------------list.js
----------------task.js
------------middleware/
----------------auth.js
----------------error.js
--------infrastructure/
------------db.js
------------logger.js
------------email.js

我很想听听您对此布局的任何想法。 我完全清楚项目结构的主题是基于意见的,但我总是热衷于听取别人的意见。

你考虑过wolkenkit吗?

它是Node.js和JavaScript的CQRS和事件采购框架,与域驱动设计(DDD)相得益彰。 它可能会让您很好地了解如何构造代码,以及运行时执行操作而无需重新发明轮子。

我知道背后的人,他们投入了3到3年的思想,血液和汗水。

域驱动设计指导系统分解为一组有界上下文/服务/微服务。 但是,您设计每项服务的方式是个性化的,取决于服务的业务领域。 例如,您的企业的核心域服务和支持域服务应以不同方式构建。

即使这个问题很老,我认为在你的第一次审讯中增加一个精确度会很有用:

据我所知,域层通常应包含存储库接口,然后应在基础结构层中创建这些接口的特定实现。 这会从您的域层中抽象出底层存储/技术问题。 在我的项目环境中,看到JavaScript本身不支持接口这样的东西,如何实现类似的效果呢?

JavaScript不提供接口。 而不是模仿OOP概念,为什么不看看更多功能的概念呢? 高阶函数非常适合javascript,您可以使用它们“声明”依赖项并在运行时注入它们:

const { FooData } = require('./data');

const getFooOfId = (getFooOfIdImpl = async (fooId) => { throw new Error(`Can't retrieved foo of id ${fooId} : missing implementation`) }) => async fooId => {
  try {
    const fooData = await getFooOfIdImpl(fooId);
    return FooData(fooData);
  } catch (err) {
    throw new Error(`Unable to retrieve Foo with id ${fooId}`);
  }
}

/*
This function is used to build a concrete implementation, for example with an in-memory database :
const inMemoryFooDatabase = {
  foo17: {
    id: 'foo17',
    foo: 'a foo value',
    bar: 'a bar value',
    foobaz: 1234,
  },
};
const getFooOfIdFromInMemoryDatabase = getFooOfId(fooId => inMemoryFooDatabase[fooId])
*/

module.exports = {
  getFooOdId,
}

没有什么能阻止你完全绕过这个功能,因为javascript中没有强大的类型检查,但它充当了你的域“接口”需求的声明。

如果您想了解更多相关信息,可以阅读我关于此主题的文章: JavaScript开发人员的领域驱动设计

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM