Apollo-link-rest: Que dois-je faire lorsque le serveur renvoie un résultat non conforme à graphql

Créé le 20 juin 2018  ·  6Commentaires  ·  Source: apollographql/apollo-link-rest

ce que j'essaie de faire, c'est d'interroger les informations de compte pour bcoin via son interface de repos http.
Pour ce faire, je dois

  1. demandez les noms de tous les accountName existants en appelant GET /wallet/:id/account
  2. demander les détails du compte par GET /wallet/:id/account/:accountName

le problème est que le premier appel renverra quelque chose comme ["default", "mySecondAccountName"]
que je ne sais pas analyser en tant que réponse graphql, ni passer directement au second GET

par exemple, lorsque j'ai essayé d'interroger en suivant la requête,

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

J'obtiendrai Error: Network error: Cannot create property 'default' on string 'default'

Je n'ai trouvé aucun indice dans le document, mais cela semble un cas très courant, je dois donc manquer quelque chose de très simple. J'apprécie vraiment si quelqu'un pouvait m'indiquer ce que je devrais rechercher

question❔

Commentaire le plus utile

@joemphilips Je pense que vous devriez utiliser un typePatcher

Je l'utilise pour gérer les réponses non conformes à graphql comme

{
   "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
   }
}

Définition de la requête

import { gql } from 'apollo-boost';

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

Configuration 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 };
    }
  }
});

Utilisation des requêtes
```js
rendu() {
revenir (
{({ chargement, erreur, données }) => {
si (chargement) {
revenir (

Chargement...

);
}

      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>
);

}
`
``

Tous les 6 commentaires

Je ne fais que deviner car je ne connais pas bcoin, mais voici une suggestion :

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

Ensuite, vous obtenez les résultats de ces données et les transmettez à une nouvelle requête qui obtient les détails du compte.

Merci pour la réponse aimable et rapide. @fbartho
Peut-être que j'aurais pas dû parler de bcoin, mon problème est plus simple

Dans l'exemple de la directive @export dans le document, il y a un exemple d'appel du point de terminaison REST deux fois .
Ma question est la suivante : que dois-je faire lorsque la première requête de cet exemple renvoie un tableau de scalaires au lieu d'un tableau d'objets ?
puisqu'il n'a pas de clé, il semble qu'il n'y ait aucun moyen de spécifier quel argument doit être exporté.

J'ai également essayé de ne pas utiliser @export et d'interroger à la place comme vous l'avez mentionné, mais le résultat de l'extraction est {}
avec l'avertissement suivant

Missing field account in {}

en passant, je pense que dans votre suggestion

query Account(id: $id)

devrait être

query Account($id: id)

J'ai découvert que lorsque j'ai exécuté la commande que vous avez suggérée, c'est-à-dire

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

Il n'exécutera aucune requête et renverra simplement {} sous la forme data .
donc je dois spécifier { theFieldNameIDesire } après la ligne de account , le problème c'est que je n'ai pas de nom de champ à spécifier :(

@joemphilips Je pense que vous devriez utiliser un typePatcher

Je l'utilise pour gérer les réponses non conformes à graphql comme

{
   "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
   }
}

Définition de la requête

import { gql } from 'apollo-boost';

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

Configuration 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 };
    }
  }
});

Utilisation des requêtes
```js
rendu() {
revenir (
{({ chargement, erreur, données }) => {
si (chargement) {
revenir (

Chargement...

);
}

      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>
);

}
`
``

Désolé de répondre tardivement. votre solution semble ne pas fonctionner pour la chaîne/le scalaire du tableau. Mais ça a l'air d'être réglé . Je vais réessayer. Et peut rouvrir si je continue à avoir des problèmes. Merci.

Cette page vous a été utile?
0 / 5 - 0 notes