I’ve been successfully using standard Netlify functions for a while now and am attempting to move away from CommonJS to ES6 import/export syntax, so I’m trying to get netlify-lambda
to build my functions from src/lambda
into ./functions
.
I’ve been following the modern netlify-lambda
guides I could find and am pretty stuck at this point. My deploy url can be found here, and when inspecting xhr requests, you can see on each load that both functions are returning a 500
error of
"FetchError: invalid json response body at https://clean-gs.myshopify.com/api/2021-04/graphql.json reason: Unexpected end of JSON input"
In dev, using netlify dev
all functions work perfectly.
However when running build
and deploy
, the same functions fail.
My netlify.toml
file looks like this:
[dev]
command = "yarn dev"
publish = "public"
functions = "functions"
port = 8888
[build]
command = "netlify-lambda build src/lambda && yarn build"
publish = "public"
functions = "functions"
I’m not using a .babelrc
file since the docs say that if one doesn’t exist it will make some assumptions and a few basic settings. I’m not doing anything fancy like TypeScript, just some very simple ES6 syntax.
Using one of the functions as an example, I call the it within Gatsby like this:
const createNewCheckout = () => {
return fetch(`/.netlify/functions/createCheckout`, {
method: 'POST',
body: JSON.stringify({}),
})
.then((res) => res.json())
.then(function (response) {
return response
})
.catch(function (error) {
console.log(error)
})
}
Here is the called function (note: data
isn’t used for this particular API call, as it just takes an empty object) and the helpers it imports from.
import { validateIncomingData, statusReturn } from './utilities'
import { queryShopify, preparePayload } from '../queries/shopifyStorefrontAPI/requestConfig'
import { CREATE_CHECKOUT } from '../queries/shopifyStorefrontAPI/checkout'
let data
let checkout
export const handler = async (event) => {
data = validateIncomingData(event)
const payload = preparePayload(CREATE_CHECKOUT, {
input: {},
})
try {
checkout = await queryShopify(payload)
const newCheckout = checkout.data.checkoutCreate.checkout
return statusReturn(200, newCheckout)
} catch (err) {
console.log(err.message)
return statusReturn(500, { error: err.message })
}
}
Which is using some helpers from:
// requestConfig.js
import fetch from 'node-fetch'
require('dotenv').config()
const {
GATSBY_SHOP_NAME,
GATSBY_SHOPIFY_STOREFRONT_TOKEN,
GATSBY_SHOPIFY_STOREFRONT_API_VERSION,
} = process.env
const SHOPIFY_GRAPHQL_URL = `https://${GATSBY_SHOP_NAME}.myshopify.com/api/${GATSBY_SHOPIFY_STOREFRONT_API_VERSION}/graphql.json`
const shopifyConfig = {
'Content-Type': 'application/json',
'X-Shopify-Storefront-Access-Token': GATSBY_SHOPIFY_STOREFRONT_TOKEN,
}
export const preparePayload = (query, v) => {
return {
query,
variables: v,
}
}
export const queryShopify = (payload) => {
return fetch(SHOPIFY_GRAPHQL_URL, {
method: 'post',
body: JSON.stringify(payload),
headers: shopifyConfig,
})
.then((res) => res.json())
.catch((error) => {
throw new Error(error)
})
}
and
// utilities.js
const headers = {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers': 'Content-Type',
'Content-Type': 'application/json',
}
export const validateIncomingData = (event) => {
if (event.httpMethod !== 'POST' || !event.body) return statusReturn(400, '')
try {
return JSON.parse(event.body)
} catch (error) {
return statusReturn(400, { error: 'Bad request body' })
}
}
export const statusReturn = (code, body) => {
return {
statusCode: code,
headers,
body: JSON.stringify(body),
}
}
and the query itself:
export const CREATE_CHECKOUT = `mutation checkoutCreate($input: CheckoutCreateInput!) {
checkoutCreate(input: $input) {
checkout {
id
}
checkoutUserErrors {
code
field
message
}
}
}`
And lastly, here is the functions part of the build command output, which to me indicates that the functions where compiled successfully (at least, I think it does, as I’m not entirely sure how to read it). Worth noting that all functions listed work correctly with netlify dev
.
$ netlify-lambda build src/lambda && yarn netlify-build
netlify-lambda: Building functions
Hash: 1c5326d16d65b7173d1a
Version: webpack 4.46.0
Time: 608ms
Built at: 06/21/2021 4:36:06 PM
Asset Size Chunks Chunk Names
addresses.js 60.5 KiB 0, 7 [emitted] addresses
createCheckout.js 60.4 KiB 1, 7 [emitted] createCheckout
customer.js 60.5 KiB 2, 7 [emitted] customer
getCheckout.js 60.4 KiB 3, 7 [emitted] getCheckout
login.js 60.9 KiB 4, 7 [emitted] login
logout.js 60.4 KiB 5, 7 [emitted] logout
orders.js 60.5 KiB 6, 7 [emitted] orders
utilities.js 1.52 KiB 7 [emitted] utilities
Entrypoint addresses = addresses.js
Entrypoint createCheckout = createCheckout.js
Entrypoint customer = customer.js
Entrypoint getCheckout = getCheckout.js
Entrypoint login = login.js
Entrypoint logout = logout.js
Entrypoint orders = orders.js
Entrypoint utilities = utilities.js
[19] ./utilities.js 1010 bytes {0} {1} {2} {3} {4} {5} {6} {7} [built]
[20] ../queries/shopifyStorefrontAPI/requestConfig.js 1.26 KiB {0} {1} {2} {3} {4} {5} {6} [built]
[21] /Users/kevin/Sites/clean-gs/node_modules/@babel/runtime/helpers/interopRequireDefault.js 225 bytes {0} {1} {2} {3} {4} {5} {6} [built]
[22] /Users/kevin/Sites/clean-gs/node_modules/axios/index.js 40 bytes {0} {1} {2} {3} {4} {5} {6} [built]
[50] /Users/kevin/Sites/clean-gs/node_modules/node-fetch/lib/index.mjs 40.1 KiB {0} {1} {2} {3} {4} {5} {6} [built]
[51] /Users/kevin/Sites/clean-gs/node_modules/dotenv/lib/main.js 3.08 KiB {0} {1} {2} {3} {4} {5} {6} [built]
[54] ../queries/shopifyStorefrontAPI/customers.js 5.25 KiB {0} {2} {4} {5} {6} [built]
[56] ../queries/shopifyStorefrontAPI/checkout.js 3.3 KiB {1} {3} [built]
[59] ./addresses.js 1020 bytes {0} [built]
[60] ./createCheckout.js 1.02 KiB {1} [built]
[61] ./customer.js 891 bytes {2} [built]
[62] ./getCheckout.js 910 bytes {3} [built]
[63] ./login.js 1.74 KiB {4} [built]
[64] ./logout.js 750 bytes {5} [built]
[65] ./orders.js 944 bytes {6} [built]
+ 51 hidden modules
What might I be missing here?
Thanks in advance!