Google Cloud functions with OpenCage Geocoder API
First of all, why a function as a service to wrap a REST API ?
You, may, don’t want to expose your own OpenCage API Key to your client end users; you may want to analyse requests sent to OpenCage, etc.
So here is a solution to proxy the requests on your own Google Cloud infrastructure.
We will first need a Google account to activate the Google Cloud Platform. Then, we will be using the Serverless Framework from serverless.com.
- node with npm or yarn, or a js package manager or your choice
- serverless: for convenience you can install it globally
$ npm i -g serverless
Assuming serverless has been setup globally, the
serverless commands are both available from your command line.
Google — Credentials
The Serverless Framework needs access to account credentials for your Google Cloud account so that it can create and manage resources on your behalf.
Create a Google Cloud Account
We need a Billing Account with a credit card attached to use Google Cloud Functions. Here’s how to create one:
- Create the account.
- Enter the name of the Billing Account and enter your billing information. And click Submit to enable billing.
- A new Billing Account will offer you a free trial.
If necessary, a more detailed guide on creating a Billing Account can be found here.
Create a new Google Cloud Project
A Google Cloud Project is required to use Google Cloud Functions. Here’s how to create one:
- Go to the Google Cloud Console.
- There is a dropdown near the top left of the screen (near the search bar that lists your projects). Click it and select
- Enter a Project name and select the Billing Account you created in the steps above.
- Click on
Createto start the creation process.
- Wait until the Project was successfully created and Google will redirect you to your new Project.
- Verify your currently within your new Project by looking at the dropdown next to the search bar. This should mark your new Project as selected.
Enable the necessary APIs
You need to enable the following APIs so that Serverless can create the corresponding resources.
Go to the
API dashboard, select your project and enable the following APIs:
- Google Cloud Functions
- Google Cloud Deployment Manager
- Google Cloud Storage
- Stackdriver Logging
You need to create credentials Serverless can use to create resources in your Project.
- Go to the
Google Cloud API Managerand select
Credentialson the left.
- Click on
Create credentialsand select
Service account key.
New service accountin the
- Enter a name for your
Service account name(e.g. "opencage-function").
- Click on
Createto create your private key.
- The so called
keyfilewill be downloaded on your machine.
- Save the
keyfilesomewhere secure. I recommend making a folder in your home folder and putting it there; like this,
~/.gcloud/keyfile.json. You can change the file name from
keyfileto anything according to the goolge project name. Just try to remember the path you saved it to!
Create a new project from a serverless boilerplate
Serverless will help up us to bootstrap the project with the following command:
$ serverless create --template google-nodejs --path gcloud-functions-opencage-geocoder
and it will output:
Serverless: Generating boilerplate...
Serverless: Generating boilerplate in "[...]/gcloud-functions-opencage-geocoder"
| _ .-----.----.--.--.-----.----| .-----.-----.-----.
| |___| -__| _| | | -__| _| | -__|__ --|__ --|
|____ |_____|__| \___/|_____|__| |__|_____|_____|_____|
| | | The Serverless Application Framework
| | serverless.com, v1.32.0
-------' Serverless: Successfully generated boilerplate for template: "google-nodejs"
now let’s get into the folder to have a look at what’s been created:
$ cd gcloud-functions-opencage-geocoder/$ ls -althat will output this directory structure:.
Lock down the framework version
serverless as a development dependency, we will be ensure to get a compatible version, without using the global version (useful for your CI):
$ npm i -D serverless
Update the service name in
Open up your
serverless.yml file and update the service name to
Update the provider config in
Open up your
serverless.yml file and update the provider section with your Google Cloud Project id and the path to your
keyfile file. It should look something like this:
Like in the example above, feel free to use node platform version 8 instead of 6. Indeed, node 6 is getting old and big fans of
async/await will be pleased with the version 8.
Google Cloud function are not generally available, here the
region parameter is set to
We will hide OpenCage Geocoder API Key and we will set it in an environment file, so we will use the
dotenv library, then the OpenCage API request will be held by the
$ npm i -S dotenv opencage-api-client
Serverless comes will some useful plugins, We will use the environment generator file plugin. Then we can, with this plugin, generate an env file containing the OpenCage API Key. If you have different API Key for your different environments (development, staging, production), the plugin still help storing all the different value regarding the stage and deploying only the targeted stage value
$ npm i -D serverless-env-generator
serverless.yml file, adding this after
Use the serverless env generator to create a
environment.yml file. This file will hold the OpenCage Geocoder API Key.
$ serverless env --attribute OCD_API_KEY --value <YOUR-OPEN-CAGE-API-KEY> --stage devServerless: Successfuly set OCD_API_KEY 🎉
Now generate a
.env file manually.
$ serverless env generateServerless: Creating .env file...
This operation is not needed when deploying, it will be done automatically by the serverless deployment process. For security reasons, the
.env file is removed after the deployment. I recommend, for the same reasons, to avoid to store these files into the repository.
Let’s code it
index.js file and remove its content. Replace it by :
We start using dotenv to import the API Key from the
GCloud functions for NodeJS 8 uses the same interface as ExpressJS. Actually the runtime uses ExpressJS to handle the incoming requests.
The Input Query Parameters can be found in the
To proxy the API Key, we first check if a key is part of the input query string. If not we add the one from the environment variable. And in case nothing was in input query parameters and the env var was not set, we return directly an 403 error.
We do not override the API Key, if one was in as an input parameter.
Then the query is sent to the OpenCage Geocoder API endpoint via the client library. The response is sent back as is.
Edit serverless handler
As we exported
opencage from our module, we have to specify it in the serverless yml file.
opencage will be the function name,
geocode is the handler and we will use
geocode for the path
$ serverless deployServerless: Creating .env file...
Serverless: Packaging service...
Serverless: Excluding development dependencies...
Serverless: Removed .env file
Serverless: Compiling function "opencage"...
Serverless: Creating deployment...
Serverless: Checking deployment create progress...
Serverless: Uploading artifacts...
Serverless: Artifacts successfully uploaded...
Serverless: Updating deployment...
Serverless: Checking deployment update progress...
region: us-central1Deployed functions
The last line of the deployments gives us the HTTP endpoint.
Now we can test our new endpoint with geocoding and reverse geocoding operations:
Piccadilly Circus London
$ curl --request GET \
- Reverse Geocode
$ curl --request GET \
To go further
If you look at the associated repository on Github, you will find some unit tests.
Cloud Functions are at the General Availability release level since the 24th of July 2018. But Node.js 8 is still in beta. And Cloud Functions are available only in the following regions for now:
I hope you enjoyed this tutorial. Feel free to reach me with whatever channel suits you for comments, issue, or coffee!
- Serverless Google Cloud Functions Guide
- Github repository : https://github.com/tsamaya/gcloud-functions-opencage-geocoder
- The same type of tutorial with an AWS Lambda