GatsbyJS getting data from Restful API

依然范特西╮ 提交于 2019-11-29 19:53:20

If you want to use GraphQL to fetch your data, you have to create a sourceNode. The doc about creating a source plugin could help you.

Follow these steps to be able to query randomuser data with graphQL in your Gatsby project.

1) create nodes in gatsby-node.js

In your root project folder, add this code to 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;
}

I used axios to fetch data so you will need to install it: npm install --save axios

explanation:

The goal is to create each node for each piece of data your want to use. According to the createNode documentation, you have to provide an object with few required fields (id, parent, internal, children).

Once you get the results data from the randomuser API, you just need to create this node object and pass it to the createNode() function.

Here we map to the results as you wanted to get 500 randomusers https://randomuser.me/api/?results=500.

create the userNode object with the required and wanted fields. You can add more fields depending on what data you will want to use in your app.

Just create the node with the createNode() function of the Gatsby API.

2) query your data with GraphiQL

Once you did that, run gatsby develop and go to http://localhost:8000/___graphql.

You can play with graphiQL to create your perfect query. As we named the internal.type of our node object 'RandomUser', we can query allRandomUser to get our data.

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

3) use this query in your gatsby page

In your page, for instance src/pages/index.js, use the query and display your data:

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
          }
        }
      }
    }
  }
`;

That is it !

Many thanks, this is working fine for me, I only change small parts of the gastbyjs-node.js because it makes an error when use sync & await, I think I need change some section of a build process to use babel to allow me to use sync or await.

Here is the code which works for me.

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

});

}

The answers given above work, except the query in step 2 seems to only return one node for me. I can return all nodes by adding totalCount as a sibling of edges. I.e.

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

The accepted answer for this works great, just to note that there's a deprecation warning if you use boundActionCreators. This has to be renamed to actions to avoid this warning.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!