我可以(或应该)在 Web API 控制器中使用 IAsyncEnumerable<T> 而不是 Task<ActionResult<IEnumerable<T>>>
Can (or should) I use IAsyncEnumerable<T> instead of Task<ActionResult<IEnumerable<T>>> in a Web API Controller
我目前有一个网站 API
- 使用存储库中的
FromSqlRaw(...).ToListAsync()
获取一行数据
- return通过控制器将此数据作为
Ok(data.ToArray())
作为 Task<ActionResult<IEnumerable<MyClass>>>
。
现在我想知道我是否应该或可以将 IAsyncEnumerable 用作 return 类型。想法是在存储库和控制器中使用它。但是,在这个(现在已经过时) 中声明不应使用它。这里建议的解决方案是这样的:
FromSqlRaw(...).AsNoTracking().AsAsyncEnumerable()
至于控制器,我希望用 ActionResult
包裹响应以显式设置 return 代码。但是,that目前似乎不起作用。
我应该只为存储库应用解决方案并将结果作为我的控制器中的列表使用,还是保持原样?
IAsyncEnumerable
为您提供了一个用于 pull-based asynchronous 数据检索的界面。换句话说,这个 API 代表一个迭代器,其中下一个项目是异步获取的。
这意味着您将分几轮接收数据,每轮都以异步方式接收数据。
之前 IAsyncEnumerable
你可以使用 IEnumerable<Task<T>>
,它代表一堆 return 类型的异步操作 T
.
而 Task<IEnumerable<T>>
表示具有 return 类型的单个异步操作 IEnumerable<T>
。
让我们将这些知识应用到 WebAPI:
- 从 HTTP 消费者的角度来看,
Task<ActionResult<T>>
和 ActionResult<T>
之间没有区别。从用户的角度来看,这是一个实现细节。
- WebAPI 控制器的操作实现了请求-响应模型。这意味着在消费者端发送单个请求并接收单个响应。
- 如果消费者再次调用相同的操作,则会实例化一个新的控制器并处理该请求。
这意味着如果您的 API 的消费者作为操作结果类型公开,则无法利用 IAsyncEnumerable
。
我目前有一个网站 API
- 使用存储库中的
FromSqlRaw(...).ToListAsync()
获取一行数据 - return通过控制器将此数据作为
Ok(data.ToArray())
作为Task<ActionResult<IEnumerable<MyClass>>>
。
现在我想知道我是否应该或可以将 IAsyncEnumerable 用作 return 类型。想法是在存储库和控制器中使用它。但是,在这个(现在已经过时)
FromSqlRaw(...).AsNoTracking().AsAsyncEnumerable()
至于控制器,我希望用 ActionResult
包裹响应以显式设置 return 代码。但是,that目前似乎不起作用。
我应该只为存储库应用解决方案并将结果作为我的控制器中的列表使用,还是保持原样?
IAsyncEnumerable
为您提供了一个用于 pull-based asynchronous 数据检索的界面。换句话说,这个 API 代表一个迭代器,其中下一个项目是异步获取的。
这意味着您将分几轮接收数据,每轮都以异步方式接收数据。
之前
IAsyncEnumerable
你可以使用IEnumerable<Task<T>>
,它代表一堆 return 类型的异步操作T
.而
Task<IEnumerable<T>>
表示具有 return 类型的单个异步操作IEnumerable<T>
。
让我们将这些知识应用到 WebAPI:
- 从 HTTP 消费者的角度来看,
Task<ActionResult<T>>
和ActionResult<T>
之间没有区别。从用户的角度来看,这是一个实现细节。 - WebAPI 控制器的操作实现了请求-响应模型。这意味着在消费者端发送单个请求并接收单个响应。
- 如果消费者再次调用相同的操作,则会实例化一个新的控制器并处理该请求。
这意味着如果您的 API 的消费者作为操作结果类型公开,则无法利用 IAsyncEnumerable
。