GatsbyJS 从 Restful API 获取数据
Posted
技术标签:
【中文标题】GatsbyJS 从 Restful API 获取数据【英文标题】:GatsbyJS getting data from Restful API 【发布时间】:2018-08-24 06:08:04 【问题描述】:我是 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 的帮助,以便对用户进行过滤和排序等...... ..
您能帮我找到如何获取数据并将它们插入到gatsby-node.js
GraphQL 的示例吗?
【问题讨论】:
你不能在运行时使用 GatsbyJS 的 GraphQL 接口,只能在构建时使用。但是,如果你真的需要 GraphQL,你可以使用第三方库。 感谢您的 PM。但我不打算制作运行时 GraphQL,为了更好的解释,我检查了这个例子 github.com/gatsbyjs/gatsby/tree/master/examples/… 。 ,但这只是从内容定制到特定 API,我想构建一个类似的示例来从任何 Restful API 加载数据。我检查了 GatsbyJS 插件部分,有插件 'gatsby-source-api' 但我无法使其工作或在我的示例应用程序中运行 这些插件和示例旨在在构建时使用(不是在componentDidMount()
上,不是在fetch
上,我不确定我是否清楚地解释自己)。恐怕目前没有用于自定义 REST API 调用的通用插件。
【参考方案1】:
您可以在前端使用 react useEffect
从 API 获取数据。它完美运行,您将不再在构建时看到任何错误
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
, [])
【讨论】:
【参考方案2】:如果你想使用 GraphQL 来获取你的数据,你必须创建一个sourceNode
。关于creating a source plugin 的文档可以帮助你。
按照这些步骤可以在您的 Gatsby 项目中使用 GraphQL 查询 randomuser
数据。
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 documentation,您必须提供一个包含少量必填字段(id、parent、internal、children)的对象。
从 randomuser API 获取结果数据后,您只需创建此节点对象并将其传递给 createNode()
函数。
在这里,我们映射到您想要获得 500 个随机用户 https://randomuser.me/api/?results=500
的结果。
使用必填字段和所需字段创建userNode
对象。
您可以根据要在应用中使用的数据添加更多字段。
只需使用 Gatsby API 的 createNode()
函数创建节点即可。
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
`;
就是这样!
【讨论】:
如果我想从我的个人数据库中获取数据怎么办?我的意思是,在生产中部署应用程序我不能在 gatsby-node.js 文件中留下 urlhttps://randomuser.me/api
...它应该与设置的服务器(例如 Express)连接。我尝试在 package.json 中添加与服务器地址匹配的代理,但它不起作用
@Enrico 我会说您应该首先检查是否有 gatsby 插件可用于连接到您的数据库。否则,您可以使用 Express 创建自己的 REST api,例如 app.get("/api-url", (req, res, next) => /*get data*/ res.json(data) )
。然后你就可以在 gatsby-node.js 文件中使用你的 api url:https://myapp.com/api-url
.
@AidanGrimshaw 据我所知,gatsby-node.js
仅在 build 时执行。所以答案是否定的,这不会在运行时更新
这将是一个很棒的 Gatsby 教程,谢谢!
有人可以在 2020 年更新这个吗?我试过了,但不再支持加密 npmjs.com/package/crypto【参考方案3】:
上面给出的答案有效,除了第 2 步中的查询似乎只为我返回一个节点。我可以通过将 totalCount 添加为边的兄弟来返回所有节点。 IE。
allRandomUser
totalCount
edges
node
id
gender
name
first
last
【讨论】:
【参考方案4】:对此接受的答案效果很好,只是要注意,如果您使用boundActionCreators
,则会出现弃用警告。必须将其重命名为 actions
以避免出现此警告。
【讨论】:
嗨@pixelbreaker - 将来,这可能会更好地作为对答案的评论,而不是答案。 完全同意@Slabgorb,但仍然是+1,因为这是一个好点:) 你介意对@pixelbreaker 接受的答案发表评论吗?甚至建议修改?【参考方案5】:非常感谢,这对我来说很好,我只更改了 gastbyjs-node.js 的一小部分,因为它在使用同步和等待时出错,我想我需要更改构建过程的某些部分才能使用 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();
);
);
【讨论】:
由于节点的构建是在页面加载之前完成的(毕竟这是一个静态站点生成器),您不必担心 babel。只需确保您用于开发的节点版本以及您部署到的服务上的节点版本(Netlify?)都支持异步/等待以上是关于GatsbyJS 从 Restful API 获取数据的主要内容,如果未能解决你的问题,请参考以下文章
如何编写 GraphQL 查询以使用 GatsbyJS 从 mdx 文件中获取图像?
GatsbyJS:从 WPGraphQL 查询 Gatsby-image 以获取高级自定义字段