目前是否就 api 设计适合 react/redux 应用达成共识?

Is there currently a consensus on which api design fits a react/redux app?

我正在使用 React 和 Redux 构建单页应用程序。这当然需要一个数据后端。现在我们正在研究哪种 api 架构是最好的,但我找不到关于哪种 api 架构最适合 react/redux 应用程序的共识。

现在我知道您基本上可以随心所欲地使用数据。但是仍然有明显的市场领导者,例如 redux over mobx。这并不能使他们变得更好,但至少知道偏好在哪里是件好事。

所以我的问题是:目前 react/redux 应用最常使用哪种 api 架构?

如今,新技术层出不穷。对于选择使用什么并没有真正达成共识,就像过去一样。找不到最适合 react/redux 应用程序的架构。找到最适合您项目的架构。

根据我们的经验,最好不要制作 API "fit" react/redux,反之亦然。 只需使用 thunk-action-creators 并以任何形式处理 API 调用。

这是一个人为的例子:

export function getUserById (userId) {
    return async dispatch => {
        dispatch({ type: 'REQUEST_USER_BY_ID', payload: userId })
        try {
            const user = await api.get(`/users/${userId}`)
            ga('send', 'event', 'user', 'profile', 'view')

            dispatch({
                type: 'LOAD_USER',
                payload: user
            })

            dispatch({
                type: 'NOTIFY_SUCCESS',
                payload: `Loaded ${user.firstname} ${user.lastname}!`
            })
        }
        catch (err) {
            dispatch({
                type: 'NOTIFY_ERROR',
                payload: `Failed to load user: ${err.message}`,
            })
        }
    }
}

这种方法的最大好处是灵活性。 API(s) 对消费者完全没有意见。 您可以在任何页面上以不同方式处理错误、添加重试逻辑、回退逻辑。 易于将需要并行或顺序调用多个不同 API 的操作粘合在一起。

我们尝试了很多方法,例如 "redux over the wire" 和 relays/apollos "bind component to query"。 这个被认为是最灵活、最容易理解和重构的。

很难找到关于这个主题的权威信息或指南,但如果您专门为一个 flux/redux 应用程序创建一个 API,并且以规范化形式存储数据,则很难争辩在数据库中,在您的 API 端点中对其进行非规范化只是为了在您的客户端中直接对其进行规范化(使用 normalizr)是相当愚蠢的......在这种情况下,只需将数据规范化并像那样通过网络将其传递给您的客户。

具体来说,你会有这样的东西:

GET /meetings

{
    "result": ["1", "2"],
    "entities": {
        "meetings": {
            "1": { "id": 1, "date": "2016-01-01", "attendees": [1, 2, 3] },
            "2": { "id": 2, "date": "2016-01-02", "attendees": [2, 3, 4] }
        },
        "users": {
            "1": { "id": 1, "name": "User 1" },
            "2": { "id": 1, "name": "User 2" },
            "3": { "id": 1, "name": "User 3" },
            "4": { "id": 1, "name": "User 4" }
        }
    }
}

鉴于这些实体中的每一个都对应于您所在州的 属性,这样的响应是 trivial to merge into your store in a reducer action, using something like Lodash merge:

return _.merge({}, state, action.entities);

如果您有多个消费者,您可以选择 normalize=true 查询参数。您可能还想将其与某种 expand|include=entities,to,include 查询参数结合使用。

最后,请注意 JSON API 规范 doesn't play nicely 具有 flux/redux 存储的规范化结构。

延伸阅读: