Hi,
Thanks for the response! This was very helpful for me to find the underlying issue. There is indeed a problem with the response from the Joke API on the deployed site. The only way I could make this tutorial run on Netlify was to switch out the API for another one. This commit on my fork of the tutorial solves the issue, as seen on my live site here. I would be happy to prepare a pull request for this, updating the function names and documentation as well as simply making it work, as I have in my own private commit above.
There seems to be a compatibility issue between deployed tutorial function and the API it is calling. As far as I can tell, the Joke API endpoint itself works as expected in manual testing; see the results with cURL below. I don’t understand enough about the setup to understand what is going on, but I have a suspicion that Netlify is being blocked by the joke API site. For example, it could be that Cloudflare’s Super Bot Fight Mode is turned on for that site, blocking all requests from AWS Lambda – but that is only my suspicion with little knowledge of the internals of either system.
The following is the result of my testing, done locally with cURL to try to get to the bottom of this, since I do understand what is going on there
. To debug this, I am copying the axios GET request as a cURL request from the Chrome Dev Tools, and running it locally.
Using the default request from the tutorial reproduces the 503 at the command line:
$ curl 'https://imaginative-seahorse-cb2baf.netlify.app/.netlify/functions/async-dadjoke' \
-H 'authority: imaginative-seahorse-cb2baf.netlify.app' \
-H 'accept: */*' \
-H 'accept-language: en-US,en;q=0.9' \
-H 'referer: https://imaginative-seahorse-cb2baf.netlify.app/' \
-H 'sec-ch-ua: "Not_A Brand";v="99", "Google Chrome";v="109", "Chromium";v="109"' \
-H 'sec-ch-ua-mobile: ?1' \
-H 'sec-ch-ua-platform: "Android"' \
-H 'sec-fetch-dest: empty' \
-H 'sec-fetch-mode: cors' \
-H 'sec-fetch-site: same-origin' \
-H 'user-agent: Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Mobile Safari/537.36' \
--compressed
{"msg":"Request failed with status code 503"}
Note that the above GET request is made to the Netlify function’s URL. If you try to reproduce this now with my site’s URL, it will give a random name from the replaced API. Starting the tutorial from scratch and using that URL should, however, reproduce this result at the command line (and in the browser).
If on the other hand I replace only the URL with the original dad joke API endpoint, bypassing the Netlify function, but otherwise using the identical request, I get the full HTML response from the API:
$ curl 'https://icanhazdadjoke.com' \
-H 'authority: imaginative-seahorse-cb2baf.netlify.app' \
-H 'accept: */*' \
-H 'accept-language: en-US,en;q=0.9' \
-H 'referer: https://imaginative-seahorse-cb2baf.netlify.app/' \
-H 'sec-ch-ua: "Not_A Brand";v="99", "Google Chrome";v="109", "Chromium";v="109"' \
-H 'sec-ch-ua-mobile: ?1' \
-H 'sec-ch-ua-platform: "Android"' \
-H 'sec-fetch-dest: empty' \
-H 'sec-fetch-mode: cors' \
-H 'sec-fetch-site: same-origin' \
-H 'user-agent: Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Mobile Safari/537.36' \
--compressed
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
…
Replacing accept: */*
with 'accept: application/json
yields the expected result of a dad joke in JSON format, giving a response at the command line similar to what is expected in the website’s function call.
$ curl 'https://icanhazdadjoke.com' \
-H 'authority: imaginative-seahorse-cb2baf.netlify.app' \
-H 'accept: application/json' \
-H 'accept-language: en-US,en;q=0.9' \
-H 'referer: https://imaginative-seahorse-cb2baf.netlify.app/' \
-H 'sec-ch-ua: "Not_A Brand";v="99", "Google Chrome";v="109", "Chromium";v="109"' \
-H 'sec-ch-ua-mobile: ?1' \
-H 'sec-ch-ua-platform: "Android"' \
-H 'sec-fetch-dest: empty' \
-H 'sec-fetch-mode: cors' \
-H 'sec-fetch-site: same-origin' \
-H 'user-agent: Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Mobile Safari/537.36' \
{"id":"uPu4MRZLmrc","joke":"Want to hear a chimney joke? Got stacks of em! First one's on the house","status":200}
Now that I have swapped out the API https://icanhazdadjoke.com'
for https://random-data-api.com/api/users/random_user
and data.joke
for data.first_name
the site itself works, as of course does the local command line call. Note that the function name and URL is unchanged (as of yet) and is still called async-dadjoke
, whereas the response comes from the random fake data generator and not from the dad joke API:
$ curl 'https://imaginative-seahorse-cb2baf.netlify.app/.netlify/functions/async-dadjoke' \
-H 'authority: imaginative-seahorse-cb2baf.netlify.app' \
-H 'accept: */*' \
-H 'accept-language: en-US,en;q=0.9' \
-H 'referer: https://imaginative-seahorse-cb2baf.netlify.app/' \
-H 'sec-ch-ua: "Not_A Brand";v="99", "Google Chrome";v="109", "Chromium";v="109"' \
-H 'sec-ch-ua-mobile: ?1' \
-H 'sec-ch-ua-platform: "Android"' \
-H 'sec-fetch-dest: empty' \
-H 'sec-fetch-mode: cors' \
-H 'sec-fetch-site: same-origin' \
-H 'user-agent: Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Mobile Safari/537.36' \
--compressed
{"msg":"Hans"}
My conclusion in all of this is that the issue I encountered is not an error of my causing and also likely not transient, but likely due to a network configuration change on the side of the API in the tutorial. I find the tutorial itself very helpful and quick and a great way to quickly deploy. I will be using my own fork of this with an updated API call, and I would be happy to contribute by making an PR to the upstream repository.