Setting boundaries in your serverless application

AWSArchitectureSoftware EngineeringDaily Email

Arguably the main job of a software architect is drawing boundaries in the right places.

We love to discuss the why, when and how of splitting things up — monorepo vs multi-repos, single vs multi-table DynamoDB models, the pros and cons of Domain-Driven Design and fat vs single-purpose Lambda functions.

A case in point is this Twitter poll I ran last week about a particular hybrid style of serverless architecture that sparked a few interesting threads:

Twitter poll results on serverless architecture style

As you can see from the poll results, opinions were split. Here’s a selection of questions and observations from the replies:

  • “Do all Lambda functions talk to a single shared database schema?”
  • “Are there multiple bounded contexts within the system?”
  • “Are there any asynchronously triggered Lambda functions?”
  • “Are all Lambda functions in the same monorepo?”
  • “The separation of functions allow for some fine-grained scaling and security benefits, but all business concerns are tightly coupled and can not be deployed, managed, or scaled independently.”
  • “Microservices architecture deployed monolithically”
  • “Monolith because an entire api should probably be split in to domain specific serverless.yaml”
  • “Wouldn’t you say it’s a microservice if the single API serves a single, concise purpose?”
  • “Monolith probably doesn’t fit, but is it otherwise a single “micro”-service?”
  • “This is almost a hybrid of standard application deployment with microservice infrastructure.”

Of course, being the internet there were a few snarky condemnations for not following their favoured dogma in its purest form.

The terminology doesn’t really matter but understanding your context well does

While having a concise name to describe a high-level architectural pattern is nice, it’s not the most important thing. Building a system that’s valuable to its users and sustainable in the long term is.

To do so, you need a strong appreciation of the entire context in which the system will be built and operated. But there are so many complicating factors within this context that will influence any boundary-drawing decisions you make. Let’s look at several questions you’ll need to consider:

  • Organisational constraints:

    • How many engineers are available to work on the project team?
    • Will there be more than one engineering team working on the project?
    • Could these engineers potentially be working on other projects simultaneously? And will they be the ones supporting it into production?
    • How familiar is the team with general DevOps practices?
    • How familiar is the team with the main AWS serverless services?
    • Are application developers full-stack or are front and back-end developers primarily separate roles?
  • Project/Application constraints:

    • How well defined is the problem domain and its associated user stories at the project outset?
    • What is the projected growth of the application?
    • What time pressures are there on project delivery?
    • What in-house legacy systems do we need to integrate with?
    • What third-party services do we need to integrate with?
    • Are there any special low-latency requirements?
    • Does sensitive user data need to be processed or stored?

There are a lot of questions I haven’t stated and many questions will lead to further questions. And so on.

No two custom software development projects are the same, so why do many folks try to fit a system into their preferred strict architectural style? Which leads me to my main point…

Cherry-picking aspects of mono, micro and nano is a valid approach

In fact, this is my standard approach when starting a new greenfield project.

Neither monoliths nor microservices (nor nanoservices) have “won” the argument for the best architecture style to build production software systems. So being a dogmatic adherent to one over the others is doing a disservice to the rest of your project team.

While you will probably have a preference for one style, you don’t need to go all-in on it, especially at the start of a project. I’m sure the architect who starts out by creating separate Git repositories and CI/CD pipelines for every individual single-purpose Lambda function is a nice guy but I cannot envision any project in which this would ever make sense.

On the other hand, you could initially identify a few bounded contexts and keep them in their own separately deployable service but still store them all in a single monorepo. Or you might start with a single CI/CD pipeline that deploys all the services together but at a later stage you can work on giving each service their own pipeline.

These are perfectly good decisions provided they’re made with the understanding of the trade-offs in your own context.

There’s that context word again…

— Paul.

Originally published .

Other articles you might enjoy:

Free Email Course

How to transition your team to a serverless-first mindset

In this 5-day email course, you’ll learn:

  • Lesson 1: Why serverless is inevitable
  • Lesson 2: How to identify a candidate project for your first serverless application
  • Lesson 3: How to compose the building blocks that AWS provides
  • Lesson 4: Common mistakes to avoid when building your first serverless application
  • Lesson 5: How to break ground on your first serverless project

    ☎️ Serverless AMA

    Need quick guidance on a specific issue on your AWS serverless project? Or just wondering where to start with serverless?

    Book a call and ask me anything.

    Learn more >>

    🛫 Serverless Launchpad

    Ready to start building your new AWS serverless project but need help with getting everything setup?

    The Serverless Launchpad is a done-for-you DevOps service installed in under a week. You get a leading-practice multi-account AWS environment, a scaffolded codebase and architecture including the common AWS serverless services, isolated cloud environments for individual developers, automated delivery pipelines right through to production and much more. Everything is IaC, extensively documented and handed over to your developers.

    Learn more >>