Serverless Cloud first came to my attention during Serverless Summit 2021 when AWS Serverless Hero Jeremy Daly presented the product that he’d been helping build himself. For anyone with an interest in Serverless who somehow hasn’t managed to come across Jeremy before I’m sure he won’t mind me linking to his content, I strongly recommend subscribing to his newsletter ‘Off-by-none’ which I’ve used to keep up with the serverless world for the past few years.
Firstly, let’s answer address the elephant in the room: what is Serverless Cloud?
Serverless Cloud allows you to build your applications without having to worry about the creation and management of cloud services, giving developers more time to focus on what they do best; writing code. It does this by abstracting the cloud services with an interface that you can add as a dependency in your application, leaving Serverless Cloud to do all of the heavy lifting.
Serverless Cloud also provides a dashboard that allows you to monitor your application with metrics and logs out of the box. It also allows you to invoke your endpoints directly from the dashboard, removing the need for a tool like Postman to perform the same functionality.
Now to the fun part: what can I do with Serverless Cloud?
Serverless Storage gives you the ability to store files without having to write the Infrastructure as Code code to create and manage the S3 buckets yourself, you don’t even need to pass a link to the bucket into your application.
Storage is a very common use case in modern software applications. In the example below you can see that I call the storage API to store the CV of an employee and get the download URL of the file which I’m returning in the response.
import { api, data, storage, schedule, events } from "@serverless/cloud";
api.post("/employees/:id/cv", async (req, res) => {
let key = "employee:" + req.params.id;
let employee = await data.get(key);
let filepath: string = '/cv/' + req.params.id + '.txt';
await storage.write(filepath, req.body);
let downloadUrl = await storage.getDownloadUrl(filepath);
employee.cvUrl = downloadUrl;
await data.set(key, employee, true);
res.send({ downloadUrl });
});
Another cool feature of the storage service is the ability to add listeners for any changes in your bucket. This is very cool and you would usually have to handle these events in your config, for example calling a lambda when anything changes in your bucket.
The code below writes a log message any time a file is stored in my bucket with the cv
prefix. You can use this feature to build a pipeline of asynchronous tasks, for instance scanning the uploaded file for a virus or redacting sensitive data from a file before making it available for retrieval from your application.
import { api, data, storage, schedule, events } from "@serverless/cloud";
storage.on("write:cv/*", async (event) => {
console.log('File has been uploaded, scanning for virus: ' + event.path);
});
You can see the other features of the storage service here.
Serverless Data gives you the ability to store your application data in a key/value data store without having to manage database access, maintenance, sizing, or even having to pass connection strings to your application.
Data is a cornerstone of software so having access to store and retrieve your application data by calling a method has the potential to reduce a great deal of development time in your teams. In the example below you can see how I retrieve a list of all employees, get a single employee and store an employee.
import { api, data, storage, schedule, events } from "@serverless/cloud";
import { Employee } from "./models/Employee";
import { v4 as uuidv4 } from 'uuid';
api.get("/employees", async (req, res) => {
let result = await data.get("employee:*", true);
res.send({ employees: result.items });
});
api.get("/employees/:id", async (req, res) => {
let key = "employee:" + req.params.id;
let result = await data.get(key);
res.send({ employee: result });
});
api.post("/employees", async (req, res) => {
let employee: Employee = req.body;
let id: number = uuidv4();
await data.set('employee:' + id, employee);
events.publish("employee.created", { name: employee.name });
res.send({ employeeId: id });
});
You can see the other features of the data service here.
Serverless Events allow you to publish events and then handle them asynchronously, either immediately or after a period of time. Again this allows you to build out asynchronous pipelines of tasks without having to create queues and configure Lambda invocations.
In the example below you can see how I publish an event when an employee is created and then asynchronously pick up the event. You can use this to send welcome emails or let other integrations of your application such as a payroll system know that this new employee has been created.
import { api, data, storage, schedule, events } from "@serverless/cloud";
import { Employee } from "./models/Employee";
import { v4 as uuidv4 } from 'uuid';
api.post("/employees", async (req, res) => {
let employee: Employee = req.body;
let id: number = uuidv4();
await data.set('employee:' + id, employee);
events.publish("employee.created", { name: employee.name });
res.send({ employeeId: id });
});
events.on("employee.created", async ({ body }) => {
console.log('Send welcome email to ' + body.name);
});
You can see the other features of the events service here.
We’ve all been on projects that require a cron job to run to either run a clean-up script or trigger a data update. With Serverless Cloud you can simply define a function to run whenever you want, removing the need to configure a cron job to run in your environments.
import { api, data, storage, schedule, events } from "@serverless/cloud";
schedule.every("1 day", () => {
console.log("Doing some sort of cleanup task every night!");
});
You can see the other features of the scheduled tasks service here.
The serverless cloud follows an isolation model. You have an organization within which you can create many apps, these are applications that can be multi-stack or independent services. Each app can then have many instances, an instance can be an environment such as production or test, with each instance getting its own set of resources such as data and storage.
This approach allows you to run your application in the cloud in seconds, almost too fast to believe.
Want to run your application in the cloud? Just type cloud
Want to share your current state with a team member for testing? Just type cloud share
Want to deploy to the test environment? Just type cloud deploy test
Want to promote the version of your application in your test environment to your production environment? Just type cloud promote test prod
It’s almost too easy.
Serverless Cloud is still in development (version 2.8.2 at the time of writing) so there is still a lot of functionality in the pipeline that isn’t available yet so here’s some of the things I would like to see in future releases:
us-east-1
region however many companies are likely to be legally bound to not transfer data outside of the country/area in which they reside so they wouldn’t be able to use Serverless Cloud.I’ve really enjoyed my experience using Serverless Cloud and I will be continuing to use it to deploy personal and proof-of-concept applications going forward. In the future, I hope some of the above points will be addressed which will allow me to push the use of Serverless Cloud within organizations.
If you want to have a look at the project with the code linked above you can find that here.
Serverless Cloud has a great Slack community that will be happy to answer any of your questions and solve any problems you might be having, you can join that here.
If you have any comments about this blog or want to have a chat you can find me on LinkedIn here.
Also Published here