How I Found the Best Pizza Restaurant 🍕 in 13,000 Cities using Cloud Tasks, Cloud Functions, and Google Maps 🗺️

Grant Timmerman
Nov 4 · 5 min read
Each pin marks the best pizza restaurant in that city/town. Yes, even the ones seemingly in the water (islands).

Have you ever wondered, where to find the best pizza in a new city? Who doesn’t like a hot slice of pepperoni pizza? (Or perhaps a square of gluten-free pesto pizza with roma tomatoes?)

Google Cloud offers some incredible elastically-scaled technology for distributed computing. The best part about it, is that you don’t have to think about how the technical infrastructure works underneath the hood.

Focus on your code, not your infrastructure.

It Started with Two Questions

  • How can I show the scale of Google Cloud Tasks?
  • How do I find the best pizza slice around the world programmatically?

In this section, we’ll write a script that creates multiple tasks that targets a Google Cloud Function. To make things interesting, we’ll use the Google Maps API and search for the best pizza in 13,000 cities around the world. We’ll store the results in Firestore. To visualize our data, a simple web page with an embedded Google Map shows a pin for each pizza restaurant.

Here’s an architectural diagram of our application:

Cloud Tasks | Cloud Functions | Maps APIs | Cloud Firestore

On the left, we have Cloud Tasks that queues up 13,000 HTTP requests.

Why would we want to use Cloud Tasks here? Perhaps we want to rate limit our calls to our API, or be able to pause requests to our API, or not call the API for duplicate requests. Here, it is handy to pre-load our 13,000 URL targets.

This use-case is great for Cloud Tasks.

In the center of the diagram, we have a Google Cloud Function (written in Node). This Cloud Function is our central entry point for:

  • Web browser requests to render the Google Map Web UI
  • API requests to get Google Maps API places data stored in Firestore

This application is powered by the Node Functions Framework which enables local development of Google Cloud Functions.

On the right, we use the Maps Geocoding API to find the lat/lng of our query and the Maps Place Search API to find the best pizza restaurant near that lat/lng. Results are stored in Firestore (on the bottom).

Set up our Application

First, some setup. Our demo shows an end-to-end app that collects data from Google Maps, stores in Firestore, and displays the data with a public URL with Cloud Functions. We need to set up the storage and compute. It’s fairly simple, but takes a few minutes.

Clone the repo github.com/GoogleCloudPlatform/cloud-tasks-pizza-map:

git clone git@github.com:GoogleCloudPlatform/cloud-tasks-pizza-map.git

We can use this special link to enable all APIs for our project:

  • Cloud Tasks API: A queue that features deduplicatication, play/pause, retry, and other configuration
  • Maps Places API: Find pizza restaurants
  • Maps Geocoding API: Find lat/lng of restaurants given a “place id”
  • Firestore API: Store data

Set up a Firestore database for storing our Google Maps API data with these configs:

  • Mode: Test mode
  • Collection: tasks-pizza

Create an API key for Maps here:

Click this button to create an API key. (Link)

Save the key in a .env file that looks like this:

KEY=AIzaSyDh7gKIvLzFA0q_ICfkO8ryvEMm3Nrde-c

Run our Application Locally

To test our server locally, follow these instructions using our KEY from the previous step:

npm i
KEY=... npm start

We’ll see the CLI outputs useful information about our app:

> tasks-pizza@1.0.0 start /github/GoogleCloudPlatform/cloud-tasks-pizza-map
> FUNCTION_SOURCE=src npx @google-cloud/functions-framework
Serving function...
Function: function
URL: http://localhost:8080/

At localhost:8080, we’ll see our routes for our app (I’ve annotated here):

[
"/tasks/start", // starts creating all Cloud Tasks
"/tasks/listnames", // lists Tasks names
"/maps/add", // adds restaurant data to the database
"/maps/get", // gets restaurant data
"/maps/listnames", // lists names of cities from a gist
"/maps/key", // prints the GMP API key for the front-end
"/target", // our Cloud Tasks target (same as /maps/add)
"/web" // our web UI for displaying our map
]

You’re running this Google Cloud Function locally! Great! Now how do we get those pins to show up on the Map? 🤔


There are some order of operations here to run the demo:

  • Load the Cloud Tasks queue by running /tasks/start. This will take a few minutes as it creates ~13,000 unique Tasks for every city in the world.
  • Ensure the Cloud Tasks queue is unpaused by going to https://console.cloud.google.com/cloudtasks. Unpausing the queue will populate our Firestore database.
  • Open our frontend at localhost:8080/web to visualize the data in our database.

At /web, we’ll see pins drop as the frontend UI reads our database records.

Pins dropping as our frontend loads our results. Each pin is a real 🍕restaurant.

Note: We purposefully slow down the frontend to create this animation, which lasts ~20 minutes to load all 13k pins.

For example, in Midtown, Manhattan, we have a link to Joe’s Pizza with around 7k ratings averaging of 4.5 ⭐s.

Joe’s Pizza at Midtown, Manhattan, New York.

Those pins that seem to be in the ocean are not mistakes. There are lots of islands around the world with pizza:

Boa Pizza on Cape Verde (4.3 ⭐s) delivers to the beach if requested. Also “good for kids”.

I’ve had hours of fun exploring the world of pizza on Google Maps using this app and could talk about the most unique pizza restaurants in a whole essay. But let’s go back to developing our app.

Deploy our Application

The great thing about our demo is that there is no special configuration needed to deploy our application to production.

It is easy to change our demo such that we aren’t using localhost, but rather, using a real https URL on Google Cloud.

We can simply run npm run deploy, which really runs this command:

gcloud functions deploy tasks-pizza
\ --trigger-http
\ --runtime=nodejs10
\ --env-vars-file=.env.yaml

In ~30 seconds, you’ll get a public URL like this:

https://us-central1-my-project.cloudfunctions.net/tasks-pizza

Note: That’s not a real URL.

If you liked this blogpost, check out these resources:

Thanks to this app, I won’t go hungry 😋🍕

Google Cloud Platform - Community

A collection of technical articles published or curated by Google Cloud Platform Developer Advocates. The views expressed are those of the authors and don't necessarily reflect those of Google.

Grant Timmerman

Written by

Google • Explorer

Google Cloud Platform - Community

A collection of technical articles published or curated by Google Cloud Platform Developer Advocates. The views expressed are those of the authors and don't necessarily reflect those of Google.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade