<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Akshay Milmile</title>
    <description>The latest articles on DEV Community by Akshay Milmile (@itachiredhair).</description>
    <link>https://dev.to/itachiredhair</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F276804%2F39120436-bc66-4d82-a515-db0591b7922f.jpeg</url>
      <title>DEV Community: Akshay Milmile</title>
      <link>https://dev.to/itachiredhair</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/itachiredhair"/>
    <language>en</language>
    <item>
      <title>Downloading MLFlow model from Databricks and Serving with Docker</title>
      <dc:creator>Akshay Milmile</dc:creator>
      <pubDate>Mon, 28 Dec 2020 19:46:30 +0000</pubDate>
      <link>https://dev.to/itachiredhair/downloading-mlflow-model-from-databricks-and-serving-with-docker-38ip</link>
      <guid>https://dev.to/itachiredhair/downloading-mlflow-model-from-databricks-and-serving-with-docker-38ip</guid>
      <description>&lt;p&gt;If you are using Managed MLFlow in Databricks Workspace to train and save your models and can't figure out how to download and serve the model outside the Databricks environment using Docker, you are in luck!&lt;/p&gt;

&lt;p&gt;In this article, I will touch upon the following points:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Downloading MLFlow model from Databricks workspace model registry&lt;/li&gt;
&lt;li&gt;Packaging downloaded model and serve it in a container using Docker&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Downloading MLFlow model from Databricks workspace
&lt;/h1&gt;

&lt;p&gt;Databricks provides the managed version of MLFlow to write our experiments in a notebook and register the model in the provided MLFlow registry.&lt;/p&gt;

&lt;p&gt;We'll use MLFlow's Python API to download a model.&lt;/p&gt;

&lt;p&gt;To download a model from Databricks workspace you need to do two things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Set MLFlow tracking URI to &lt;code&gt;databricks&lt;/code&gt; using &lt;a href="https://www.mlflow.org/docs/latest/python_api/mlflow.html#mlflow.set_tracking_uri"&gt;python API&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Setup databricks authentication. I prefer authenticating by setting the following environment variables, you can also use &lt;a href="https://docs.databricks.com/dev-tools/cli/index.html#set-up-authentication"&gt;databricks CLI&lt;/a&gt; to authenticate:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DATABRICKS_HOST
DATABRICKS_TOKEN
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's a basic code snippet to download a model from Databricks workspace model registry:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;os&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;mlflow&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;mlflow.store.artifact.models_artifact_repo&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ModelsArtifactRepository&lt;/span&gt;

&lt;span class="n"&gt;model_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"example-model-name"&lt;/span&gt;
&lt;span class="n"&gt;model_stage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Staging"&lt;/span&gt;  &lt;span class="c1"&gt;# Should be either 'Staging' or 'Production'
&lt;/span&gt;
&lt;span class="n"&gt;mlflow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_tracking_uri&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"databricks"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;makedirs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"model"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;exist_ok&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;local_path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ModelsArtifactRepository&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s"&gt;'models:/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;model_name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;model_stage&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;download_artifacts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dst_path&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"model"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;model_stage&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; Model &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;model_name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; is downloaded at &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;local_path&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Running above python script will download an ML model in the &lt;code&gt;model&lt;/code&gt; directory.&lt;/p&gt;

&lt;h1&gt;
  
  
  Containerizing MLFlow model serving with Docker
&lt;/h1&gt;

&lt;p&gt;The next step is to package this downloaded model in a docker image and serve a model when you run the image.&lt;/p&gt;

&lt;p&gt;Here's a basic Dockerfile to do the same:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; continuumio/miniconda3&lt;/span&gt;

&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; MLFLOW_HOME /opt/mlflow&lt;/span&gt;
&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; MLFLOW_VERSION 1.12.1&lt;/span&gt;
&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; PORT 5000&lt;/span&gt;

&lt;span class="k"&gt;RUN &lt;/span&gt;conda &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; conda-forge &lt;span class="nv"&gt;mlflow&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;MLFLOW_VERSION&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; model/ ${MLFLOW_HOME}/model&lt;/span&gt;

&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; ${MLFLOW_HOME}&lt;/span&gt;

&lt;span class="k"&gt;RUN &lt;/span&gt;mlflow models prepare-env &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;MLFLOW_HOME&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;/model

&lt;span class="k"&gt;RUN &lt;/span&gt;useradd &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;MLFLOW_HOME&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt; mlflow
&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="nb"&gt;chown &lt;/span&gt;mlflow: &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;MLFLOW_HOME&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;USER&lt;/span&gt;&lt;span class="s"&gt; mlflow&lt;/span&gt;

&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; mlflow models serve -m ${MLFLOW_HOME}/model --host 0.0.0.0 --port ${PORT}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Few things to note from &lt;code&gt;Dockerfile&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We are using base image &lt;code&gt;continuumio/miniconda3&lt;/code&gt; because mlflow by default uses conda to install it's dependencies while preparing environment for the model serving&lt;/li&gt;
&lt;li&gt;We are using non-root &lt;code&gt;mlflow&lt;/code&gt; user with limited permissions to run &lt;code&gt;mlflow models serve&lt;/code&gt; process in a secure way&lt;/li&gt;
&lt;li&gt;We are specifying host as &lt;code&gt;0.0.0.0&lt;/code&gt; to listen on as default uses &lt;code&gt;127.0.0.1&lt;/code&gt; which will not let us access webserver started by mlflow from outside container&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Wrapping up
&lt;/h1&gt;

&lt;p&gt;This is a very simple and minimal example of how you can use docker to serve the MLFlow model trained in Databricks workspace.&lt;br&gt;
I hope this article will help you save time in connecting the dots in different documentations.&lt;br&gt;
So that is it, fellas. Thank you for reading the article. Wish you a great day. Peace out ✌.&lt;/p&gt;

&lt;h1&gt;
  
  
  Reference
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://www.mlflow.org/docs/latest/cli.html#mlflow-models-serve"&gt;https://www.mlflow.org/docs/latest/cli.html#mlflow-models-serve&lt;/a&gt;&lt;br&gt;
&lt;a href="https://databricks.com/blog/2019/10/17/managed-mlflow-now-available-on-databricks-community-edition.html"&gt;https://databricks.com/blog/2019/10/17/managed-mlflow-now-available-on-databricks-community-edition.html&lt;/a&gt;&lt;br&gt;
&lt;a href="https://docs.databricks.com/dev-tools/cli/index.html#set-up-authentication"&gt;https://docs.databricks.com/dev-tools/cli/index.html#set-up-authentication&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Build a serverless service for "Contact Me" form in Golang and deploy on GCP</title>
      <dc:creator>Akshay Milmile</dc:creator>
      <pubDate>Thu, 09 Jan 2020 12:24:54 +0000</pubDate>
      <link>https://dev.to/itachiredhair/build-a-serverless-service-for-contact-me-form-in-golang-and-deploy-on-gcp-3del</link>
      <guid>https://dev.to/itachiredhair/build-a-serverless-service-for-contact-me-form-in-golang-and-deploy-on-gcp-3del</guid>
      <description>&lt;p&gt;"Contact me" forms are pretty common. You can use it for your portfolio website, contact section of your online business and so on.&lt;/p&gt;

&lt;p&gt;This tutorial assumes our "Contact me" form has three fields: Name, Email, and Message. On hitting submit it will call a REST API which will trigger our GCP (Google Cloud Platform) function which in turn will forward above mentioned details to our email.&lt;/p&gt;

&lt;p&gt;This tutorial will cover the following things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Setting up the code with "&lt;a href="https://serverless.com"&gt;Serverless Framework&lt;/a&gt;" in Golang.&lt;/li&gt;
&lt;li&gt;Configuring Twilio SendGrid API.&lt;/li&gt;
&lt;li&gt;Prepare GCP resources.&lt;/li&gt;
&lt;li&gt;Deploying the Golang code on Google Cloud Functions.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Setting up the code
&lt;/h1&gt;

&lt;p&gt;We are using the "&lt;a href="https://serverless.com"&gt;Serverless Framework&lt;/a&gt;" to manage our function. In this tutorial, we will configure it to support GCP. But it's very easy to change the provider to other platforms like AWS, Azure, etc.&lt;/p&gt;

&lt;p&gt;If you don't have "Serverless Framework" installed on your machine, let's get it first by following below link (just install it, no need to login):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://serverless.com/framework/docs/getting-started/"&gt;https://serverless.com/framework/docs/getting-started/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Create the codebase:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ cd to/desired/location/in/GOPATH
$ serverless create --template google-go --name contactmebackend --path contactmebackend
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Next, install the plugin required for GCP (I'm using yarn, feel free to use NPM):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn add serverless-google-cloudfunctions
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;You will get the following files under &lt;code&gt;contactmebackend&lt;/code&gt; the directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Makefile
fn.go
fn_test.go
node_modules
package.json
serverless.yml
yarn.lock
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We will use Twilio's SendGrid API to send the information coming from REST API to our email address. SendGrid has a Golang package to interact with its API. Since we will be deploying this code to GCP functions later, we will need to setup &lt;a href="https://github.com/golang/go/wiki/Modules"&gt;Golang module&lt;/a&gt; so that GCP can figure out the external dependencies. Follow these steps to do just that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ export GO111MODULE=on
$ go mod init
$ go get -u github.com/sendgrid/sendgrid-go
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Edit &lt;code&gt;fn.go&lt;/code&gt; with the following code. I have provided comments to better understand the code (don't forget to replace it with your name and email id):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;contactmebackend&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="s"&gt;"encoding/json"&lt;/span&gt;
&lt;span class="s"&gt;"log"&lt;/span&gt;
&lt;span class="s"&gt;"net/http"&lt;/span&gt;
&lt;span class="s"&gt;"os"&lt;/span&gt;
&lt;span class="s"&gt;"github.com/sendgrid/sendgrid-go"&lt;/span&gt;
&lt;span class="s"&gt;"github.com/sendgrid/sendgrid-go/helpers/mail"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c"&gt;// Email struct defines the data coming via REST API&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="n"&gt;EmailAddress&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`json:"emailAddress"`&lt;/span&gt;
&lt;span class="n"&gt;Name&lt;/span&gt;         &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`json:"name"`&lt;/span&gt;
&lt;span class="n"&gt;Message&lt;/span&gt;      &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`json:"message"`&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c"&gt;// SendEmail function sents email with the data coming from REST API&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;SendEmail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ResponseWriter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;
&lt;span class="n"&gt;decoder&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewDecoder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;decoder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nb"&gt;panic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c"&gt;// Prepare the email content&lt;/span&gt;
&lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;mail&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewEmail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;EmailAddress&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;subject&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="s"&gt;"Contacted via portfolio website"&lt;/span&gt;
&lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;mail&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewEmail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Your name"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Your email id"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;plainTextContent&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Message&lt;/span&gt;
&lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;mail&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewSingleEmail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;from&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;subject&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;plainTextContent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;plainTextContent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c"&gt;// Get the SendGrid API key from environment variable&lt;/span&gt;
&lt;span class="n"&gt;sendGridAPIKey&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"SENDGRID_API_KEY"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c"&gt;// Generate a SendGrid Send Client&lt;/span&gt;
&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;sendgrid&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewSendClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sendGridAPIKey&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c"&gt;// Send the message&lt;/span&gt;
&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusCode&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusAccepted&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusCode&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusOK&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="c"&gt;// Request failed&lt;/span&gt;
&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteHeader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusInternalServerError&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Write&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Something bad happened!"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="c"&gt;// Request successful&lt;/span&gt;
&lt;span class="c"&gt;// Setting header to allow cors&lt;/span&gt;
&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Access-Control-Allow-Origin"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"*"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Write&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Success"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h1&gt;
  
  
  Configuring Twilio SendGrid API
&lt;/h1&gt;

&lt;p&gt;The only thing remaining for the above code to work as expected is the &lt;a href="https://sendgrid.com"&gt;SendGrid&lt;/a&gt; API key. To get the key, &lt;a href="https://app.sendgrid.com/login"&gt;log in to SendGrid Console&lt;/a&gt; first. Then go to &lt;a href="https://app.sendgrid.com/settings/api_keys"&gt;create API key&lt;/a&gt; page. Click on Create API Key.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--RxIKCVUL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/3hl6h4pru7bv8a9zmwrt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RxIKCVUL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/3hl6h4pru7bv8a9zmwrt.png" alt="Create API Key page"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Enter the name for the key. You can keep the Full Access for API Key permissions and hit "Create &amp;amp; View". Copy the API key displayed on the next page and keep it with you in some secure place.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2NFMiFDM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/v2ylcpu5mupsqbcaxi63.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2NFMiFDM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/v2ylcpu5mupsqbcaxi63.png" alt="API Key details page"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Testing the code
&lt;/h1&gt;

&lt;p&gt;To make sure the above code works, we will edit &lt;code&gt;fn_test.go&lt;/code&gt; and run tests. Edit &lt;code&gt;fn_test.go&lt;/code&gt; with the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;contactmebackend&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="s"&gt;"net/http"&lt;/span&gt;
&lt;span class="s"&gt;"net/http/httptest"&lt;/span&gt;
&lt;span class="s"&gt;"strings"&lt;/span&gt;
&lt;span class="s"&gt;"testing"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;TestSendEmail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;testing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="c"&gt;// Mock data with the 'body' which will go over the REST, and 'wantStatus' which is the expected status for the data sent in 'body' field&lt;/span&gt;
&lt;span class="n"&gt;tests&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="n"&gt;body&lt;/span&gt;       &lt;span class="kt"&gt;string&lt;/span&gt;
&lt;span class="n"&gt;wantStatus&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;
&lt;span class="p"&gt;}{&lt;/span&gt;
&lt;span class="c"&gt;// This one has all the necessary fields for successful request&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;`{"name": "Itachi Redhair", "emailAddress": "itachi.redhair@gmail.com", "message": "Would love to meet over a beer!"}`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;wantStatus&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusOK&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="c"&gt;// This one will fail the request because emailAddress is missing.&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;`{"name": "Itachi Redhair", "message": "Would love to meet over a beer!"}`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;wantStatus&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusInternalServerError&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;test&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;tests&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="c"&gt;// httptest.NewRequest package will form the mock request object which we can pass on to our function directly&lt;/span&gt;
&lt;span class="n"&gt;req&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;httptest&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MethodPost&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;strings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewReader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Content-Type"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"application/json"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c"&gt;// mock response object&lt;/span&gt;
&lt;span class="n"&gt;rr&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;httptest&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewRecorder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;SendEmail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;got&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;rr&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Result&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusCode&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;got&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;wantStatus&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Errorf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"SendEmail(%q) = %q, want %q"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;got&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;wantStatus&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now before you run the tests, you need to set the environment variables. Run the following command with the SendGrid API key:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export SENDGRID_API_KEY={Paste the api key which you copied earlier}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Run the test with the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;go test
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;You should see output which should be somewhat like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2020/01/08 11:18:29 &amp;lt;nil&amp;gt;
PASS
ok      medium-code-dump/contactmebackend       1.003s
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h1&gt;
  
  
  Preparing GCP resources
&lt;/h1&gt;

&lt;p&gt;Now that our code is ready, we need to deploy it. To deploy it on Cloud Functions we need to enable few GCP APIs. You can do so by following this &lt;a href="https://serverless.com/framework/docs/providers/google/guide/credentials/"&gt;guide on serverless.com&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Once you've enabled the required APIs, got credentials JSON file, stored it on your local machine and updated the &lt;code&gt;serverless.yml&lt;/code&gt; file, edit &lt;code&gt;functions&lt;/code&gt; field in &lt;code&gt;serverless.yml&lt;/code&gt; field like below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;functions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;first&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;handler&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;SendEmail&lt;/span&gt;
    &lt;span class="na"&gt;events&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;http&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;dummy-text&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;code&gt;SendEmail&lt;/code&gt; is the name of the handler function from our code in &lt;code&gt;fn.go&lt;/code&gt;. Name of the function &lt;code&gt;first&lt;/code&gt; doesn't really mean anything and is ignored, same goes for value of the field &lt;code&gt;http&lt;/code&gt;. You can see this link for details.&lt;/p&gt;

&lt;h1&gt;
  
  
  Deploying
&lt;/h1&gt;

&lt;p&gt;We are just there. To deploy the code just hit the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;serverless deploy
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Wait till the deployment is done. You will get the link to trigger the function at the end. Something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Deployed functions
first
  https://us-central1-{project-id}.cloudfunctions.net/SendEmail
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Before you try the above link, you need to specify the environment variable &lt;code&gt;SENDGRID_API_KEY&lt;/code&gt; in your cloud functions.&lt;/p&gt;

&lt;p&gt;Go to &lt;a href="https://console.cloud.google.com/functions/list"&gt;Cloud Functions List&lt;/a&gt; in GCP console. Open our newly deployed function &lt;code&gt;SendEmail&lt;/code&gt;. Click on edit. Scroll down and you will see an option to edit the environment variables. Add &lt;code&gt;SENDGRID_API_KEY&lt;/code&gt; and it's value and hit deploy.&lt;/p&gt;

&lt;p&gt;After your function is deployed, try the following command with the above link:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl -X POST \
https://us-central1-{project-id}.cloudfunctions.net/SendEmail \
-H 'Content-Type: application/json' \
-d '{
"emailAddress":"dummy-email@dummy.com","name":"dummy name", "message":"Hi there would like to meet you!"
}'
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Check your email and if everything goes fine you won't be disappointed.&lt;/p&gt;

&lt;h1&gt;
  
  
  Wrapping up
&lt;/h1&gt;

&lt;p&gt;This is a very simple and minimal example of how you can leverage Google Cloud Functions to deploy serverless service written in Golang.&lt;br&gt;
I am using this for the contact me form I have on my portfolio and wanted to share with you the approach I've followed. If you need a live demo, then check out my portfolio website &lt;a href="https://findakshay.dev"&gt;https://findakshay.dev&lt;/a&gt; and scroll down.&lt;/p&gt;

&lt;p&gt;If there is something you didn't understand or not working for you or can be improved, please let me know. You can reach out to me via Twitter or Linkedin. You can also email me at &lt;a href="mailto:akshay.milmile@gmail.com"&gt;akshay.milmile@gmail.com&lt;/a&gt;. You can check out some other projects that I've worked in past on my Github.&lt;br&gt;
So that is it guys. Thank you for reading the article. Wish you a happy new year. Peace out ✌.&lt;/p&gt;

</description>
      <category>go</category>
      <category>serverless</category>
      <category>googlecloudplatform</category>
    </item>
  </channel>
</rss>
