GatsbyJS получает данные от Restful API

Я новичок в React и GatsbyJS. Я запутался и не смог разобраться в том, как просто загрузить данные из стороннего Restful API.

Например: я хотел бы получить данные из randomuser.me/API, а затем использовать данные на страницах.

Давайте скажем что-то вроде этого:

  import React from 'react'
  import Link from 'gatsby-link'

  class User extends React.Component {
    constructor(){
      super();
      this.state = {
        pictures:[],
      };

    }

    componentDidMount(){
      fetch('https://randomuser.me/api/?results=500')
      .then(results=>{
        return results.json();
      })
      .then(data=>{
        let pictures = data.results.map((pic,i)=>{
            return(
              <div key={i} >
                <img key={i} src={pic.picture.medium}/>
              </div>
            )
        })
        this.setState({pictures:pictures})
      })
    }

    render() {
      return (<div>{this.state.pictures}</div>)
    }
  }

  export default User;

Но я хотел бы получить помощь GraphQL для фильтрации & сортировать пользователя и т.д...

Не могли бы вы помочь мне найти пример того, как я могу получать данные и вставлять их в GraphQL на gatsby-node.js

Ответ 1

Если вы хотите использовать GraphQL для извлечения ваших данных, вам необходимо создать sourceNode. Документ о создании плагина источника может помочь вам.

Выполните следующие шаги, чтобы иметь возможность запрашивать данные randomuser с помощью graphQL в вашем проекте Gatsby.

1) создавать узлы в gatsby-node.js

В корневой папке проекта добавьте этот код в gatsby-node.js:

const axios = require('axios');
const crypto = require('crypto');

exports.sourceNodes = async ({ boundActionCreators }) => {
  const { createNode } = boundActionCreators;

  // fetch raw data from the randomuser api
  const fetchRandomUser = () => axios.get('https://randomuser.me/api/?results=500');
  // await for results
  const res = await fetchRandomUser();

  // map into these results and create nodes
  res.data.results.map((user, i) => {
    // Create your node object
    const userNode = {
      // Required fields
      id: '${i}',
      parent: '__SOURCE__',
      internal: {
        type: 'RandomUser', // name of the graphQL query --> allRandomUser {}
        // contentDigest will be added just after
        // but it is required
      },
      children: [],

      // Other fields that you want to query with graphQl
      gender: user.gender,
      name: {
        title: user.name.title,
        first: user.name.first,
        last: user.name.last,
      },
      picture: {
        large: user.picture.large,
        medium: user.picture.medium,
        thumbnail: user.picture.thumbnail,
      }
      // etc...
    }

    // Get content digest of node. (Required field)
    const contentDigest = crypto
      .createHash('md5')
      .update(JSON.stringify(userNode))
      .digest('hex');
    // add it to userNode
    userNode.internal.contentDigest = contentDigest;

    // Create node with the gatsby createNode() API
    createNode(userNode);
  });

  return;
}

Я использовал axios для получения данных, поэтому вам нужно будет установить его: npm install --save axios

объяснение:

Цель состоит в том, чтобы создать каждый узел для каждой части данных, которую вы хотите использовать. Согласно документации createNode, вы должны предоставить объект с несколькими обязательными полями (id, parent, internal, children).

Как только вы получите данные результатов из API-интерфейса randomuser, вам просто нужно создать этот объект-узел и передать его функции createNode().

Здесь мы сопоставляем результаты, как вы хотели получить 500 randomusers https://randomuser.me/api/?results=500.

создайте объект userNode с необходимыми полями. Вы можете добавить больше полей в зависимости от того, какие данные вы хотите использовать в своем приложении.

Просто создайте узел с помощью функции createNode() API Gatsby.

2) запрашивать данные с помощью GraphiQL

Как только вы это сделали, запустите gatsby develop и перейдите на http://localhost: 8000/___ graphql.

Вы можете играть с графическим языком, чтобы создать идеальный запрос. Как мы назвали internal.type нашего объекта узла 'RandomUser', мы можем запросить allRandomUser, чтобы получить наши данные.

{
  allRandomUser {
    edges {
      node {
        gender
        name {
          title
          first
          last
        }
        picture {
          large
          medium
          thumbnail
        }
      }
    }
  }
}

3) используйте этот запрос на странице gatsby

На вашей странице, например src/pages/index.js, используйте запрос и покажите свои данные:

import React from 'react'
import Link from 'gatsby-link'

const IndexPage = (props) => {
  const users = props.data.allRandomUser.edges;

  return (
    <div>
      {users.map((user, i) => {
        const userData = user.node;
        return (
          <div key={i}>
            <p>Name: {userData.name.first}</p>
            <img src={userData.picture.medium} />
          </div>
        )
      })}
    </div>
  );
};

export default IndexPage

export const query = graphql'
  query RandomUserQuery {
    allRandomUser {
      edges {
        node {
          gender
          name {
            title
            first
            last
          }
          picture {
            large
            medium
            thumbnail
          }
        }
      }
    }
  }
';

Вот и все!

Ответ 2

Большое спасибо, это отлично работает для меня, я меняю только небольшие части габбаев-node.js, потому что это вызывает ошибку при использовании sync & await, я думаю, мне нужно изменить какой-то раздел процесса сборки, чтобы использовать babel, чтобы позволить мне использовать синхронизацию или ждать.

Вот код, который работает для меня.

 const axios = require('axios');
 const crypto = require('crypto');

 // exports.sourceNodes = async ({ boundActionCreators }) => {
 exports.sourceNodes = ({boundActionCreators}) => {
const {createNode} = boundActionCreators;
return new Promise((resolve, reject) => {

// fetch raw data from the randomuser api
// const fetchRandomUser = () => axios.get('https://randomuser.me/api/?results=500');
// await for results
// const res = await fetchRandomUser();

axios.get('https://randomuser.me/api/?results=500').then(res => {

  // map into these results and create nodes
  res.data.results.map((user, i) => {

    // Create your node object
    const userNode = {
      // Required fields
      id: '${i}',
      parent: '__SOURCE__',
      internal: {
        type: 'RandomUser', // name of the graphQL query --> allRandomUser {}
        // contentDigest will be added just after
        // but it is required
      },
      children: [],

      // Other fields that you want to query with graphQl
      gender: user.gender,
      name: {
        title: user.name.title,
        first: user.name.first,
        last: user.name.last
      },
      picture: {
        large: user.picture.large,
        medium: user.picture.medium,
        thumbnail: user.picture.thumbnail
      }
      // etc...
    }

    // Get content digest of node. (Required field)
    const contentDigest = crypto.createHash('md5').update(JSON.stringify(userNode)).digest('hex');
    // add it to userNode
    userNode.internal.contentDigest = contentDigest;

    // Create node with the gatsby createNode() API
    createNode(userNode);
  });
  resolve();
});

});

}

Ответ 3

Ответы, приведенные выше, работают, за исключением того, что запрос на шаге 2 возвращает только один узел для меня. Я могу вернуть все узлы, добавив totalCount в качестве брата ребер. Т.е.

{ allRandomUser { totalCount edges { node { id gender name { first last } } } } }

Ответ 4

Принятый ответ для этого прекрасно работает, просто чтобы заметить, что при использовании boundActionCreators появляется предупреждение об устаревании. Это должно быть переименовано в actions, чтобы избежать этого предупреждения.