当前位置: 首页 > 知识库问答 >
问题:

带超媒体的AngularJS(HATEOAS):如何使用超媒体URL来增加状态

阴雪风
2023-03-14

我有一个带有ui路由器的AngularJS应用程序,它使用带有超媒体的REST API。一般的想法是让API为其各种调用生成URL,并防止客户机自己构造URL。

[
  {
    "id": 1,
    "name": "Product A",
    "_links": {
      "self": {
        "href": "http://localhost:4444/api/products/1",
        "name": null,
        "templated": false
      },
      "actions": []
    }
  },
  {
    "id": 2,
    "name": "Product B",
    "_links": {
      "self": {
        "href": "http://localhost:4444/api/products/2",
        "name": null,
        "templated": false
      },
      "actions": []
    }
  }
]

还有别的想法吗?

除非我在这方面非常错误,否则我不是在寻找模板化的解决方案,即API返回一个url模板的解决方案,该url模板需要客户机注入参数。关键在于url已经填充了数据,因为有些url比上面提供的示例要复杂得多。

共有1个答案

从光启
2023-03-14

我以前遇到过几次这个问题。我在下面一步一步地详细说明了我首选的解决方案。最后两个步骤专门针对您在文章中概述的问题,但同样的原则可以应用于您的整个应用程序

首先在API级别上定义根endpoint。对应的根实体是顶级链接的集合,换句话说,客户端需要直接访问的链接。

其思想是客户机只需要知道一个endpoint,即根endpoint。这样做的好处是,您不必将路由逻辑复制到客户机,并且API的版本控制变得容易得多。

{
    "_links": {
      "products": {
        "href": "http://localhost:4444/api/products",
      }
    }
}
$stateProvider.state('main', {
    resolve: {
        root: function($http) {
         return $http.get("http://localhost:4444/api/").then(function(resp){
              return resp.data;
         });
        }
    }
});
 $stateProvider.state('products', {
    parent: 'main',
    url: "/products",
    resolve: {
        products: function($http, root) {
         return $http.get(root._links.products.href).then(function(resp){
              return resp.data;
         });
        }
    }
});
$stateProvider.state('products.product', {
    url: "/{productId}"
    resolve: {
        product: function($http, $timeout, $state, $stateParams, $q products) {
         var productId = parseInt($stateParams.productId);
         var product;

        for (var i = 0; i < products.length; i++) {
            product = products[i];
            if (product.id === productId) {
                return $http.get(product._links.self.href).then(function(response){
                    return response.data;
                });
                }
        }

        // go back to parent state if no child was found, do so in a $timeout to prevent infinite state reload
        $timeout(function(){
            $state.go('^', $stateParams);
        });

        // reject the resolve
        return $q.reject('No product with id ' + productId);
    }
});

您可以将上面的代码移动到服务中,以使您的状态更加轻量级。

希望这能有所帮助!

 类似资料:
  • 我现在正在读《实践中的Rest》一书。我无法理解以下术语超媒体,超媒体格式,超媒体控件,域应用协议。作者建议需要特定领域的超媒体格式。我很难理解这些。我在谷歌上搜索了这些术语,但没有找到正确的答案。谁能解释一下这些术语,以及为什么我们需要特定于领域的超媒体格式而不是应用程序/XML?

  • 超媒体点击事件的监听 超媒体消息的点击事件包括:点击打开链接url和点击打开app的原生页面;其中点击打开url链接使用setOnHyperUrlListener接口,方法如下: Ntalker.getInstance().setOnHyperUrlListener(new OnHyperUrlListener() { @Override public void OnOpenHyp

  • 顺便说一句,真的很好的谈话! 所有的输入都很感激!

  • /** 是否开启超媒体吸底功能(默认开启) @param enableSnap enableSnap */ [Ntalker ntalker_setEnableSnap:NO];

  • 那么问题是,在加载水果详细信息页面时,没有当前上下文的客户机如何决定要获取的API URL? 现在怎么办:不? 首先想到的一个解决方案是在集合响应中有一个'item'URL模板,并使用其中的命名参数来构造页面URL。然后,详细信息页面将查询API以恢复相同的“Item”URL,并植入它传递的参数。这似乎并不理想,但它确实实现了期望的解耦。 提前谢了。