如何在 Angular2 中使用 RxJS 与 HATEOAS 交互 API?

How to use RxJS in Angular2 to interact with HATEOAS API?

我有一个实现 HATEOAS 的 (Django) API,因此通常外键对象作为 URL 到达其他 API 端点。以下是 http://localhost:8000/brew-monitor/api/fermentations/1/ 的结果,是一个带有关联数据集对象的发酵对象:

{
    "id": 1,
    "name": "My Beer",
    "datasets": [
        "http://localhost:8000/brew-monitor/api/datasets/1/",
        "http://localhost:8000/brew-monitor/api/datasets/2/"
    ]
}

我需要编写一个服务来获取上述对象,然后遍历 datasets URL 并获取它们(我知道,也许它可以更有效,但我正在自学仇恨)。

数据集对象如下所示:

{
    "id": 1,
    "unit": "DEGF",
    "variable_measured": "T",
    "fermentation": "http://localhost:8000/brew-monitor/api/fermentations/1/",
    "logging_device": "http://localhost:8000/brew-monitor/api/devices/1/",
    "controls": [],
    "active": true,
    "datapoints": [
        "http://localhost:8000/brew-monitor/api/datapoints/1/",
        "http://localhost:8000/brew-monitor/api/datapoints/2/",
        "http://localhost:8000/brew-monitor/api/datapoints/3/"
    ]
}

所以我希望我的服务的最终结果如下所示:

{
    "id": 1,
    "name": "My Beer",
    "datasets": [
        {
            "id": 1,
            "unit": "DEGF",
            "variable_measured": "T",
            "fermentation": "http://localhost:8000/brew-monitor/api/fermentations/1/",
            "logging_device": "http://localhost:8000/brew-monitor/api/devices/1/",
            "controls": [],
            "active": true,
            "datapoints": [
                "http://localhost:8000/brew-monitor/api/datapoints/1/",
                "http://localhost:8000/brew-monitor/api/datapoints/2/",
                "http://localhost:8000/brew-monitor/api/datapoints/3/"
            ]
        },
        {
            "id": 2,
            "unit": "UNITLESS",
            "variable_measured": "SG",
            "fermentation": "http://localhost:8000/brew-monitor/api/fermentations/1/",
            "logging_device": "http://localhost:8000/brew-monitor/api/devices/1/",
            "controls": [],
            "active": true,
            "datapoints": [
                "http://localhost:8000/brew-monitor/api/datapoints/4/",
                "http://localhost:8000/brew-monitor/api/datapoints/5/",
                "http://localhost:8000/brew-monitor/api/datapoints/6/"
            ]
        }
    ]
}

我只是知道 RxJS 可以做到这一点。怎么样?

编辑: 我有一个使用嵌套订阅的解决方案,但我认为您应该避免这种情况是常识。所以请不要嵌套订阅。

我会做这样的事情

const source$ = of({
    "id": 1,
    "name": "My Beer",
    "datasets": [
        "http://localhost:8000/brew-monitor/api/datasets/1/",
        "http://localhost:8000/brew-monitor/api/datasets/2/"
    ]
});
const data$ = source$.pipe(
  switchMap(source => this.getDatasets(source))
);

data$.subscribe(x => console.log(x));

function getDatasets(source) {
  return forkJoin(source.datasets.map(endpoint => fakeHttpRequest(endpoint))).pipe(
    map(results => ({...source, datasets: results}))
  );
}

function fakeHttpRequest(endpoint) {
  return of({
    test: '123'
  });
}

RXJS 很棒。