Creating a Source Plugin
In this section, we will learn to how to create a source plugin to pull data from REST API that exposes pokemon data: https://pokemon-json.herokuapp.com/.
The lesson you learnt here is transerable to any REST API that you created yourself or provided by any third-party.
Create a Local Plugin
bash
mkdir -p plugins/gatsby-source-pokemoncd plugins/gatsby-source-pokemonnpm init --ytouch gatsby-node.js
bash
mkdir -p plugins/gatsby-source-pokemoncd plugins/gatsby-source-pokemonnpm init --ytouch gatsby-node.js
plugins/gatsby-source-pokemon/gatsby-node.jsjs
exports.sourceNodes = async ({ reporter }, configOptions) => {reporter.info(`In gatsby-source-pokemon with the following configOptions`);reporter.info(JSON.stringify(configOptions));};
plugins/gatsby-source-pokemon/gatsby-node.jsjs
exports.sourceNodes = async ({ reporter }, configOptions) => {reporter.info(`In gatsby-source-pokemon with the following configOptions`);reporter.info(JSON.stringify(configOptions));};
gatsby-config.jsjs
module.exports = {plugins: ['gatsby-plugin-sass',{resolve: 'gatsby-source-filesystem',options: {name: 'src',path: `${__dirname}/src`,},},{resolve: 'gatsby-source-filesystem',options: {name: 'blogs',path: `${__dirname}/blogs`,},},{resolve: 'gatsby-transformer-remark',options: {plugins: [{resolve: 'gatsby-remark-images',options: {maxWidth: 700,},},],},},'gatsby-plugin-sharp','gatsby-transfomer-sharp',{resolve: 'gatsby-source-instagram',options: {username: 'malcolm__kee',},},{resolve: 'gatsby-source-pokemon',options: {x: 'y',},},],};
gatsby-config.jsjs
module.exports = {plugins: ['gatsby-plugin-sass',{resolve: 'gatsby-source-filesystem',options: {name: 'src',path: `${__dirname}/src`,},},{resolve: 'gatsby-source-filesystem',options: {name: 'blogs',path: `${__dirname}/blogs`,},},{resolve: 'gatsby-transformer-remark',options: {plugins: [{resolve: 'gatsby-remark-images',options: {maxWidth: 700,},},],},},'gatsby-plugin-sharp','gatsby-transfomer-sharp',{resolve: 'gatsby-source-instagram',options: {username: 'malcolm__kee',},},{resolve: 'gatsby-source-pokemon',options: {x: 'y',},},],};
bash
npm start
bash
npm start
Create a Source Plugin
Retrive data from API
bash
cd plugins/gatsby-source-pokemonnpm i node-fetch
bash
cd plugins/gatsby-source-pokemonnpm i node-fetch
plugins/gatsby-source-pokemon/gatsby-node.jsjs
const fetch = require('node-fetch');exports.sourceNodes = async ({ reporter }, configOptions) => {reporter.info(`In gatsby-source-pokemon with the following configOptions`);reporter.info(JSON.stringify(configOptions));const pokemons = await fetch('https://pokemon-json.herokuapp.com/api/pokedex').then((res) =>res.json());console.log(pokemons);};
plugins/gatsby-source-pokemon/gatsby-node.jsjs
const fetch = require('node-fetch');exports.sourceNodes = async ({ reporter }, configOptions) => {reporter.info(`In gatsby-source-pokemon with the following configOptions`);reporter.info(JSON.stringify(configOptions));const pokemons = await fetch('https://pokemon-json.herokuapp.com/api/pokedex').then((res) =>res.json());console.log(pokemons);};
Create a data node
plugins/gatsby-source-pokemon/gatsby-node.jsjs
const fetch = require('node-fetch');exports.sourceNodes = async ({ actions, createNodeId, createContentDigest, reporter },configOptions) => {const { createNode } = actions;reporter.info(`In gatsby-source-pokemon with the following configOptions`);reporter.info(JSON.stringify(configOptions));const pokemons = await fetch('https://pokemon-json.herokuapp.com/api/pokedex').then((res) =>res.json());pokemons.forEach((pokemon) => {const nodeId = createNodeId(`pokemon-${pokemon.id}`);const nodeContent = JSON.stringify(pokemon);const nodeData = Object.assign({}, pokemon, {id: nodeId,parent: null,children: [],internal: {type: 'Pokemon',content: nodeContent,contentDigest: createContentDigest(pokemon),},});createNode(nodeData);});};
plugins/gatsby-source-pokemon/gatsby-node.jsjs
const fetch = require('node-fetch');exports.sourceNodes = async ({ actions, createNodeId, createContentDigest, reporter },configOptions) => {const { createNode } = actions;reporter.info(`In gatsby-source-pokemon with the following configOptions`);reporter.info(JSON.stringify(configOptions));const pokemons = await fetch('https://pokemon-json.herokuapp.com/api/pokedex').then((res) =>res.json());pokemons.forEach((pokemon) => {const nodeId = createNodeId(`pokemon-${pokemon.id}`);const nodeContent = JSON.stringify(pokemon);const nodeData = Object.assign({}, pokemon, {id: nodeId,parent: null,children: [],internal: {type: 'Pokemon',content: nodeContent,contentDigest: createContentDigest(pokemon),},});createNode(nodeData);});};
You can now query the pokemon data with GraphQL in Gatsby:
graphql
{allPokemon {edges {node {idname {english}base {HPAttack}imagesprite}}}}
graphql
{allPokemon {edges {node {idname {english}base {HPAttack}imagesprite}}}}
Create a page to display the data
bash
touch src/pages/pokemons.js
bash
touch src/pages/pokemons.js
src/pages/pokemons.jsjsx
import { graphql } from 'gatsby';import * as React from 'react';import { Layout } from '../components/layout';const AllPokemonsPage = ({ data }) => {const pokemons = data.allPokemon.edges.map(({ node }) => node);return (<Layout><table><tbody>{pokemons.map((pokemon) => (<tr key={pokemon.id}><td><img src={pokemon.sprite} alt={pokemon.name.english} /></td><td><p>{pokemon.name.english}</p><p>Base HP: {pokemon.base.HP}</p><p>Base Atk: {pokemon.base.Attack}</p></td><td><img src={pokemon.image} alt={pokemon.name.english} /></td></tr>))}</tbody></table></Layout>);};export default AllPokemonsPage;export const query = graphql`query AllPokemonQuery {allPokemon {edges {node {idname {english}base {HPAttack}imagesprite}}}}`;
src/pages/pokemons.jsjsx
import { graphql } from 'gatsby';import * as React from 'react';import { Layout } from '../components/layout';const AllPokemonsPage = ({ data }) => {const pokemons = data.allPokemon.edges.map(({ node }) => node);return (<Layout><table><tbody>{pokemons.map((pokemon) => (<tr key={pokemon.id}><td><img src={pokemon.sprite} alt={pokemon.name.english} /></td><td><p>{pokemon.name.english}</p><p>Base HP: {pokemon.base.HP}</p><p>Base Atk: {pokemon.base.Attack}</p></td><td><img src={pokemon.image} alt={pokemon.name.english} /></td></tr>))}</tbody></table></Layout>);};export default AllPokemonsPage;export const query = graphql`query AllPokemonQuery {allPokemon {edges {node {idname {english}base {HPAttack}imagesprite}}}}`;