Building Serverless Zoom Apps
Tags: firebase, javascript, vue, serverless
Published: 2022-11-09 18:17:28

When we build Zoom Apps, we’re creating tools that have the potential to be used by millions of people every day to do their jobs. The difficulty here is that we’re writing real-time, collaborative, and distributed apps using monolithic tools that are designed to solve different problems.

We can deploy a docker image and orchestrate clusters to make sure we have a highly available and scalable application but at the end of the day, we are still responsible for maintaining and updating that server infrastructure to make sure our app continues to work for all users.

Whether we’re staying late yet again dealing with crashed servers, or deciphering system configuration in an attempt to secure and optimize our app there is a lot to think about for a backend development team.

Often, we end up working against our tools rather than with them which is ironic when we’re configuring these servers and orchestrating clusters just to reliably run the logic that makes our app awesome.

Today, let’s talk about improving our developer experience in a production-ready environment way that allows us to experiment, fail fast and win big

## What to Expect from this guide

I’m hoping you can answer the following questions after this guide:

1. What is a “Serverless” App?

2. How can we make a Zoom App serverless?

3. What is the quickest way to get started?

## What is a Zoom App?

For readers that are unfamiliar with what exactly a Zoom App is I recommend checking our [Introduction to Zoom Apps](https://dev.to/zoom/introducing-zoom-apps-33he) series.

In one sentence, I would say it’s a super-powered web app. Meaning, you’ve got the flexibility of a web app with the reach and in-client features of Zoom right at your fingertips. 

With the Zoom Apps SDK, we can use JavaScript or TypeScript to create first-class applications to enhance the meeting experience.

## What’s the catch?

So we know that Zoom Apps are super-powered web apps which means they have the same considerations as a typical web app. 

This is great for web developers because it means we are working in a familiar landscape but it’s key to understand that we have the same challenges as writing a typical web application.

* What will our server infrastructure be?

* How can we ensure high availability?

* Cluster Orchestration? Load Balancing? 

* What about our databases?

The list goes on! There’s certainly a lot we need to think about as developers to get started building.

## Why is that a Catch?

it might be easy to think those are the components of a web app. That’s simply the boilerplate which is why I think a lot of developers find the initial setup and configuration of a production-ready project to be one of the biggest barriers to experimenting and failing fast.

For a lot of developers, I think the problems we like solving are quite a bit more nuanced and we don’t want to maintain what is effectively boilerplate for our app. 


When we look at the server infrastructure including our storage, authentication, user models, and content delivery as part of the boilerplate we can start to see how monolithic tools and technologies break down for us. 

Instead, if we can reuse some of the boilerplate server code that we need and modularize our infrastructure we can provision, develop and deploy applications instantly.

That’s where serverless apps come in!

## What Makes a Serverless App?

Serverless technology is based on a microservice architecture that exposes one or more services to be used as modular units for your application per your use case.

What does this look like in the real world? It means that you don’t have to think about any of the servers for your apps. Sure there is a computer somewhere that is running your code but the best part about serverless architecture is that you don’t have to factor in the underlying technologies when building out your next killer app.


Instead, we’ll be using a platform that encompasses the backend and logic of a server that we can easily consume in our front-end application.

### Backend as a Service (BaaS)

Not thinking about servers means using a backend as a service where you don’t have to worry about updating your operating system or patching your database. 

Where cloud storage is automatically configured and your frontend code is hosted through a CDN. All of this represents hours and hours of research, setup, testing, and implementation on its own.

I really can’t overstate how significant of a head start this is on developing an MVP that you would want as your product.

### Functions as a Service (FaaS)

While we have the backend systems available as services, we still need a way to implement our custom server logic. 

Luckily serverless architectures provide functions as a service which are short-lived instances that run your backend logic.

As these instances are so temporary, you’re only charged for exactly what you use and you never have to deal with runtime errors related to out-of-date system dependencies

## Pros and Cons

As we know, nothing is perfect so let’s take a moment to go over some of the Pros and Cons of serverless applications:

### Pros

* Cost Effective

* Easily Scalable

* Zero Maintenance

* Shorter Time-to-Market

### Cons

* Complex Debugging 

* Vendor Dependency

* Multi-Tenancy

* Costly Compute Tasks

Looking at the pros, we’ve covered most of this already as we’ve learned about serverless architecture. We have less to manage, and containerized code with more precise billing. This means less of a headache for us and therefore a shorter, and cheaper, time to market.

It’s when we look at the cons of serverless applications that we can learn more.

### Complex Debugging

Since your code is running on another server, debugging can sometimes be time-consuming and complex with server errors on a cloud-based server. With the sample code that we’ll be using in this guide, the use of Local Emulators greatly improves our debugging experience.

### Vendor Dependency

As there currently isn’t an ORM of sorts for cloud vendors often writing a serverless application can lock you into a specific vendor. Of course, you can make the migration between services relatively pain-free by wrapping your database calls with your multi-vendor API.

### Multi-Tenancy

This is a new concern for our security engineers out there that are looking to adopt serverless applications. Due to the shared nature of most cloud computing servers, there is a risk that vulnerabilities such as privilege escalation or memory leaks can lead to data breaches.

### Costly Compute Tasks

Running costly compute tasks on a FaaS is inadvisable and instead should only be used for short-lived tasks like a typical server route. Using the ephemeral containers which are charged based on usage time to compute data can not only cost quite a bit but also take too long.

Instead, the cloud platform likely provides other compute or VPS services that would be more applicable.

## Using Firebase

Firebase is a Platform as a Service (PaaS) that provides Cloud Functions and Backend services. It has usable free tiers and intuitive paths to get started quickly. 

These techniques and tips apply to any Paas/IaaS provider through the steps to implement will vary.

Throughout this guide, we will use three functions of firebase

### Cloud Functions

These fulfill the FaaS requirement for our serverless application quite well. As described by Firebase these will allow us to:

> Automatically run backend code in response to events triggered by Firebase features and HTTPS requests

### Firestore

This will allow us to sync data between our various clients without having to put any thought into database configuration. Just make a schema for the shape of our database and push data!

> Flexible, scalable NoSQL cloud database to store and sync data for client and server-side development

### Hosting

This is how we will serve content to our users. We can set it up as a dynamic or static host and either way it will automatically be configured to scale and distribute our content globally.

> With a single command, you can quickly deploy web apps and serve both static and dynamic content to a global CDN

## Replacing our Server

As some of you may know, we have a Basic Sample Zoom App that uses a simple express server to demonstrate the bare minimum needed to get started with a Zoom App.

![Zoom Github](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rs3jkresc1b3gwaft0hj.png)

Being a basic server, it’s still responsible for quite a bit! Let’s take a look.

### Zoom Apps Authorization Flow

Our server is currently responsible for acting as the redirect URL for our Zoom App which can receive the access token. This is something we specifically need a server for because we can’t expose the token to a web client.

This is where Cloud Functions come in. Cloud Functions allow us to:

* Receive the Authorization Code

* Obtain the Access Token

* Make Requests to the Zoom API

and so much more!

### OWASP Headers

If you’re already a Zoom App Developer you know that the OWASP security headers are essential for getting your app up and running. Without them, you’ll see what I call the white screen of death - a blank zoom app with only a console error to guide you.

When we’re working with the sample code today, we can set production headers in firebase.json and use the development server configuration to set the development headers.

Luckily, if you clone the code you’ll see that this is already done for you.

### Zoom Apps Context Header

If you have looked at any of our Zoom Apps sample applications so far, you’ll notice that they decrypt and unpack the Zoom Apps Header that is sent by the Zoom client.

When we don’t have direct access to a server, and in this case, we are using a Single Page Application, then how can we read the request headers?

The answer is that we don’t. We can get all the information we need from the Zoom Apps JS SDK. While we could set a cloud function as our homepage to decipher the headers this is impractical when we have the Zoom Apps SDK.

### Client Side Routing

For readers that haven’t used client-side routing before, it is incredible! Instead of making requests to the server, we can use JavaScript bundles and instantly load the new chunk of code. 

This means fewer requests to your server, less bandwidth, and instant load times.

## A Look at the Demo App

Our sample today can be found on our GitHub and is a serverless, single-page, todo application. Yes, it uses all the buzzwords and is built on a modern tech stack around an intuitive developer experience.


![Sample Serverless App](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7h493489ywa3n13jdod1.png)


**[Clone The Repo Here](https://github.com/zoom/zoomapps-serverless-vuejs)**

## Configuring Firebase

This step should be very simple which is one of the reasons I built this sample around Firebase. 

* Join a Free Account

* Create a New Project

* Enable Hosting, Functions & Firestore

* Set Up Secrets Manager

## Firebase Development

When working with Firebase, you’ll want to make use of the Local Emulators.

What are Local Emulators? They are local services that emulate the serverless architecture on your local system. This allows you to test and debug locally which offers instant access to more detailed debug logs

Likewise, you’re able to make changes to your application locally and retain hot reloading which drastically improves productivity

Once we have the emulators running, we can proxy the function emulators using our development server so that our OAuth Redirect URL can be used. This is all set up in the sample application that we have.

## Configure your Zoom App

When working with a development environment, we have a .secrets.local file for our Zoom App credentials. However, when we are running in a production environment, we are lucky enough to have a Secrets Manager to create, rotate and manage application secrets.

In both cases, the secrets will be automatically injected into our application environment.

In the image below, you can see that for development we are using a tunnel to our local system for our development credentials ([Ngrok](https://ngrok.com) in this case). Notice the format of the redirect URL matches the path to a local emulator.

For production environments, we are using the actual hosting URL and cloud function URL provided by Firebase. This enables a smooth developer experience with a logical separation of environments.

## What’s Next?

If you haven’t already [check out our github](https://github.com/zoom/zoomapps-serverless-vuejs)! Get started right away using our sample application so you can build out the next killer Zoom App! 

If you’re feeling comfortable with Cloud Functions and Zoom Apps take a look at the next post in this series - [What I Learned Implementing PKCE for Serverless Zoom Apps](https://dev.to/zoom/what-i-learned-implementing-pkce-for-serverless-zoom-apps-1k9l).

## Thank You for Reading!

Thanks for taking the time to read this guide. If you have any lingering questions or just want to chat about building the future of collaboration please head over to our [Developer Forum](https://devforum.zoom.us/).

Happy Coding!