CQRS 和 WebAPI 设计

CQRS and WebAPI Design

我最近一直在研究 CQRS 和 Web API。我理解读写之间的分离,即查询和命令。我的问题是,我的 Web Api 操作,例如 [HttpGet] 是否应该期望一个查询参数封装属性,如(SortParam、Page、PageSize 等...)或 should/could 我仍然是否单独公开了这些参数,然后创建一个 Query 对象并将其传递给处理程序?所以基本上我的动作应该是什么样子:

public IHttpActionResult Get(Query query)
{
    try
    {
        var result = _queryDispatcher.Dispatch<Query, QueryResult>(query);
        return Ok(result);
    }
    catch (Exception)
    {
        return InternalServerError();
    }
}

或者看起来像这样可以吗:

public IHttpActionResult Get(string sortBy = "id", int page = 1, int pageSize = maxPageSize)
{
    try
    {
        var query = new Query { SortParam = sortby, Page = page, PageSize = pageSize };
        var result = _queryDispatcher.Dispatch<Query, QueryResult>(query);
        return Ok(result);
    }
    catch (Exception)
    {
        return InternalServerError();
    }
}

见仁见智。也就是说,我相信

完全没问题

keep these parameters exposed individually and then create a Query object and pass it along the handler.

框架允许两者兼顾。对于第一个,使用 [FromUri] 参数属性从查询字符串构建复杂对象。

[HttpGet]
public IHttpActionResult Get([FromUri]Query query) {
    var result = _queryDispatcher.Dispatch<Query, QueryResult>(query);
    return Ok(result);
}

或者直接使用公开的参数。

[HttpGet]
public IHttpActionResult Get(string sortBy = "id", int page = 1, int pageSize = maxPageSize) {
    var query = new Query { SortParam = sortby, Page = page, PageSize = pageSize };
    var result = _queryDispatcher.Dispatch<Query, QueryResult>(query);
    return Ok(result);
}

它们都产生相同的功能。

然而,第一个允许更容易维护,因为如果在其中添加任何新属性,则无需更改操作,因为框架将根据提供的参数绑定模型。

此外,如果目标是保持控制器精简,则不要处理操作中的错误,而是应用横切关注点并由异常过滤器处理它