Finally, you’ll need an account with OpenWeatherMap - we’ll be making use of their weather API service.

The Beginnings

With Serverless we get to define our infrastructure in YAML, so let’s begin there:

# create a directories for the service and webpage.
mkdir -p weather_in_venice/{service,webpage}# navigate into the service directorycd weather_in_venice/service
# create the serverless.yml file. This is where we'll declare the# parts that make up our service.
touch serverless.yml
# Open the directory in atom (or editor of your choice!)
atom .

Describing our Infrastructure

Opening up serverless.yml, we can begin describing the parts we’ll need for our webpage to work, namely, a function for telling us the current temperature for Venice, and an HTTP endpoint to invoke our function when requested.

# Name of our service (the service being the function and integrated API endpoint)service:WeatherInVeniceprovider:# Define *provider* specific details.name:aws# Serverless framework supports multiple cloud providers.# We're using AWS...runtime:nodejs6.10# AWS Lambda supports a small number of runtimes.# We'll use node in this tutorialregion:us-east-1# See the end of this post for info on regions, if you're# not already familiar with them.functions:# This is where it gets exciting! We're describing our# function and an event for invoking the function.getWeather:# Name of our function.handler:function.getWeather# Location of our function's code, *function* is the file, and# *getWeather* is the name of the exported module.events:# Define events here. Multiple AWS services trigger# events that you can tap into. Here, we# only need to integrate with an API Gateway event.-http:path:weather# Path of the API endpoint.method:get# The HTTP method. We only need to support# a GET request.cors:true# We'll be calling our API endpoint from a# different domain, so we need to enable cors.# If you're not sure what cors is see end of# post for more info.

We’re getting very close to knowing the current temperature in Venice and being able to display it on a webpage.

But let’s not get ahead of ourselves. We still need to create the beating heart of our service, our Lambda Function!

Staying in the service directoy, we’ll create a file called function.js:

module.exports.getWeather=(event,context,callback)=>{/*
In serverless.yml we said that our function would be exported as
`getWeather`.
*/constdata={temperature:19.2};/* Define some dummy data, for now. In the next post
we'll replace this with a live call to the OpenWeatherMap API. */constresponse={statusCode:200,headers:{"Access-Control-Allow-Origin":"*",},body:JSON.stringify(data)// JSON.stringify converts the JavaScript response object// into a JSON string, which is what our client is expecting.};/* Build a response object. Since our function
is responding to an HTTP request, we should
at least define the response status code, `statusCode`,
and the response body, `body`. Because we'll
be depending on CORS we also need to set
the `Access-Control-Allow-Origin` header. */callback(null,response);/* We terminate the request by invoking the `callback` function
given to us by Lambda. We're passing `null` as the first argument
as our function has successfully executed. If our function
fails to execute, then we'd pass a description of the
error as our first argument. */};

I’ve deliberately kept the number of moving parts in our function to a minimum - I want to focus first on getting something deployed and working with our webpage.

Before we deploy let’s use the Serverless Framework to invoke our function locally, to see if there are any obvious errors we’ve missed. On the command line:

OK, Let’s Deploy!

This couldn’t be easier. Again, on the command line:

serverless deploy

That’s it!

The Serverless Framework will now do what it must to gracefully hand over our function and infrastructure requirements to AWS. An important part of this job is creating a CloudFormation template from our serverless.yml file. CloudFormation is another AWS service that allows you to describe your AWS resources, like S3 buckets, Lambda Functions, EC2 instances, and so on, and then have AWS build and configure them for you. Really, what we’ve been writing to serverless.yml is just a slightly higher abstraction of that. CloudFormation is an incredibly powerful service (and idea), but one we sadly haven’t the time to explore further in this post.

We’re particularly interested in the output under endpoints. There you’ll see the API Gateway generated URL for invoking our function. Notice its path, /dev/weather? It contains a trailing /weather, as specified in our yaml file, but it also has /dev/ in there. Serverless allows us to deploy to different environments, [dev]elopment being the default. We could have a two stage deployment, where we test out a new feature in dev, and when we’re happy we deploy to production. This would be easily done on the command line with the --stage flag:

serverless deploy --stage prod

Anyway, back to our endpoint. Copy it and give it a try in a browser, or on the command line:

pwd-> /Users/omar/weather-in-venice/service
# Check where I amcd ../webpage
# Navigate back one directory and forward into webpage
touch index.html app.js
# Create two files - one for our html markup and the other# for our JavaScript
atom .
# Open up the directory with Atom (or editor of your choice)

Let’s get some basic markup together for index.html:

<!DOCTYPE html><html><head><metacharset="utf-8"><title>What is the temperature in Venice?</title><style>h1,h2{text-align:center;font-family:sans-serif;color:#333;}</style></head><body><h1>What is the temperature in Venice, Italy?</h1><h2id='temperature'>Checking...</h2><script src="app.js"charset="utf-8"></script></body></html>

And some behaviour for app.js:

functionrenderTemp(data){varel=document.getElementById('temperature');el.innerHTML=data.temperature+" °C";}// replace with the endpoint created in your deployment.varendpoint='https://replace-me.execute-api.us-east-1.amazonaws.com/dev/weather';fetch(endpoint,{mode:'cors'}).then(function(resp){returnresp.json();}).then(renderTemp);

The above code is using the browser’s Fetch API for fetching data from our API Gateway resource. Notice we’ve set mode to cors. On a successful request we pass the returned JSON to renderTemp, where we assign the temperature to the innerHTML property of the h2 DOM element we created in our HTML doc.

Give it a spin on your browser. If things have gone to plan, you should have a working MVP!

In the next post we’ll work on replacing our stub data with live weather data using OpenWeatherMap’scurrent weather API. This’ll allow us to explore how we can set and use environment variables with AWS Lambda with help from the Serverless Framework. See you there!