Ошибка gatsby-source-graphql и GraphQL Shopify Admin API - PullRequest
1 голос
/ 12 мая 2019

Репо с этим кодом можно найти ЗДЕСЬ

Я работаю над поиском и объединением данных из API-интерфейсов Shopify Storefront и GraphQL Admin в Gatsby. Для получения API-интерфейса Storefront я использую gatsby-source-shopify , хотя мне не удалось найти плагин исходного кода для Shopify Admin API , и в итоге я использовал gatsby-source-graphql.

Я создал личное приложение Shopify , предоставил все разрешения и смог получить данные, используя пример скручивания из документации API Shopify GraphQL Admin.

curl -X POST \
"https://shop-name.myshopify.com/admin/api/2019-04/graphql.json" \
-H "Content-Type: application/graphql" \
-H "X-Shopify-Access-Token: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
-d '
{
  shop {
    name
  }
}
'

Вывод:

{"data":{"shop":{"name":"Shop Name"}},"extensions":{"cost":{"requestedQueryCost":1,"actualQueryCost":1,"throttleStatus":{"maximumAvailable":1000.0,"currentlyAvailable":999,"restoreRate":50.0}}}}

Сообщение об ошибке:

success open and validate gatsby-configs — 0.007 s
success load plugins — 0.345 s
success onPreInit — 0.005 s
success initialize cache — 0.015 s
success copy gatsby files — 0.068 s
success onPreBootstrap — 0.006 s
error Plugin gatsby-source-graphql returned an error


  Error: Parse error on "operationName" (STRING) at [1, 2]


gatsby-source-shopify/sandbox starting to fetch data from Shopify

gatsby-source-shopify/sandbox fetched and processed productTypes: 287.590ms

gatsby-source-shopify/sandbox fetched and processed policies: 297.440ms

gatsby-source-shopify/sandbox fetched and processed blogs: 302.418ms

gatsby-source-shopify/sandbox fetched and processed articles: 344.917ms

gatsby-source-shopify/sandbox fetched and processed collections: 8603.841ms


gatsby-source-shopify/sandbox fetched and processed products: 20362.561ms

gatsby-source-shopify/sandbox finished fetching data from Shopify: 20369.525ms
warning The gatsby-source-graphql plugin has generated no Gatsby nodes. Do you need it?
success source and transform nodes — 21.169 s
warning Multiple node fields resolve to the same GraphQL field `ShopifyArticle.blog` - [`blog`, `blog___NODE`]. Gatsby will use `blog___NODE`.
warning Multiple node fields resolve to the same GraphQL field `ShopifyCollection.products` - [`products`, `products___NODE`]. Gatsby will use `products___NODE`.
warning Multiple node fields resolve to the same GraphQL field `ShopifyProduct.options` - [`options`, `options___NODE`]. Gatsby will use `options___NODE`.
warning Multiple node fields resolve to the same GraphQL field `ShopifyProduct.variants` - [`variants`, `variants___NODE`]. Gatsby will use `variants___NODE`.
success building schema — 0.283 s
success createPages — 0.000 s
success createPagesStatefully — 0.042 s
success onPreExtractQueries — 0.005 s
success update schema — 0.019 s
success extract queries from components — 0.098 s
success run static queries — 0.021 s — 2/2 96.96 queries/second
success run page queries — 0.014 s — 4/4 301.32 queries/second
success write out page data — 0.012 s
success write out redirect data — 0.001 s
success Build manifest and related icons — 0.104 s
success onPostBootstrap — 0.106 s

info bootstrap finished - 23.946 s

 WARNING  Compiled with 1 warnings                                                         6:04:43 PM

Module Warning (from ./node_modules/eslint-loader/index.js):

/Users/skok/dev/gatsby-shopify-starter/src/components/collections.js
  2:10  warning  'useStaticQuery' is defined but never used  no-unused-vars
  2:26  warning  'graphql' is defined but never used         no-unused-vars

✖ 2 problems (0 errors, 2 warnings)


You may use special comments to disable some warnings.
Use // eslint-disable-next-line to ignore the next line.
Use /* eslint-disable */ to ignore all warnings in a file.

You can now view gatsby-shopify in the browser.

  http://localhost:8000/

View GraphiQL, an in-browser IDE, to explore your site's data and schema

  http://localhost:8000/___graphql

Note that the development build is not optimized.
To create a production build, use npm run build

warning ⚠ 「wdm」:
info ℹ 「wdm」: Compiled with warnings.
 WAIT  Compiling...                                                                        6:04:43 PM

info ℹ 「wdm」: Compiling...
 WARNING  Compiled with 1 warnings                                                         6:04:43 PM

Module Warning (from ./node_modules/eslint-loader/index.js):

/Users/skok/dev/gatsby-shopify-starter/src/components/collections.js
  2:10  warning  'useStaticQuery' is defined but never used  no-unused-vars
  2:26  warning  'graphql' is defined but never used         no-unused-vars

✖ 2 problems (0 errors, 2 warnings)


You may use special comments to disable some warnings.
Use // eslint-disable-next-line to ignore the next line.
Use /* eslint-disable */ to ignore all warnings in a file.
warning ⚠ 「wdm」:
info ℹ 「wdm」: Compiled with warnings.

gatsby-config.js

require('dotenv').config({
  path: `.env.${process.env.NODE_ENV}`
});

module.exports = {
  siteMetadata: {
    title: `Gatsby Shopify`,
    description: `Gatsby Shopify Starter.`,
    author: `@iamskok`,
  },
  plugins: [
    `gatsby-plugin-react-helmet`,
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `images`,
        path: `${__dirname}/src/images`,
      },
    },
    `gatsby-transformer-sharp`,
    `gatsby-plugin-sharp`,
    {
      resolve: "gatsby-source-graphql",
      options: {
        // This type will contain remote schema Query type
        typeName: "ShopifyAdmin",
        // This is field under which it's accessible
        fieldName: "admin",
        // Url to query from
        url: `https://${process.env.SHOP_NAME}.myshopify.com/admin/api/2019-04/graphql.json`,
        headers: {
          // Learn about environment variables: https://gatsby.dev/env-vars
          'X-Shopify-Access-Token': `${process.env.ADMIN_PASSWORD}`,
          'Content-Type': 'application/graphql'
        },
        fetchOptions: {
          method: 'POST'
        },
        refetchInterval: 60
      },
    },
    {
      resolve: `gatsby-source-shopify`,
      options: {
        // The domain name of your Shopify shop. This is required.
        // Example: 'gatsby-source-shopify-test-shop' if your Shopify address is
        // 'gatsby-source-shopify-test-shop.myshopify.com'.
        shopName: process.env.SHOP_NAME,

        // An API access token to your Shopify shop. This is required.
        // You can generate an access token in the "Manage private apps" section
        // of your shop's Apps settings. In the Storefront API section, be sure
        // to select "Allow this app to access your storefront data using the
        // Storefront API".
        // See: https://help.shopify.com/api/custom-storefronts/storefront-api/getting-started#authentication
        accessToken: process.env.STOREFRONT_ACCESS_TOKEN,

        // Set verbose to true to display a verbose output on `npm run develop`
        // or `npm run build`. This prints which nodes are being fetched and how
        // much time was required to fetch and process the data.
        // Defaults to true.
        verbose: true,
      },
    },
    {
      resolve: `gatsby-plugin-manifest`,
      options: {
        name: `gatsby-starter-default`,
        short_name: `starter`,
        start_url: `/`,
        background_color: `#663399`,
        theme_color: `#663399`,
        display: `minimal-ui`,
        icon: `src/images/gatsby-icon.png`, // This path is relative to the root of the site.
      },
    },
  ],
}

./src/collections.js

import React from 'react'
import { useStaticQuery, graphql } from 'gatsby'

const Collections = () => {
  const storefrontData = useStaticQuery(
    graphql`
      query {
        allShopifyCollection {
          edges {
            node {
              id
              description
              descriptionHtml
              handle
              image {
                altText
                id
                src
                localFile {
                  childImageSharp {
                    fluid(maxWidth: 910) {
                      ...GatsbyImageSharpFluid_withWebp_tracedSVG
                    }
                  }
                }
              }
              products {
                id
                handle
                title
              }
              title
              updatedAt
            }
          }
        }
      }
    `
  )

  const adminData = useStaticQuery(
    graphql`
      query {
        admin {
          shop {
            name
          }
        }
      }
    `
  )

  console.log('storefront data:', JSON.stringify(storefrontData));
  console.log('admin data:', JSON.stringify(adminData));

  return (
    <div className="collections">
      <h2>Collections</h2>
    </div>
  )
}

export default Collections

index.js:

import React from 'react'
import Layout from '../components/layout'
import Collections from '../components/collections'

const IndexPage = () => (
  <Layout>
    <h1>Shopify</h1>
    <Collections />
  </Layout>
)

export default IndexPage

package.json

{
  "name": "gatsby-shopify",
  "private": true,
  "description": "Gatsby Shopify Starter",
  "version": "0.1.0",
  "author": "Vladimir Skok <skok@vova.io>",
  "dependencies": {
    "gatsby": "^2.4.2",
    "gatsby-image": "^2.0.41",
    "gatsby-plugin-manifest": "^2.1.1",
    "gatsby-plugin-offline": "^2.1.0",
    "gatsby-plugin-react-helmet": "^3.0.12",
    "gatsby-plugin-sharp": "^2.0.36",
    "gatsby-source-filesystem": "^2.0.33",
    "gatsby-source-graphql": "^2.0.18",
    "gatsby-source-shopify": "^2.0.28",
    "gatsby-transformer-sharp": "^2.1.19",
    "prop-types": "^15.7.2",
    "react": "^16.8.6",
    "react-dom": "^16.8.6",
    "react-helmet": "^5.2.1"
  },
  "devDependencies": {
    "prettier": "^1.17.0"
  },
  "keywords": [
    "gatsby"
  ],
  "license": "MIT",
  "scripts": {
    "build": "gatsby build",
    "develop": "gatsby develop",
    "format": "prettier --write src/**/*.{js,jsx}",
    "start": "npm run develop",
    "serve": "gatsby serve",
    "test": "echo \"Write tests! -> https://gatsby.dev/unit-testing\""
  },
  "repository": {
    "type": "git",
    "url": "https://github.com/iamskok/gatsby-shopify-starter"
  },
  "bugs": {
    "url": "https://github.com/iamskok/gatsby-shopify-starter/issues"
  }
}

Ожидаемый результат - выполнить успешный запрос GraphQL к API-интерфейсу Shopify. Фактический результат - ошибка сервера с кодом состояния 400.

Ответы [ 2 ]

0 голосов
/ 12 мая 2019

Ваша настройка gatsby-source-graphql отличается от команды curl в следующей настройке:

  • Метод POST HTTP
  • Content-Type: application/graphql заголовок

Чтобы соответствовать команде curl, вы можете попробовать следующую настройку:

    {
      resolve: "gatsby-source-graphql",
      options: {
        typeName: "ShopifyAdmin",
        fieldName: "admin",
        url: `https://${process.env.SHOP_NAME}.myshopify.com/admin/api/2019-04/orders.json`,
        headers: {
          'X-Shopify-Access-Token': `${process.env.ADMIN_PASSWORD}`,
   +      'Content-Type': 'application/graphql',
        },
   +    fetchOptions: {
   +      method: 'POST'
   +    }
        refetchInterval: 60
      },
    },

0 голосов
/ 12 мая 2019

У вас есть несколько проблем здесь.

Сначала вам нужно пройти X-Shopify-Storefront-Access-Token, а не X-Shopify-Access-Token.(если вы действительно используете частное приложение)

Тогда вам нужно запросить /api/2019-04/graphql не /admin/api/2019-04/graphql.json".

Пожалуйста, обратитесь к этому документу: https://help.shopify.com/en/api/custom-storefronts/storefront-api/getting-started#accessing-the-storefront-api-graphql-endpoint

...