8 practical serverless design patterns for enterprise devs
Serverless app teams can turn to architecture patterns to guide the way to a successful product. Learn the criteria to narrow your options and the key differences between eight patterns.
Architectural models for code construction, known as design patterns, act as critical blueprints for developers. When considering serverless computing, developers naturally flock to serverless design patterns.
But before sifting through architecture pattern suggestions, developers need to reflect on two key questions:
- What is the nature of your serverless application?
- What serverless framework, or frameworks, do you expect to run in?
Serverless app type and provider
The first thing to do is nail down the type of serverless app needed and which provider is best to host it.
Serverless computing runs code components variously known as microservices, functions or lambdas. Let's use functions, the most generic term, to reduce confusion. Typical serverless applications are either an event-handling application or a web front-end application.
In an event-handling application, externally or internally generated events trigger serverless function execution. In a web front-end application, a user triggers a function through a browser or mobile app interaction. Developers must know which model they'll follow before choosing their serverless design patterns.
The application's serverless platform is also a key consideration. While there are general rules for serverless function builds, the specific technique has to fit within the serverless framework provided by the cloud vendor. This is particularly important if you plan to use a cloud provider's workflow-building orchestration tools, such as AWS Step Functions, Microsoft Azure Logic Apps or any number of similar workflow techniques available in Google Cloud Platform. If you have a preferred cloud provider, examine how your serverless application would map to it.
Event-handling app design patterns
For event-handling applications, a baseline design pattern typically has a straightforward name, like the event-driven application pattern. This type of pattern should presume that a single event triggers the execution of a serverless function and that either no further events will be generated or that the processing of one event will selectively trigger another. That event can occur externally, generated by something like an IoT sensor, or occur because a cloud web service queued a task to be handled, such as text, image or video processing.
More complex event processing requires stateful event handling. This means some mechanism must be in place to control state in the application design without making serverless functions stateful -- which they cannot be, because they're not persistent. The specific mechanism used here again depends almost entirely on the chosen cloud provider.
With AWS Lambda, for example, use its event workflow design pattern. Complex events must avoid using synchronous -- call-and-wait-for-result -- practices, because these are difficult to orchestrate in a stateful framework. A generally useful model is a state machine design pattern integrated with the specific provider's serverless feature set.
Web front-end app design patterns
For the web model, the base design pattern is a microservices or services design pattern. This design pattern uses a function to provide the needed link to one or a few related HTTP events that represent a common HTTP endpoint. Here, an API gateway or service broker front-ends the function, which is invoked by the HTTP event -- get/post -- then frequently accesses an external data store. This architecture pattern is like a storefront design pattern adapted for serverless.
A more complex model for web and mobile support is the webhook design pattern, which uses a queue to hold work passed from the serverless function to a nonserverless back-end process set, including a hybrid cloud model where transaction processing takes place in the data center. Back-end congestion triggers a function to queue the work, rather than pass too much data to the back-end process. This general design pattern will work in any cloud, but tailor the implementation to match the cloud provider's back-pressure mechanism and queuing services.
Two architecture patterns related to webhook are also worth consideration. One is the first-in, first-out design pattern, which is used when a queue must be processed in this specific order. This processing order is usually required if the output work is multistep and stateful in nature, as many transactions are.
The other option is the request router design pattern. This pattern uses a function to examine input and relays it to another function depending on the request. This method works only for asynchronous functions, and it uses a front-end queue to hold input work that either cannot be dispatched immediately or overwhelm the function processing.
Put serverless design patterns to use
Serverless design patterns are useless until you classify the target application as either event-driven or web- or app-driven. This step helps you identify the primary suitable design patterns. Event-driven patterns are either simple event or stateful in most cases, and web models are variations on a storefront pattern.
Then, take that first-cut approach to the documentation pages of the target serverless provider, and see what specific tools and features they offer to support the app's operation. The tools and features of a serverless provider include things like queue tools, database tools and even API or service brokers. It's smart to fit your use of functions and serverless into and around these tools in order to simplify development and optimize the resulting application's scalability.
On the other hand, all these web service tools have a cost, and if you want to avoid spending money, you may need to find a distinct serverless architecture pattern that doesn't use them. For example, the request router design pattern can replace a proprietary offering like AWS Step Functions in some situations.
When developing the application, remember that serverless design patterns are different from the kinds of design patterns most developers typically used in conventional apps. Developers should think of serverless more like a method of charging for cloud services, rather than an architecture that dictates certain practices. As such, it can apply to nearly any software project with the proper effort.
Because serverless is still an emerging technology, different cloud providers have introduced platforms for it in different ways, and no neat and established design pattern cookbook exists just yet. In the meantime, use these recognized design patterns, and keep up to date on changes in serverless technology.