Apollo-link-rest: O que devo fazer quando o servidor retorna um resultado não compatível com Graphql

Criado em 20 jun. 2018  ·  6Comentários  ·  Fonte: apollographql/apollo-link-rest

o que estou tentando fazer é consultar as informações da conta para bcoin por meio de sua interface http rest.
Para fazer isso, eu devo

  1. pergunte os nomes de todos os accountName chamando GET /wallet/:id/account
  2. peça os detalhes da conta por GET /wallet/:id/account/:accountName

o problema é que a primeira chamada retornará algo como ["default", "mySecondAccountName"]
que não sei como analisar como uma resposta do graphql, nem passar diretamente para o segundo GET

por exemplo, quando tentei fazer uma consulta seguindo a consulta,

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

Vou receber Error: Network error: Cannot create property 'default' on string 'default'

Não consegui encontrar nenhuma pista no documento, mas este parece um caso muito comum, então devo estar faltando algo muito simples. Eu realmente aprecio se alguém pudesse me indicar o que devo procurar

question❔

Comentários muito úteis

@joemphilips , acho que você deveria usar um typePatcher

Eu o uso para lidar com respostas não compatíveis com Graphql, como

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

Definição de consulta

import { gql } from 'apollo-boost';

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

Configuração 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 };
    }
  }
});

Uso de consulta
`` `js
render () {
Retorna (
{({carregando, erro, dados}) => {
if (carregando) {
Retorna (

Carregando...

);
}

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

}
`
``

Todos 6 comentários

Estou apenas supondo, pois não estou familiarizado com o bcoin, mas aqui está uma sugestão:

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

Em seguida, você obtém os resultados disso a partir dos dados e os passa para uma nova consulta que obtém os detalhes da conta.

Obrigado pela resposta gentil e rápida. @fbartho
Talvez eu não devesse ter mencionado a bcoin, meu problema é mais simples

No exemplo da diretiva @export no documento, há um exemplo de chamada de endpoint REST duas vezes .
Minha pergunta é: o que devo fazer quando a primeira consulta neste exemplo retorna uma matriz de escalar em vez de uma matriz de objeto?
uma vez que não tem chave, parece que não há como especificar qual argumento deve ser exportado.

Eu também tentei não usar @export e, em vez disso, consultar como você mencionou, mas o resultado da busca é {}
com o seguinte aviso

Missing field account in {}

aliás, acho que na sua sugestão

query Account(id: $id)

deveria estar

query Account($id: id)

Descobri que quando executo o comando que você sugeriu, ou seja,

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

Na verdade, ele não executará nenhuma consulta e apenas retornará {} como data .
portanto, devo especificar { theFieldNameIDesire } após a linha de account , o problema é que não tenho nenhum nome de campo para especificar :(

@joemphilips , acho que você deveria usar um typePatcher

Eu o uso para lidar com respostas não compatíveis com Graphql, como

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

Definição de consulta

import { gql } from 'apollo-boost';

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

Configuração 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 };
    }
  }
});

Uso de consulta
`` `js
render () {
Retorna (
{({carregando, erro, dados}) => {
if (carregando) {
Retorna (

Carregando...

);
}

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

}
`
``

Desculpe responder tarde. sua solução parece não funcionar para string / escalar de array. Mas parece estar consertado . Tentarei novamente. E pode reabrir se continuar tendo problemas. Obrigado.

Esta página foi útil?
0 / 5 - 0 avaliações