Introduction to Serverless (FaaS)
Older Article
This article was published 7 years ago. Some information may be outdated or no longer applicable.
Serverless computing, serverless functions, FaaS. These buzzwords have been floating around for a while. Let’s look at what they actually mean and build something with them.
Definition
The biggest “quirk” you need to remember: “serverless” still involves servers. There’s no magic that eliminates servers entirely. It’s a model where we, the developers, don’t worry about managing those servers.
Lingo
Let’s run through the basic terms around Serverless computing. Here’s a screenshot from a slide I presented at Download Event in Bergamo, Italy earlier this year.

IaaS
Infrastructure As A Service. Think Amazon’s Elastic Cloud Computing (AWS EC2) or Virtual Private Cloud (VPC). The key point: you manage everything. Amazon provides the infrastructure, but you set up and run the server.
SaaS
Software As A Service. A service that gives you specific functionality, free or paid. Stripe and PayPal for payments, Slack for communication. You integrate them, but you know very little about what’s happening under the hood.
PaaS
Platform As A Service. You get an entire platform to deploy and run an application, without worrying about the underlying infrastructure. Heroku is a solid example. Deploy to a Dyno (Heroku’s term), scale up or down as needed.
BaaS
Backend As A Service. A highly available backend for specific tasks, typically accessed through dedicated SDKs and APIs. DynamoDB from Amazon and Firebase from Google are good examples.
BaaS counts as Serverless. Why? From our perspective, there’s no server management involved.
FaaS
Function As A Service. You invoke a function. That’s it. Useful for things like implementing custom logic or orchestrating web services. Cost is a big factor here too (more on that shortly).
FaaS is the other service category considered Serverless.
So now we’ve got a handle on the various components in the Serverless space.
Pros and Cons
Serverless computing has clear benefits, but it also comes with trade-offs.
Pros:
- No “always-on” pricing (“Pay As You Go” instead)
- Computational power scales with load and usage
- Framework, language, and environment agnostic
- Horizontal scalability via ephemeral containers
- Lightweight virtualisation, no heavy configuration needed
“Ephemeral” here means short-lived containers. A container starts up, executes, returns data (or does some computation), then shuts down and gets destroyed.
In short, FaaS lets you focus on writing the function, not on DevOps. And you only pay for the computational time you actually use. Compare that to an EC2 instance running (and billing) around the clock.
Cons:
- Application state is hard to maintain
- No variable or data sharing between invocations
- Long-running functions get cut short
- Potential startup latency
Since functions run in ephemeral containers, sharing variables between invocations is nearly impossible. Containers have execution time limits, so long-running functions won’t work. And if a function goes idle for a while, its container can go stale (the infrastructure decides when), meaning you might hit longer startup times.
Serverless Framework
The Serverless Framework is an open source project from Serverless, Inc. It lets you create serverless functions without getting in the way, and it’s provider agnostic. You can target AWS, Microsoft Azure, or IBM OpenWhisk.
Example
We’ll use the Serverless Framework to create a function running on AWS (via AWS Lambda). The function will talk to Unsplash and Cloudinary. I picked the Serverless Framework for two reasons: I’d been wanting to try it, and it makes deploying to AWS (and other providers like Azure, Bluemix, and Oracle Cloud) easy.
Here’s the scenario. You need a sample image of something (a cat, a house, a business person, you name it, but probably a cat). You want to grab one and store it somewhere.
We’ll build a Serverless Function that takes an argument like “cat”, fetches a random image from Unsplash, and uploads it to Cloudinary’s Media Library. We’ll cover setting up the Serverless Framework, configuring it, and wiring the pieces together.
Getting started
Install the Serverless Framework: npm i -g serverless
Start a new serverless project: serverless login
You’ll need to set up your AWS credentials. This article doesn’t cover that, but check the AWS Credential Setup Guide from Serverless, Inc.
Once logged in, create a new service using the Node.js template: serverless create -t aws-nodejs
This generates two files:
* handler.js
* serverless.yml
handler.js holds the function we’ll invoke. serverless.yml contains the service configuration.
Open the yml file and add these lines:
service: aws-nodejs
app: XXX
tenant: XXX
Replace XXX with your app and tenant values.
Deploy the service: serverless deploy
Verify it’s working by invoking the function (called hello by default): serverless invoke -f hello -l
If everything’s set up correctly, you’ll see a message body come back.
Updating the handler
Time to update the handler function. We’ll rename it and write the actual code:
'use strict';
function _getImage(term) {
const url = `https://api.unsplash.com/photos/random?query=${term}&client_id=${process.env.UNSPLASH_API_KEY}`;
return new Promise((resolve, reject) => {
const https = require('https');
const request = https.get(url, (response) => {
if (response.statusCode < 200 || response.statusCode > 299) {
reject(
new Error('Failed to load page, status code: ' + response.statusCode)
);
}
const body = [];
response.on('data', (chunk) => body.push(chunk));
response.on('end', () => resolve(body.join('')));
});
request.on('error', (err) => reject(err));
});
}
module.exports.image = async (event, context, callback) => {
const cloudinary = require('cloudinary');
cloudinary.config({
cloud_name: process.env.CLOUDINARY_CLOUD_NAME,
api_key: process.env.CLOUDINARY_API_KEY,
api_secret: process.env.CLOUDINARY_API_SECRET,
});
if (event.queryStringParameters && event.queryStringParameters.term) {
const term = event.queryStringParameters.term;
return _getImage(term).then((response) => {
const r = JSON.parse(response);
return cloudinary.v2.uploader.upload(r.urls.full, (error, result) => {
return callback(null, {
statusCode: 200,
body: JSON.stringify({
message: `Access image at ${result.secure_url}`,
}),
});
});
});
}
};
That’s a chunk of code. Let’s break it down.
All the
process.env.*values are explained later in this article.
_getImage() hits Unsplash and returns a random image based on the term argument.
You’ll need a valid API key for this to work. Register for one.
The second part, starting with module.exports.image, is the FaaS code that runs on AWS. It sets up Cloudinary credentials.
Sign up for Cloudinary to get your API key.
With credentials in place, we check for query parameters. If they exist, we call _getImage().
That function returns a random image. We take the full URL from Unsplash, pass it to the Cloudinary Node.js Uploader, and if the upload succeeds, we return the Cloudinary URL.
Managing dependencies
The code depends on the Cloudinary Node.js API. How does the Serverless platform know about this dependency and install it on AWS?
Simple. You need a package.json in the same location as your other files, with the dependency listed:
{
"name": "serverless",
"version": "1.0.0",
"description": "",
"main": "handler.js",
"dependencies": {
"cloudinary": "^1.11.0"
},
"devDependencies": {},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
Managing secrets
We’ve got several secrets in the code, and they shouldn’t be exposed. The serverless.yml config file lets you set environment variables, accessible via process.env:
Extend serverless.yml with the following (swap in your real values):
provider:
name: aws
runtime: nodejs8.10
environment:
CLOUDINARY_API_KEY: 'cloudinary-api-key'
CLOUDINARY_API_SECRET: 'cloudinary-api-secret'
CLOUDINARY_CLOUD_NAME: 'cloudinary-cloud-name'
UNSPLASH_API_KEY: 'unsplash-api-key'
API Gateway
We’ve created a service, but there’s no way to call it via REST yet. To invoke the function, we need an API Gateway.
Since we’re using the Serverless Framework, this is painless. Just update serverless.yml with the gateway details:
functions:
image:
handler: handler.image
events:
- http:
path: image
method: get
We define that an HTTP GET to /image should resolve to handler.image, which is module.exports.image in our code.
Deploy
After all these changes, deploy (or redeploy): serverless deploy
Executing
During deploy, you’ll get Service Information that looks something like this:

See the endpoints? That’s what we use to invoke our FaaS. Let’s try it.
The service URLs and responses will be different for your setup.
You should see a URL come back. And if you log into your Cloudinary Media Library, the image should be sitting there:

Conclusion
We’ve covered the basics of Serverless computing and built a fun example: a FaaS solution that loads a random image from a royalty-free provider into Cloudinary.