【问题标题】:REST (HATEOAS) and ReactJSREST (HATEOAS) 和 ReactJS
【发布时间】:2016-06-19 14:10:18
【问题描述】:

我有兴趣使用 REST 的 HATEOAS 原则来减少 SPA 应用程序中的业务逻辑。在特定于 React 的上下文中,我想知道是否存在使这不切实际的挑战,如果没有,有什么好的策略可以遵循?

使用 HATEOAS 从 UI 中删除业务逻辑的概念示例:

我只找到了一个建议React/Flux is not compatible with a HATEOAS strategy 的链接,在其他地方没有有意义的讨论。在 React/Flux 应用程序中真的不可行吗?那个 SO 帖子没有得到足够的关注。有没有人有最喜欢或推荐的方法来取得成功(有或没有 Flux 或 Redux)?

有人举了一个相当详细的例子leveraging HATEOAS in the context of Angular。我正在为 React 寻找类似的东西。

就我个人而言,我正在描绘超媒体链接中的 rel 标记,它控制渲染哪些 JSX 组件 (conditional JSX)。这对于现实世界的 React 应用程序来说是不是太天真了?也许有条件渲染的 React 组件粒度太粗,无法以这种方式使用?

我假设超媒体链接由 HAL 实现提供,或者以其他方式符合 ATOM 提要约定 (RFC4287)。

【问题讨论】:

    标签: rest reactjs redux flux hateoas


    【解决方案1】:

    HATEOAS 100% 兼容 React 和 Flux,HATEOAS 兼容 Angular,HATEOAS 兼容 JQuery 甚至 vanilla JS。

    HATEOAS 不会对消费客户端施加任何技术或实施要求。

    HATEOAS 实际上只是一个您可以设计 API 的概念(您可以使用多个标准之一,尽管像 HAL

    基本上,如果您可以调用 API,那么您就可以实现 HATEOAS 客户端。

    那么如何到达那里:

    • 第 1 步,您通常如何在 React 中进行 API 调用?以同样的方式进行。
    • 第 2 步,询问响应。
    • 第 3 步,根据响应,在 UI 中做出适当的响应。

    例如,调用订单 api /orders,我得到以下响应:

    {
        "_links": {
            "self": { "href": "/orders" },
            "next": { "href": "/orders?page=2" }
        }
    }
    

    由此我可以推断next 是一个有效的关系,如果我转到那个href,我实际上会收到第二页订单,所以在这种情况下,在UI 中显示下一个按钮。

    但是,如果我收到以下回复:

    {
        "_links": {
            "self": { "href": "/orders" },
        }
    }
    

    然后我可以推断出next 不是一个有效的关系,在我的 UI 中我应该禁用或不显示下一步按钮。

    没有魔法,它只是思想的改变,一种新的范式。

    【讨论】:

    • 它有一些缺点,如果您打算获取具有更大数据集的列表,则有效负载大小总是很大,因为所有记录都将包含 _links 内容。这对移动设备来说很痛苦,你的前端会非常健谈,而且当你必须生成链接以在某个补丁中发回时,这真的很令人沮丧。此外,您经常会发现自己正在编辑 _links 中的链接以获得正确的链接。此外,您的应用程序必须在每件该死的事情中分页。只有在你的 react 应用中实际使用它时,你才能体验到痛苦。
    • 那么在前端应用程序中路由会发生什么?如果用户通过 URL 深入到应用程序中,前端如何为正在加载的应用程序部分获取适当的 API 链接?毕竟,使用 HATEOAS,您通常从一个指向 API 入口点的链接开始,然后通过链接进一步进入应用程序。
    • @RahilAhmad REST 并不适用于简单的前端 2 后端通信,而是适用于许多客户端(尤其是不受您控制的客户端)必须与各种服务器/服务交互而不是针对它们耦合到各种媒体类型的特定 API,并提供对收到的响应进行操作的机制。 REST 并不是为了将有效负载减少到最低限度,而是为了支持持续数十年的系统的探索和自然进化。如果 REST 不能满足您的需求,请不要使用它
    • @wired_in 你基本上需要管理你的前端到目前为止已经探索过的内容以及它在探索 API 时收集的信息的上下文。用户遵循的链接关系基本上会在您的上下文中创建一棵树,其中树中的每个分支或多或少都指向其自己的动态页面(或组件)。某些媒体类型,即 hal-forms,可能需要您为响应数据的 _template 属性中包含的元素动态呈现表单组件。此外,该上下文应该能够使某些分支无效,以防数据过时
    【解决方案2】:

    在我说出我最可能错误/不相关的答案之前,我只想让您知道我刚刚阅读了 HATEOAS 是什么。那里的警告,从我简要阅读的内容来看,HATEOAS 似乎主要是关于 API,通过为您提供与您刚刚请求的资源相关的资源的链接,告诉您如何导航自身。

    既然如此,我看不出为什么您不能在您的操作中实现动态 url ajax 调用,这将根据提供给您的内容改变您的 SPA 的应用程序状态(即 Redux),但是,对于应用程序的所有部分,您仍然需要以可视方式表示状态。以下是粗略的半伪且未经过深思熟虑的表示,大致基于您的银行帐户示例:

    // our component file
    import React from 'react'
    import { makeAWithdrawl } from './actions'
    
    export default React.createClass({
      handleClick: function(e) {
        e.preventDefault()
        makeAWithdrawl(this.props.account.withdraw.href)
      },
      render: function () {
        <div className="account">
          <p className="account_number">{this.props.account.accountNumber}</p>
          <p className="balance">{this.props.account.balance}</p>
          <p><a href={this.props.account.deposit.href}>Deposit</a></p>
          {this.props.account.withdraw ? <p><a onClick={this.handleClick}>Withdraw</a></p> : ''}
        </div>
      }
    })
    
    
    // our actions file
    import store from 'store' // our redux store
    import axios from 'axios' // an ajax library
    
    export function makeAWithdrawl(url) {
      return axios.post(url).then(function(resp){
        store.dispatch({
          type: 'MAKE_WITHDRAWL',
          action: resp.data
        }) // do your reducer stuff
      })
    }
    

    您的应用程序仍然知道它在 SPA 中正在做什么,但是,这将允许 API 指导您在哪里调用以执行任何需要执行的操作。希望对您有所帮助。

    【讨论】:

      猜你喜欢
      • 2011-11-02
      • 2014-03-07
      • 1970-01-01
      • 1970-01-01
      • 2016-12-11
      • 1970-01-01
      • 2013-10-31
      • 2019-03-23
      • 2014-08-16
      相关资源
      最近更新 更多