Let's take a step back and define "Serverless Eventing".
What is Serverless?
It is no secret that I love serverless computing. As you know, we have discovered a way to transmit data through condensation. We actually beam data into nimbostratus clouds and that's where the compute and storage takes place. You experience outages when the sky is clear.
Alright, I am just kidding. We have not yet discovered how to host data in actual clouds but someone in a lab somewhere is working on it. I actually go into details in an earlier post.
TL;DR: Serverless is about abstracting infrastructure from the developer so that they can focus on code. I have heard people often confuse "Managed Services" with "Serverless". On the surface, they look the same. The responsibility of infrastructure management has shifted from the user to the provider in both scenarios.
Managed Services, however, tend to stop at that point. If you have a managed WordPress installation, for example, it is still WordPress at the end of the day. The only difference is that the responsibility for managing uptime and patches lies with a provider, not the user.
What differentiates serverless from Managed Services can be punctuated by these three points.
- Simplified Code Deployment: The core tenet of Serverless computing is to be primarily code centric. This is accomplished by creating a packaging standard that allows developers to define their code runtime, bundle that definition with their code, and push to production. Two common examples could be Buildpacks and Containers.
- Resource Allocation On-Demand: Abstracting the infrastructure takes away the power of resource control from the developers. Developers need to know that the resources they need will be available and will scale based on increased traffic. A Serverless platform needs to guarantee the ability to bring up workers to execute code. We also need to ensure that developers on pay for the resources that they use.
- Stateless Microservices: In order to take full advantage of serverless architecture, one should decompose their application into smaller,stateless microservices. Having these components act independently of each other allows for more agile development, easier packaging, and code specialization.
What is Eventing?
So what is Eventing? Admittedly, I didn't make up the word. Knative Eventing is where the word first came to light for me. But I enjoy this over "event-driven".
If we take a step back, in my earlier post I talk about "data-driven" applications. The term is very vague as data is simply information but it doesn't tell you anything about the state of said information. The data could be current, the data could be in cold-storage. "Event-Driven" is being data-driven but with a real-time aspect.
Events run our world. I am not just talking about conferences and concerts. A recent transaction on your credit card is an event. Adding an item to a cart with an online retailer is an event. Clicking on a recommended item is an event. Your ride share app telling you that your driver is now 4 minutes away instead of 5 is an event.
A modern application will generate and/or ingest several hundreds if not thousands of events in a given day. This is what we can call "eventing"; an action verb for producing and consuming events in an application. These events are active in nature. The context and content of an event tells your application what to do next.
In the above credit card example, to prevent fradulent activity, one would want to analyze that transaction as soon as it happens. This would kick off another event where an initial fraud analysis takes place, looking for obvious signs. Depending on the results, there are two possible events, either an "everything is okay, proceed as you were" or "this doesn't look right, let's further analyze the charge". That in turn may kick off its own set of events and so on.
Bringing it home, what is "Serverless Eventing"
Let's combine these two concepts. We want to create an application that is event-driven and also serverless. Easy, just create a Kafka cluster, create some topics, setup your microservices to consume and you are good to go. Right?
Yes and no. That is certainly one way you can do it but really Kafka or any pub/sub style messaging bus is really more of a component of Serverless Eventing.
Let's look at our definitions of Serverless again. The application needs to be stateless, resources need to scale, and we need to simplify the bundling of code. This done by abstracting the infrastructure components from the developer. Similarly we need to abstract the binding of event sources to their sinks (producers and consumers).
The traditional method is to do so imperatively. You tell your application to get these messages from this topic hosted on this cluster using this API Endpoint, etc. In a Serverless model, we want to scale and imperatively defining the bindings prohibit that. As our application grows and our services are working with more events, we need to declaratively bind the events.
We don't want to code our services to directly consume from a specific source, requiring specific libraries, and so on. Instead, our services should be able to passively receive events and react accordingly based on our services' business logic. As your application grows, rather than having to bind event sources to your services by hardcoding it, you define the connections and event flow using the Serverless Eventing tool.
While Knative Eventing isn't the only tool that is accomplishing this vision, I personally believe that they have one of the best opinionated structures to execute. You define event sources, brokers, channels, and sinks as Kubernetes objects via YAML. These components will then deliver the messages to your services.
Due to it's open source nature, you are able to extend the Knative Eventing CRDs to support new event sources and do other customizations. Knative Eventing supports a number of event sources such as GitHub, Kubernetes, Kafka, and more. You are essentially given a toolbox to build your own pipelines for event-driven applications.
Knative Eventing also allows for both simple and advanced routing. Simple routing will take an event from a source and send it to a specific sink. Advanced routing gives you some intelligence when it comes to determining what to do with the event before it reaches the sink. You can then route it to the proper sink based on a set of criteria.
In summary, Serverless Eventing enables developers to declaratively bind event sources to their sinks, abstracting the process from the developer. Through this blog series, you will learn specific ways to do this.