- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试将 Servant 身份验证(servant-auth-server 包)与 RIO 作为我的处理程序 monad 结合使用,以避免出现 exceptT 反模式。但是,我无法正确排列类型以处理被拒绝的身份验证。
我的(简化的)API 端点是
type UserEndpoint = "user" :> (
Get '[JSON] User
:<|> ReqBody '[JSON] UpdatedUser :> Put '[JSON] User
)
和对应的服务器
protectedServer
:: HasLogFunc m
=> AuthResult AuthUserId
-> ServerT UserEndpoint (RIO m)
protectedServer (Authenticated authUser) =
getUser authUser :<|> updateUser authUser
-- Otherwise, we return a 401.
protectedServer _ = throwIO err401
在拒绝身份验证的分支中出现类型错误:
Could not deduce (MonadIO ((:<|>) (RIO m User)))
arising from a use of ‘throwIO’
[..]
我不理解这种类型的错误。据我所知(并给出了
protectedServer
的签名),返回类型应该是
ServerT UserEndpoint (RIO m)
,它应该有一个
MonadIO
的实例, 以便根据
exceptions tutorial 进行异常处理应该使用
throwIO
而不是
throwAll
来自
Servant.Auth.Server
.看来我还没有完全理解Servant的类型机制,我的错误在哪里?
updateUser :: HasLogFunc m => AuthUserId -> UpdatedUser -> RIO m User
updateUser authUser updateUser = ...
getUser :: HasLogFunc m => AuthUserId -> RIO m User
getUser authUser = ...
最佳答案
问题是 throwIO err401
是单例RIO
行动。但是当一个servant服务器有多个端点时,每个不同的处理程序必须由 :<|>
组成。组合器。
如果您的 API 有许多端点,那么为每个端点编写 401 返回处理程序很快就会变得烦人。幸运的是,似乎servant-auth-server提供 throwAll
自动为整个 API 构建错误返回处理程序的辅助函数。
编辑:正如 Ulrich 所指出的,throwAll
的问题是它只适用于 MonadError
monad 和 RIO
不是 MonadError
的实例.但是应该可以修改类型类以使其支持 RIO
.
首先,一些导入和辅助数据类型:
{-# LANGUAGE UndecidableInstances, TypeOperators, FlexibleInstances,
TypeFamilies, DataKinds, ImportQualifiedPost
#-}
module Main where
import RIO (RIO) -- rio
import RIO qualified
import Data.Tagged (Tagged (..)) -- package tagged
import Servant ((:<|>) (..), ServerError(..))
import Network.HTTP.Types -- package http-types
import Network.Wai -- package wai
import Data.ByteString.Char8 qualified as BS
这是主要的
RIOThrowAll
类型类:
class RIOThrowAll a where
rioThrowAll :: ServerError -> a
-- for a composition of endpoints
instance (RIOThrowAll a, RIOThrowAll b) => RIOThrowAll (a :<|> b) where
rioThrowAll e = rioThrowAll e :<|> rioThrowAll e
-- if we have a function, we ignore the argument and delegate on the result
instance (RIOThrowAll b) => RIOThrowAll (a -> b) where
rioThrowAll e = \_ -> rioThrowAll e
-- if we reach a RIO action at the tip of a function
instance RIOThrowAll (RIO.RIO env x) where
rioThrowAll e = RIO.throwIO e
-- this is only for Raw endpoints which embed a WAI app directly
instance RIOThrowAll (Tagged (RIO.RIO env x) Application) where
rioThrowAll e = Tagged $ \_req respond ->
respond $ responseLBS (mkStatus (errHTTPCode e) (BS.pack $ errReasonPhrase e))
(errHeaders e)
(errBody e)
关于authentication - 使用 RIO 在 Servant.Auth 中拒绝身份验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67262209/
我正在使用rdf4j库来导出XML文件。我使用org.eclipse.rdf4j.rio.RDFWriter将其保存到文件中,并且我需要定义基本名称空间。因此,我希望拥有这样的东西:。我知道我可以使用
我正在尝试在 RIO 应用程序中设置日志记录;但是,我似乎不了解日志记录界面。 RIO 文档鼓励定义记录器并按如下方式运行应用程序: withLogFunc logOptions $ \lf -> d
有人有如何在node-rio中使用sourceAndEval函数的示例吗? https://github.com/albertosantini/node-rio 我可以仅使用 eval 来运行基本示例
使用 rio.plot.show 后如何添加颜色条? 我尝试了很多东西,但遇到了各种错误 这是我尝试过的一种方法: fig, ax = plt.subplots(figsize = (16, 16))
RIO 在这里代表 Windows8 'Registered I/O'网络扩展。从示例代码来看,似乎无论您是将 RIONotify 与事件还是 IO 完成端口一起使用,您基本上最终都会编写相同的循环,
我已使用所需组件填充了表单,并将示例代码粘贴到了按钮单击事件中。 我已添加 TStringDynArrayarray 和 TSearchOption 类型声明,但出现编译错误,如下所示。 unit d
有没有办法在启动 IDE 时摆脱烦人的欢迎页面? 对于某些以前的版本,您可以通过注册表完成此操作,但我可以在 Rio 中找到它。尝试将文件夹“欢迎页面”重命名为其他名称,但随后出现错误 - 找不到页面
我对 Delphi 10.3 Rio 内联变量声明感到非常兴奋。但是我遇到了奇怪的问题,似乎我需要在内联声明后初始化记录: program Project8; {$APPTYPE CONSOLE} {
有没有办法在 iOS 中使用 MVVMCross 实现方法绑定(bind)?我在视频或教程中看不到此类绑定(bind)的示例... ImageNavigationViewModel: publ
我有一个曾经在 Delphi Seattle 创建的项目,现在我想搬到 Delphi Rio。我使用 findfirst/findnext 读取外部 SD 卡上的目录结构 i := findfir
我的代码: require 'rio' rio('nice.jpg') < rio('http://farm4.static.flickr.com/3134/3160515898_59354c9733
我正在使用 RIO monad 和 RIO 库,并且想添加日志记录。 RIO 日志函数,如 logInfo,将 Utf8Builder 作为参数,它是 ByteString 构建器的包装器。我想在我的
.NET 团队是否有任何计划让 Windows 8/Server 2012 中引入的 RIO 套接字在 .NET 中可用? 在 .NET 中使用它们的过渡期间我有哪些选择 - 扩展 Socket 类?
我正在尝试将 Servant 身份验证(servant-auth-server 包)与 RIO 作为我的处理程序 monad 结合使用,以避免出现 exceptT 反模式。但是,我无法正确排列类型以处
我有一个 HTTPRepository使用存储库的 URL 进行初始化。我使用 RepositoryConnection检索和添加(天气)数据到存储库。从 Web 服务中检索数据,然后将其转换为 RD
我有一个 ListView ,它绑定(bind)到一个字符串数组: 我的项目模板只是一个 TextView ... 再次使用瑞士... local:MvxBind="Text " /> 但
我正在尝试使用 GeoText 生成国家/地区提及,但无法识别像里约热内卢、里约热内卢这样的城市。我查了字典,里面那些城市都可以。 输入: text = "里约热内卢、拉斯维加斯、纽约" geo =
我正在尝试通过服务器端路由使用 Meteor 访问 Rserve 服务器来调用 R 代码。允许访问 Rserve 的 Node.js 模块是 node-rio我在 meteorhacks:npm 中使
我使用 RIOSend 通过分布式网络发送部分 TCP 数据。 Nagle 已关闭以达到最小延迟。 当目的地是本地时,一切看起来都不错,但如果是真正的远程(大约 40 毫秒 ping)目的地,我会看到
我在让 winsock RIO 工作时遇到了问题。似乎每次我发布 RIOReceive 时,它都会立即返回并传输 0 个字节,而我的对等方无法通过消息。 发布 RIOReceive 后,我等待 R
我是一名优秀的程序员,十分优秀!