Building a Serverless Contact Form

Don Irwin
3 min readApr 22, 2020

--

Using Azure Functions and Proxies as an API Relay

On a recent project, the client wanted a simple, single page, portfolio web site with a contact form to notify the client via email when a user submitted the form. The client was “techy” and being all read up on the current state of web development, wanted the web site to be serverless. I’ve been building web sites for 20+ years, so building a site with HTML, CSS and JavaScript was a refreshing challenge given all the options available like Angular, React or Vue. In the end though, most of what these frameworks do is render HTML, CSS and Javascript. So, the challenge for this article: How do we capture user input and email it with just HTML, CSS and JavaScript?

Serverless Email?

Well, not technically — there has to be an email server somewhere, but we definitely want nothing to do with maintaining that server. So, we’ll use an email service like SendGrid. There is a free tier to SendGrid that (as of this writing) allows you to send 40,000 emails for 30 days, then 100/day forever.I’m not going to cover setting up SendGrid. For this exercise, all you will need is an API key and the email API enpoint — you can create one under settings in your SendGrid account or use any other email service of your choosing.

SendGrid has an Email API, so I can just send requests to their server, right? Well yes, if you are using a relay server, but we are trying to do this without a dedicated server we have to maintain. Can I send directly from a browser? No — SendGrid (and any reputable email service) has CORS restrictions enabled which prevents direct communication between browsers and their email API. When you have a browser-only application that reaches out to APIs, the API key has to be embedded in the application. Anyone with access to a browser-only application can access all of the Javascript source code, including your API keys.

Making your API key publicly accessible could result in anyone authenticating API calls with your API key — this is a significant security concern both for you and SendGrid. That leaves cloud-based serverless computing as a good option.

Functions and Proxies

For this article, I’ll be using Azure Functions (you could use AWS Lambda or GCP Functions as well). Serverless functions are great for delivering small blocks of functionality through custom code. A couple years back, Azure added proxies to their Functions.

Functions Proxies let you define a single API surface for multiple function apps. Any function app can now define an endpoint that serves as a reverse proxy to another API — whether that endpoint is another function app, an API app, or anything else.

An Azure Function Proxy allows us to modify requests and responses. Therefore, we can take a request to the proxy from our browser and add SendGrid’s required Authorization header which includes our Email API key.

In order to get started, create an Azure Function, then create a Proxy in the function:

Azure Function

Configure the proxy:

  • Set the route template — this defines the URL your code will call — /send
  • Set the HTTP methods you will accept — POST
  • Set the backend URL (to Email API) — https://api.sendgrid.com/v3/mail/send
  • Override the request to add the Authorization header

Configure Azure Function CORS:

  • Navigate back the the Azure Function (top level)
  • Navigate to CORS (link on main function tab)
  • Set the domains your site will be calling from (include localhost for testing)

To test the proxy, set the backend URL to a utility like RequestBin and post a request to see if your app is sending data the way your email service expects it.

On the web side, simply make a call to the proxy:

JavaScript example code

QED — now, you can essentially call an email API from your browser by relaying the request through an Azure Function proxy.

--

--

Don Irwin

Live in the future, build what is missing! F-16s and code…hmmm! https://www.donirwin.dev