Apollo-link-rest: Что мне делать, если сервер возвращает результат, не совместимый с graphql

Созданный на 20 июн. 2018  ·  6Комментарии  ·  Источник: apollographql/apollo-link-rest

то, что я пытаюсь сделать, - это запросить информацию об учетной записи в bcoin через его интерфейс http rest.
Для этого я должен

  1. спросить имена всех существующих accountName , вызвав GET /wallet/:id/account
  2. запросить реквизиты счета GET /wallet/:id/account/:accountName

проблема в том, что первый вызов вернет что-то вроде ["default", "mySecondAccountName"]
который я не знаю, как анализировать как ответ graphql, и не передавать напрямую второму GET

например, когда я попытался выполнить запрос по следующему запросу,

query (id: "primary") @rest(type: AccountName, path: "/wallet/:id/account") {
  default

Я получу Error: Network error: Cannot create property 'default' on string 'default'

Я не смог найти никаких подсказок в документе, но это кажется очень распространенным случаем, поэтому мне, должно быть, не хватает чего-то очень простого. Я очень признателен, если кто-нибудь может указать мне, что мне следует искать

question❔

Самый полезный комментарий

@joemphilips Я думаю, вам следует использовать typePatcher

Я использую его для обработки ответов, не совместимых с graphql, например

{
   "100": {
      "id": 100,
      "node_id": 105,
      "category_id": 8,
      "title": "Title 100",
      "highlight": true
   },
   "138": {
      "id": 138,
      "node_id": 106,
      "category_id": 7,
      "title": "Title 138",
      "highlight": false
   },
   "140": {
      "id": 140,
      "node_id": 101,
      "category_id": 9,
      "title": "Title 140",
      "highlight": false
   },
   "158": {
      "id": 158,
      "node_id": 146,
      "category_id": 4,
      "title": "Title 158",
      "highlight": false
   }
}

Определение запроса

import { gql } from 'apollo-boost';

export const GET_NEWS_QUERY = gql`
  query getNews {
    News @rest(type: "News", path: "news") {
      data
    }
  }
`;

Конфигурация RestLink

const restLink = new RestLink({
  uri: API_URL,
  typePatcher: {
    News: (data, outerType) => {
      if (outerType === 'News') {
        data = Object.keys(data).map(id => {
          const result = data[id];

          if (result) {
            return {
              __typename: 'News',
              ...result
            };
          }
        });
      }

      return { data };
    }
  }
});

Использование запроса
`` js
оказывать() {
возвращение (
{({загрузка, ошибка, данные}) => {
if (loading) {
возвращение (

Загружается ...

);
}

      if (error) {
        return (
          <View>
            <Text>Error :(</Text>
          </View>
        );
      }

      const news = data && data.News && data.News.data;
      const filteredNews = news && news.filter(Boolean);

      return (
        <Styles.Container>
          <Carousel
            data={filteredNews}
            handleOnPress={this.navigateToScreen}
          />
        </Styles.Container>
      );
    }}
  </Query>
);

}
`
``

Все 6 Комментарий

Я только догадываюсь, так как я не знаком с bcoin, но вот предложение:

query Account(id: $id){
   account(id: $id) @rest(type: "[String]", path: "/wallet/:id/account")
}

Затем вы получаете результаты из данных и передаете их новому запросу, который получает данные учетной записи.

Спасибо за добрый и быстрый ответ. @fbartho
Может, мне не стоило упоминать о bcoin, моя проблема проще

В примере директивы @export в документе есть пример двойного вызова конечной точки REST .
Мой вопрос: что мне делать, если первый запрос в этом примере возвращает массив Scalar вместо массива объектов?
поскольку у него нет ключа, похоже, нет способа указать, какой аргумент следует экспортировать.

Я также попытался не использовать @export и вместо этого запросить, как вы упомянули, но результатом выборки будет {}
со следующим предупреждением

Missing field account in {}

кстати я думаю в твоем предложении

query Account(id: $id)

должно быть

query Account($id: id)

Я обнаружил, что когда я запускаю предложенную вами команду, т.е.

query Account(id: $id){
   account(id: $id) @rest(type: "[String]", path: "/wallet/:id/account")
}

На самом деле он не выполняет никаких запросов, а просто возвращает {} как data .
поэтому я должен указать { theFieldNameIDesire } после строки account , проблема в том, что у меня нет имени поля для указания :(

@joemphilips Я думаю, вам следует использовать typePatcher

Я использую его для обработки ответов, не совместимых с graphql, например

{
   "100": {
      "id": 100,
      "node_id": 105,
      "category_id": 8,
      "title": "Title 100",
      "highlight": true
   },
   "138": {
      "id": 138,
      "node_id": 106,
      "category_id": 7,
      "title": "Title 138",
      "highlight": false
   },
   "140": {
      "id": 140,
      "node_id": 101,
      "category_id": 9,
      "title": "Title 140",
      "highlight": false
   },
   "158": {
      "id": 158,
      "node_id": 146,
      "category_id": 4,
      "title": "Title 158",
      "highlight": false
   }
}

Определение запроса

import { gql } from 'apollo-boost';

export const GET_NEWS_QUERY = gql`
  query getNews {
    News @rest(type: "News", path: "news") {
      data
    }
  }
`;

Конфигурация RestLink

const restLink = new RestLink({
  uri: API_URL,
  typePatcher: {
    News: (data, outerType) => {
      if (outerType === 'News') {
        data = Object.keys(data).map(id => {
          const result = data[id];

          if (result) {
            return {
              __typename: 'News',
              ...result
            };
          }
        });
      }

      return { data };
    }
  }
});

Использование запроса
`` js
оказывать() {
возвращение (
{({загрузка, ошибка, данные}) => {
if (loading) {
возвращение (

Загружается ...

);
}

      if (error) {
        return (
          <View>
            <Text>Error :(</Text>
          </View>
        );
      }

      const news = data && data.News && data.News.data;
      const filteredNews = news && news.filter(Boolean);

      return (
        <Styles.Container>
          <Carousel
            data={filteredNews}
            handleOnPress={this.navigateToScreen}
          />
        </Styles.Container>
      );
    }}
  </Query>
);

}
`
``

Извините, что ответил поздно. ваше решение, похоже, не работает для строки / скаляра массива. Но вроде бы поправили . Я попробую снова. И может снова открыться, если у меня будут проблемы. Спасибо.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги