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:
What is a “Serverless” App?
How can we make a Zoom App serverless?
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 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.
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.
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 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! 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.
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.
Happy Coding!
Top comments (1)
Hi,
Thanks for sharing all of that information.
Let's say I am building a Zoom Meeting SDK mobile application with this Serverless approach.
I need to include in my project the CLIENT_ID, CLIENT_SECRET, SDK_KEY and SDK_SECRET to log-in an use the SDK.
Normally, with a server, we would hide our secrets in the server and not expose it in our user application.
What do you suggest? There is some mention of that in the documentation I think, but I would like to know more.
Thanks.