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?


person AJ-    schedule 15.03.2018    source источник
comment
Вы не можете использовать интерфейс GraphQL GatsbyJS во время выполнения, только во время сборки. Однако вы можете использовать для этого стороннюю библиотеку, если вам действительно нужен GraphQL.   -  person Miguel Calderón    schedule 15.03.2018
comment
Спасибо за ваш личный кабинет. но я не собираюсь создавать среду выполнения GraphQL, для лучшего объяснения я проверяю этот пример github.com/gatsbyjs/gatsby/tree/master/examples/. , но это настраивается только для конкретного API из контентного, здесь я хотел бы построить аналогичный пример для загрузки данных из любого Restful API. Я проверяю раздел плагинов GatsbyJS, есть плагин gatsby-source-api, но я не мог заставить его работать или запускаться в моем примере приложения   -  person AJ-    schedule 15.03.2018
comment
Эти плагины и примеры предназначены для использования во время сборки (не в componentDidMount(), не в fetch, я не уверен, что я четко объяснюсь). Боюсь, что на данный момент нет универсального плагина, который можно было бы использовать для настраиваемых вызовов REST API.   -  person Miguel Calderón    schedule 15.03.2018


Ответы (5)


Вы можете получать данные в интерфейсе из API, используя response useEffect. Он работает отлично, и вы больше не увидите никаких ошибок во время сборки.

 const [starsCount, setStarsCount] = useState(0)
  useEffect(() => {
    // get data from GitHub api
    fetch(`https://api.github.com/repos/gatsbyjs/gatsby`)
      .then(response => response.json()) // parse JSON from request
      .then(resultData => {
        setStarsCount(resultData.stargazers_count)
      }) // set data for the number of stars
  }, [])
person Ericgit    schedule 07.07.2021

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

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

1) Создайте узлы в gatsby-node.js

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

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

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

  // 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, вы должны предоставить объекту несколько обязательных полей (идентификатор, родительский, внутренний, дочерний).

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

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

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

Просто создайте узел с функцией createNode() API Гэтсби.

2) Запросите свои данные с помощью GraphQL

После этого запустите gatsby develop и перейдите к http://localhost:8000/___graphql.

Вы можете поиграть с 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
          }
        }
      }
    }
  }
`;

Вот и все!

person Nenu    schedule 16.03.2018
comment
Что, если я хочу получить данные из моей личной базы данных? Я имею в виду, что при развертывании приложения в производственной среде я не могу оставить в файле gatsby-node.js URL-адрес _1 _... он должен быть связан с настроенным сервером (например, Express). Я попытался добавить прокси в package.json, соответствующий адресу сервера, но это не сработает. - person Enrico; 06.11.2018
comment
@Enrico Я бы сказал, вам следует сначала проверить, доступен ли плагин gatsby для подключения к вашей базе данных. В противном случае вы можете создать свой собственный REST api с помощью Express, что-то вроде app.get("/api-url", (req, res, next) => { /*get data*/ res.json(data) }). После этого вы сможете использовать свои URL-адреса API в файле gatsby-node.js: https://myapp.com/api-url. - person Nenu; 08.11.2018
comment
@AidanGrimshaw Насколько мне известно, gatsby-node.js выполняется только во время сборки. Таким образом, ответ будет отрицательным, это не будет обновляться во время выполнения. - person Nenu; 25.06.2019
comment
Это было бы отличным учебником по Гэтсби, спасибо! - person Robin Métral; 03.11.2019
comment
Может кто-нибудь обновить это до 2020 года? Я пробовал, но криптовалюта больше не поддерживается npmjs.com/package/crypto - person Richard Reis; 06.01.2020
comment
Могу ли я использовать это и для запроса POST? - person Md.Abdul Halim Rafi; 02.02.2020
comment
@RichardReis, у меня сработало как есть - person dawn; 11.12.2020

Большое спасибо, у меня все работает нормально, я изменяю только небольшие части gastbyjs-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();
});

});

}
person AJ-    schedule 19.03.2018
comment
Поскольку создание узлов выполняется до загрузки страницы (в конце концов, это генератор статического сайта), вам не стоит беспокоиться о babel. Просто убедитесь, что версия узла, который вы используете для разработки, и версия узла в службе, которую вы развертываете (Netlify?), Поддерживают async / await. - person Roy; 31.10.2018

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

person pixelbreaker    schedule 16.08.2019
comment
Привет @pixelbreaker - в будущем это, вероятно, будет лучше в качестве комментария к ответу, чем ответа. - person Slabgorb; 16.08.2019
comment
Полностью согласен с @Slabgorb, но все же +1, потому что это хороший момент :) Не могли бы вы прокомментировать это в принятом ответе @pixelbreaker? Или даже предложить отредактировать? - person Robin Métral; 03.11.2019

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

{
  allRandomUser {
    totalCount
    edges {
      node {
        id
        gender
        name {
          first
          last
        }
      }
    }
  }
}
person scaganoff    schedule 20.10.2018