After the previous turotial with AWS Lambda, here is now the Google Cloud Functions version.
This repository shows how to create an Google Cloud function to proxy OpenCage Geocoder API.
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, analyze requests sent to Open Cage, etc. So here is a solution to proxy the requests on your own infrastructure.
In this tutorial we will be using the serverless framework from serverless.com.
We will first need a Google account to activate the Google Cloud Plateform.
-
node, npm or yarn
-
serverless: for convenience install it globally:
$ npm install -g serverless
Assuming serverless has been setup globally, the sls and serverless commands are available.
The Serverless Framework needs access to account credentials for your Google Cloud account so that it can create and manage resources on your behalf.
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.
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
Create Project
. - Enter a Project name and select the Billing Account you created in the steps above.
- Click on
Create
to 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.
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 Manager
and selectCredentials
on the left. - Click on
Create credentials
and selectService account key
. - Select
New service account
in theService account
dropdown. - Enter a name for your
Service account name
(e.g. "opencage-function"). - Select
Project
-->Owner
as theRole
. Key type
isJSON
.- Click on
Create
to create your private key. - The so called
keyfile
will be downloaded on your machine. - Save the keyfile somewhere 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 keyfile to anything according to the goolge project name. Just remember the path you saved it to!
serverless will help up us to bootstrap the project with the command
$ serverless create --template google-nodejs --path gcloud-functions-opencage-geocoder
will output this:
Serverless: Generating boilerplate...
Serverless: Generating boilerplate in "/Users/tsamaya/work/github/tsamaya/gcloud-functions-opencage-geocoder"
_______ __
| _ .-----.----.--.--.-----.----| .-----.-----.-----.
| |___| -__| _| | | -__| _| | -__|__ --|__ --|
|____ |_____|__| \___/|_____|__| |__|_____|_____|_____|
| | | The Serverless Application Framework
| | serverless.com, v1.32.0
-------'
Serverless: Successfully generated boilerplate for template: "google-nodejs"
$ cd gcloud-functions-opencage-geocoder/
$ ls -al
will output this directory structure
.
├── .gitignore
├── index.js
├── package.json
└── serverless.yml
$ npm i -D serverless
Open up your serverless.yml
file and update the service name
service: opencage-geocoder
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:
provider:
name: google
runtime: nodejs8
project: opencage-123456
credentials: ~/.gcloud/keyfile.json
region: us-central1
Like in the example above, feel free to use node Plateform version 8 instead of 6. Google Cloud funciton are not generally available, here the region
parameter is set to us-central1
which point to the only available location while I am writing this tutorial.
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 opencage-api-client
library
$ npm i -S opencage-api-client dotenv
Serverless comes will some useful plugins, We will use the environment generator file plugin
$ npm i -D serverless-env-generator
Edit serverless.yml
file, adding this after provider:
section
plugins:
- serverless-google-cloudfunctions
- serverless-env-generator
# Plugin config goes into custom:
custom:
envFiles: #YAML files used to create .env file
- environment.yml
Use serverless env generator to create environment.yml
file
$ serverless env --attribute OCD_API_KEY --value <YOUR-OPEN-CAGE-API-KEY> --stage dev
Serverless: Successfuly set OCD_API_KEY 🎉
now let's generate a .env
file.
$ serverless env generate
Serverless: Creating .env file...
Open the index.js
file and remove its content. Replace it by :
require('dotenv').config();
const opencage = require('opencage-api-client');
exports.geocode = (request, response) => {
if (!request.query) {
response.status(400).send({error: 400, message: "Couldn't read query parameters"});
return;
}
if (typeof process.env.OCD_API_KEY === 'undefined' && typeof request.query.key === 'undefined') {
response.status(403).send({error: 403, message: 'missing API key'});
return;
}
const query = request.query;
query.key = process.env.OCD_API_KEY;
opencage.geocode(query).then(data => {
response.status(200).send(data);
}).catch(err => {
response.status(400).send({error: 400, message: err.statusText});
});
};
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
functions:
opencage:
handler: geocode
events:
- http: geocode
$ serverless deploy
Serverless: 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: Done...
Serverless: Uploading artifacts...
Serverless: Artifacts successfully uploaded...
Serverless: Updating deployment...
Serverless: Checking deployment update progress...
..........
Serverless: Done...
Service Information
service: opencage-geocoder
project: opencage-199303
stage: dev
region: us-central1
Deployed functions
opencage
https://us-central1-opencage-123456.cloudfunctions.net/geocode
- geocode
Picadilly Circus London
$ curl --request GET \
--url 'https://us-central1-opencage-123456.cloudfunctions.net/geocode?q=Picadilly%20Circus%20London'
- reverse geocode
-22.6792, 14.5272
$ curl --request GET \
--url 'https://us-central1-opencage-123456.cloudfunctions.net/geocode?q=-22.6792%2C+14.527'
I hope you enjoyed this tutorial. Feel free to reach me with whatever channel suits you for comment, issue, or coffee!
- Serverless Google Cloud Functions Guide
Licensed under the MIT License
A copy of the license is available in the repository's LICENSE file.