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

时间:2019-06-14 14:03:26

标签: rxjs angular2-services hateoas

我有一个实现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并同样获取它们(我知道,也许它可以更有效,但是我正在自学HATEOAS) 。

数据集对象如下:

{
    "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可以做到这一点。怎么样?

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

1 个答案:

答案 0 :(得分:5)

我会做这样的事情

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很棒。