通过 react(ApolloClient.query()) 方法从 GraphQL 服务器获取数据

Posted

技术标签:

【中文标题】通过 react(ApolloClient.query()) 方法从 GraphQL 服务器获取数据【英文标题】:Fetching data from GraphQL server via react(ApolloClient.query()) method 【发布时间】:2020-12-15 03:43:19 【问题描述】:

首先对不起我的英语。 所以我试图从 GraphQL 服务器获取一些数据并且有几个问题, 这是我的代码:

import  createHttpLink  from 'apollo-link-http';
import  gql  from '@apollo/client';
import  ApolloClient, InMemoryCache  from '@apollo/client';
import 'babel-polyfill';

const httpLink = createHttpLink(
  uri: 'https://api.spacex.land/graphql/',
  headers: 
      authorization: 'Bearer MY_TOKEN',
  ,
);

const client = new ApolloClient(
  link: httpLink,
  cache: new InMemoryCache(),
  connectToDevTools: true,
  query: 
    fetchPolicy: 'network-only',
    errorPolicy: 'all',
  
);

async function fetchedData(params) 
  const fetched = await client.query(
    query: gql`
      query 
        launchesPast(limit: 10) 
          mission_name
          launch_date_local
          launch_site 
            site_name_long
          
          links 
            article_link
            video_link
          
          rocket 
            rocket_name
            first_stage 
              cores 
                flight
                core 
                  reuse_count
                  status
                
              
            
            second_stage 
              payloads 
                payload_type
                payload_mass_kg
                payload_mass_lbs
              
            
          
          ships 
            name
            home_port
            image
          
        
      
      `,
    fetchPolicy: "network-only",
    variables: null
  );
  return fetched;

导出默认fetchedData().then((res) => console.log(res));

Browser tab Network Browser tab Network

浏览器选项卡响应:

"errors":["message":"查询超出复杂度 limit","locations":["line":1,"column":1],"extensions":"code":"GRAPHQL_VALIDATION_FAILED"]

浏览器标签控制台:

POST https://api.spacex.land/graphql/ 400(错误请求);

例如,通过 GraphQLClient.request() 进行的相同查询正在运行。

import 'babel-polyfill';

import  GraphQLClient, gql  from 'graphql-request'

async function fetchedData() 
  const endpoint = 'https://api.spacex.land/graphql/'

  const graphQLClient = new GraphQLClient(endpoint, 
    headers: 
      authorization: 'Bearer MY_TOKEN',
    ,
  )

  const query = gql`query 
    launchesPast(limit: 10) 
      mission_name
      launch_date_local
      launch_site 
        site_name_long
      
      links 
        article_link
        video_link
      
      rocket 
        rocket_name
        first_stage 
          cores 
            flight
            core 
              reuse_count
              status
            
          
        
        second_stage 
          payloads 
            payload_type
            payload_mass_kg
            payload_mass_lbs
          
        
      
      ships 
        name
        home_port
        image
      
    
  
  `

  const data = await graphQLClient.request(query)
  console.log(JSON.stringify(data, undefined, 2))
  return data;

export default fetchedData().catch((error) => console.error(error));

Browser tab Network Browser tab Network

并且浏览器选项卡响应是正确的

【问题讨论】:

【参考方案1】:

您尝试使用variables 参数来实现。像这样?

const query = gql`query($limit: Int) 
    launchesPast(limit: $limit) 
      mission_name
      launch_date_local
      launch_site 
        site_name_long
      
      links 
        article_link
        video_link
      
      rocket 
        rocket_name
        first_stage 
          cores 
            flight
            core 
              reuse_count
              status
            
          
        
        second_stage 
          payloads 
            payload_type
            payload_mass_kg
            payload_mass_lbs
          
        
      
      ships 
        name
        home_port
        image
      
    
  
  `
  const variables =  limit: 10 ;
  
  const data = await graphQLClient.request(query, variables)

你的情况

import 
    createHttpLink
 from 'apollo-link-http';
import 
    gql
 from '@apollo/client';
import 
    ApolloClient,
    InMemoryCache
 from '@apollo/client';
import 'babel-polyfill';

const httpLink = createHttpLink(
    uri: 'https://api.spacex.land/graphql/',
    headers: 
        authorization: 'Bearer MY_TOKEN',
    ,
);

const client = new ApolloClient(
    link: httpLink,
    cache: new InMemoryCache(),
    connectToDevTools: true,
    query: 
        fetchPolicy: 'network-only',
        errorPolicy: 'all',
    
);

async function fetchedData(params) 
    const fetched = await client.query(
        query: gql`
        query($limit: Int) 
            launchesPast(limit: $limit) 
                mission_name
                launch_date_local
                launch_site 
                site_name_long
                
                links 
                article_link
                video_link
                
                rocket 
                rocket_name
                first_stage 
                    cores 
                    flight
                    core 
                        reuse_count
                        status
                    
                    
                
                second_stage 
                    payloads 
                    payload_type
                    payload_mass_kg
                    payload_mass_lbs
                    
                
                
                ships 
                name
                home_port
                image
                
            
        
    `,
        fetchPolicy: "network-only",
        variables: 
            limit: 10,
        
    );

    return fetched;

export default fetchedData().then((res) => console.log(res));

【讨论】:

我回去,打开Apollo Client DevTools,开始一步步删除各个字段,最终发现问题出在“rocket first_stage”或“rocket second_stage”。该请求仅在启用其中之一时才有效,但不能同时启用两者。我不知道它是如何工作的,但这是解决方案。尤其是我不知道 GraphQLClient().Request() 和 ApolloClient().Query() 之间有什么区别。

以上是关于通过 react(ApolloClient.query()) 方法从 GraphQL 服务器获取数据的主要内容,如果未能解决你的问题,请参考以下文章

React Native - 当 react-native 版本 > 0.55 时,无法通过 react-native-cli 创建新项目

在浏览器里用react库 不通过import

使用通过 react、redux 和 react-redux 完成的组件以及在 react 应用程序中使用 webpack 构建时出错

如何通过链接和路由传递道具/状态 - react.js

Heroku 在通过 Django 部署之前构建 React 应用程序

react怎么通过函数控制渲染dom