Pass client state to a Netlify function
Disclosure: I am currently on the Product team at Netlify.
Awhile back I built a drawing idea generator, which pulls a random Unsplash image for you to draw. I wanted to add filters, so that people could refine the result by subject and/or orientation. I use a Netlify serverless function to fetch from the API, so I needed to pass client state—i.e. the user’s filter configuration—into the Netlify function. Enter query parameters!
HTML
First, people need to be able to select their filters! I added a couple <select>
elements to the markup, using Unsplash’s API values for each <option>
value:
<label for="topics">Topic</label>
<select id="topics" aria-describedby="topic-desc">
<option value="any" default>Any</option>
<option value="Jpg6Kidl-Hk">Animals</option>
<option value="rnSKDHwwYUk">Architecture</option>
...
</select>
<label for="orientation">Orientation</label>
<select id="orientation">
<option value="any" default>Any</option>
<option value="landscape">Landscape</option>
<option value="portrait">Portrait</option>
<option value="squarish">Squarish</option>
</select>
“Any” is not an accepted value in the API, but I provided that value here so I wouldn’t have to handle conditional logic for undefined filters. Unaccepted values are essentially ignored in requests to the API.
Client-side JavaScript
Per my client-side scripts, clicking on the “Try another photo” button calls a function fetchPhoto
that then invokes my photos.js
serverless function.
I updated fetchPhoto
such that it now reads the values from the filter <select>
s, and passes those to the serverless function as query parameters:
const fetchPhoto = async function (delay) {
const topicsValue = document.getElementById('topics').value,
orientationValue = document.getElementById('orientation').value,
functionWithParams = `/.netlify/functions/photos?topics=${topicsValue}&orientation=${orientationValue}`;
let response = await fetch(functionWithParams).then(handleErrors).then(response => response.json());
...
}
Serverless function
Now I can reference those in my serverless function, aka photos.js
:
exports.handler = async function (event) {
const API_KEY = process.env.UNSPLASH_API_KEY,
photoAPI = `https://api.unsplash.com/photos/random?content_filter=low&client_id=${API_KEY}`,
paramTopics = event.queryStringParameters.topics,
paramOrientation = event.queryStringParameters.orientation,
photoAPIWithParams = `${photoAPI}&topics=${paramTopics}&orientation=${paramOrientation}`,
response = await fetch(photoAPIWithParams),
data = await response.json();
return {
...
}
}
Here I’m using event.queryStringParameters
to retrieve the parameters I passed in from client-side JS. queryStringParameters
returns an object, so I’m defining a variable for each key in the params object, then appending it to the API request URL.
And voila! Sketchers can now choose a topic and/or orientation, click “try another photo”, and receive an appropriate image:
This isn’t the only way to use query parameters! You could also access them in your return
statement, if for example you wanted to print these values for the user.
To check out this update in context of the project, you can explore my code on Github.