gpt4 book ai didi

elm - 拦截 Elm 中的任何响应的 401

转载 作者:行者123 更新时间:2023-12-02 16:58:44 26 4
gpt4 key购买 nike

我正在 Elm 中构建一个应用程序,其中大多数 API 调用都受到保护;即用户需要登录才能进行 API 调用。如果用户未登录,他们将收到 401 Unauthorized 响应。如果任何响应是 401,我希望应用程序重定向到登录页面。

目前,我仅为单个 API 调用设置了此重定向。以下是代码的精简版本,可让您了解其设置方式:

-- Util/Api.elm
type alias Data data =
{ data : data
}

-- Resources/Expense.elm
getExpenses : (Progress (Api.Data (List Expense)) -> msg) -> Sub msg
getExpenses msg =
(dataDecoder expenseListDecoder)
|> Http.get expensesEndpoint
|> Progress.track expensesEndpoint msg

-- Main/Msg.elm
type Msg
= ExpenseListMsg ExpenseListMsg
| RedirectToLogin

-- Main/Update.elm
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
ExpenseListMsg msg ->
ExpenseList.Update.update msg model

GoTo path ->
model ! [ Navigation.newUrl path ]

RedirectToLogin ->
model ! [ Navigation.load "path/to/login" ]

-- ExpenseList/Msg.elm
type ExpenseListMsg
= GetExpensesProgress (Progress (Api.Data (List Expense)))
| SetLoading

-- ExpenseList/Update.elm
update : ExpenseListMsg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
SetLoading ->
{ model | expenses = setExpensesLoading model.expenses } ! []

GetExpensesProgress (Done { data }) ->
{ model | expenses = addExpenses model.expenses data } ! []

GetExpensesProgress (Fail (BadStatus { status })) ->
case status.code of
401 ->
model ! [ msgToCmd RedirectToLogin ]

_ ->
model ! []

GetExpensesProgress (Fail error) ->
model ! []

GetExpensesProgress progress ->
{ model | expenses = setExpensesLoading model.expenses } ! []

本质上,我想将 401 响应的逻辑从 ExpenseList/Update.elm 移动到 Main/Update.elm,以便我可以用它来满足我想要的任何请求。

我尝试了很多方法,但没有任何方法可以与 Elm 的类型系统配合使用。例如,我想做的一件事是尝试进行中间缺少特异性的嵌套模式匹配,例如:

-- Main/Update.elm
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
ApiCall (messageType (msg (Fail (BadStatus { status })))) ->
case status of ->
. . .
. . .

我希望这样的东西能够工作并匹配一条如下所示的消息:ApiCall (ExpenseListMsg (GetExpensesProgress (Fail (BadStatus))))。不幸的是,这不是正确的 Elm 语法,因此我的代码无法编译。

如何编写一些内容,允许我将 API 调用标记为 protected 并在 Main.Update.update 的顶层捕获 401 错误?

最佳答案

目前,API调用由ExpenseList/Update模块封装。这种封装使得 API 调用结果对于 Main 模块不可用。交互工作如下:Main -> FeatureModule -> API

因为 API 提供了确定应用是否应重定向到登录页面所需的信息,并且您希望 Main 模块执行重定向,所以 Main 模块需要访问 API。因此,需要去掉封装。相反,您可以:

  • 拥有一个 API 模块,通过生成 Task 来提供低级 API 功能。与生成 Cmd 不同,这允许调用者(例如 Main 模块)决定如何处理 Task 的结果,这可以是通过将 Task 转换为 Cmd 并将其交给 Elm 运行时来执行来获取。
  • ExpenseList.Update模块使用API​​模块来创建Tasks

按照这种安排:

  • Main 模块发送高级命令到功能模块,然后功能模块使用 API 模块生成低级指令,然后将其提供给模块。
  • Main 模块不需要关心这些低级指令是什么,它只是将 Task 转换为 Cmd 并等待结果。
  • 结果返回时采用低级格式(例如成功/失败)。此时,Main 模块可以跳转并处理 401 错误的重定向。否则,它可以将结果传递给功能模块,以便它可以处理结果。

关于elm - 拦截 Elm 中的任何响应的 401,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50574477/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com