Как использовать RxJS в Angular2 для взаимодействия с HATEOAS API? - PullRequest
0 голосов
/ 14 июня 2019

У меня есть (Django) API, который реализует HATEOAS, поэтому обычно объекты с внешним ключом передаются в виде 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/"
    ]
}

Мне нужно написать сервис, который будет ПОЛУЧАТЬ вышеуказанный объект, а затем перебирать URL-адреса datasets иПОЛУЧИТЕ их также (я знаю, возможно, это может быть более эффективным, но я учу себя о 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 Ответ

5 голосов
/ 15 июня 2019

Я бы сделал что-то вроде этого

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 - это круто.

...