Highly opinionated project template for Serverless Framework that follows and applies hexagonal architecture principle to serverless world. Prepared with easy testing in mind.

Overview

serverless-hexagonal-template

GitHub license GitHub stars PRs Welcome

Highly opinionated project template for Serverless Framework that applies hexagonal architecture principles to the serverless world. Crafted with easy testing in mind.

Quick start

This is a template from which you can create your own project by executing following command:

sls create --template-url https://github.com/serverlesspolska/serverless-hexagonal-template --name your-project-name

Next install dependencies:

cd your-project-name
npm i

and deploy to dev stage in default region:

sls deploy

High-level architecture

This template implements depicted below architecture. The application itself is just an example used to show you how to test serverless architectures.

You can easily modify the source code and tailor it to your needs. High-level architecture

Why use this template?

This template project was created with two goals in mind: streamlined developer's flow and easy testing, because, sadly, both are not common in serverless development yet.

Standardized structure

The project structure has been worked out as a result of years of development in Lambda environment using Serverless Framework. It also takes from the collective experience of the community (to whom I am grateful) embodied in books, talks, videos and articles.

This template aims to deliver common structure that would speed up development by providing sensible defaults for boilerplate configurations. It defines where what should be placed (i.e. source code in src/ folder, tests in __tests__ etc.) so you don't need to waste time on thinking about it every time you start new project and creates common language for your team members. Thus, decreasing cognitive overload when switching between projects started from this template.

Structure explanation

There are some guidelines in terms of folders structure and naming conventions.

Path Description Reason
./__tests__ default folder name for tests when using jest. Substructure of this folder follows exactly the ./src/ structure. Don't keep tests together with implementation. Easier to exclude during deployment. Easier to distinguish between code and implementation.
./config all additional config files for jest and deployment deployment.yml is included in serverless.yml, it is separate because when you have multiple microservices making single system they should share same stages and regions. Also you can put VPC configuration there.
./documentation You may keep here any documentation about the project.
./src Implementation code goes here This is a widespread convention.
./src/<functionName>/ Each Lambda function has it's own folder Better organization of the code.
./src/<functionName>/function.js Every file that implements Lambda's handler method is named function.js. The handler method name is always handler Easy to find Lambda handlers.
./src/common/ Place where common elements of implementation are stored. Most implementation code goes here. You should follow Single-responsibility principle. Makes testing possible and really easy!
./src/common/adapters/<name>Adapter.js For files implementing technical part of an Adapter in terms of Hexagonal Architecture This should be very generic i.e. class that allows connections to MySQL without any particular SQL code that you want to execute in your usecase.
./src/common/entities/<EntityName>.js Here you keep files that represent objects stored in your repository (database) Useful when you use database 😉
./src/common/services/<name>Service.js For files implementing business part of an Adapter in terms of Hexagonal Architecture This service uses corresponding <name>Adapter.js adapter or adapters. You would put a specific SQL code here and pass it to adapter instance to execute it.

After working a lot with that structure I saw a pattern emerging that <name>Adapter.js together with <name>Service.js they both implement an adapter in terms of Hexagonal Architecture. Moreover, usually well written adapters (<name>Adapter.js) can be reused among different projects (can be put into separate NPM package).

File naming conventions

If a file contains a class it should be named starting with big letter i.e StorageService.js. If file does not contain a class but one or many JavaScript functions name start from small letter i.e s3Adapter.js.

Hexagonal architecture

Design of the code has been planned with hexagonal architecture in mind. It allows better separation of concerns and makes it easier to write code that follows single responsibility principle. Those are crucial characteristics that create architectures which are easy to maintain, extend and test.

Easy testing

Tests are written using jest framework and are divided into three separate groups:

  • unit
  • integration
  • end to end (e2e)

Testing diagram Note: Unit tests not shown on the diagram for clarity.

Unit tests

Those tests are executed locally (on developers computer or CI/CD server) and don't require access to any resources in the AWS cloud or on the Internet.

Unit tests are ideal to test your business logic. You may also decide to test your services (located at src/common/services). Both are really easy to do when using hexagonal architecture.

Please don't mock whole AWS cloud in order to test everything locally. This is wrong path. Just don't do that. 😉

npm run test

Integration tests

Integration tests focus on pieces of your code (in OOP I'd say classes), that realize particular low & mid level actions. For example your Lambda function may read from DynamoDB, so you would write a service and adapter modules (classes) that would implement this functionality. Integration test would be executed against real DynamoDB table provisioned during deployment of that project. However the code will be running locally (on you computer or CI/CD server).

Integration tests

Those tests require resources in the cloud. In order to execute them you first need to deploy this project to AWS.

sls deploy
npm run integration

Those commands deploy project to the cloud on dev stage and execute integration tests.

The npm run integration command executes underneath the serverless-export-env plugin that exports environment variables set for each Lambda function in the cloud. Results of that command are saved locally to the .awsenv file. This file is later injected into jest context during tests.

There is also a shortcut command that executes tests but doesn't execute serverless-export-env plugin. It requires the .awsenv file to be already present. Since environment variables don't change that often this can save you time.

npm run int

End to end tests (e2e)

End to end tests focus on whole use cases (from beginning to the end) or larger fragments of those. Usually those tests take longer than integration tests.

An example of such test would be POST request sent to API Gateway /item endpoint and a check if processItem Lambda function was triggered by DynamoDB Streams as a result of saving new item by createItem Lambda function invoked by the request. Such approach tests chain of events that happen in the cloud and gives confidence that integration between multiple services is well configured.

e2e test

This test is implemented in __tests__/processItem/functionIsTriggeredByDdbStream.e2e.js

You can test it yourself by executing:

npm run e2e

Run all tests

Convenience command has been added for running all test. Please bare in mind it requires deployed service.

npm run all

DEBUG mode

If you want to see logs when running tests on your local machines just set environment variable DEBUG to value ON. For example:

DEBUG=ON npm run test
 # or
DEBUG=ON npm run integration

GUI / acceptance tests

End to end tests are not a substitution to GUI or acceptance tests. For those other solutions (such as AWS CloudWatch Synthetics) are needed.

Deployment

Deployment to dev stage.

sls deploy

Deployment to a specific stage

sls deploy -s <stage> # stage = dev | test | prod

What's included?

Serverless Framework plugins:

Node.js development libraries:

  • AWS SDK
  • Eslint with modified airbnb-base see .eslintrc.yml
  • Jest
  • dotenv
  • aws-testing-library for end to end testing
  • serverless-logger
You might also like...

Tailwind & Next Mentorship Template

This is a Next.js project bootstrapped with create-next-app. Getting Started First, run the development server: npm run dev # or yarn dev Open http://

May 22, 2022

Template to create reactjs component library which will help you to create your dream library.

reactjs-library-template Template to create reactjs component library which will help you to create your dream library. How to use Commands to setup e

Dec 25, 2021

Low tech template for a reduced carbon impact :seedling:

Enverse minimalist front-end template 🌱 🌱 For all else, use Astro.build 😃 Recomended package manager: pnpm Preact + Typescript + Vite How to use: F

Jan 10, 2022

Obsidian To HTML, A template for building obsidian style notes to a static site

oth (Obsidian To HTML) This is a template for publishing obsidian notes as a static site. The goal of the project is to stay minimal, since this is a

Nov 4, 2022

My discord.js bot template

My discord.js Bot Template This repository is an ongoing project to extract core pieces of the discord.js bots and ecosystems I run into a reusable te

Mar 3, 2022

A tiny javascript templating framework in ~400 bytes gzipped

t.js A tiny javascript templating framework in ~400 bytes gzipped t.js is a simple solution to interpolating values in an html string for insertion in

Dec 29, 2022

HTML Framework that allows you not to write JavaScript code.

HTML Framework that allows you not to write JavaScript code.

EHTML (or Extended HTML) can be described as a set of custom elements that you can put on HTML page for different purposes and use cases. The main ide

Dec 22, 2022

A helper to send whatsapp without scheduling a contact, the project developed using TDD with Jest, Javascript classes, BotstrapVue and SweetAlert.

Project setup npm install Compiles and hot-reloads for development npm run serve Compiles and minifies for production npm run build Lints and fixes

Sep 13, 2022

three.js + haxe starter project

three.js + haxe starter project

Haxe + three.js starter project This is a batteries-included template project using three.js with the haxe language. Main.hx sets up a physically base

Nov 24, 2022
Comments
  • Merge main to master

    Merge main to master

    • deps: bump up

    • deps: bump up jest & eslint

    • deps: bump up ksuid

    • deps: bump up axios

    • deps: bump up middy to 2.5.7

    • deps: bump up middy to 3.1.0

    Co-authored-by: Pawel Zubkiewicz [email protected]

    opened by serverlesspolska 0
Owner
Paweł Zubkiewicz
Paweł Zubkiewicz
Semi-embedded JS template engine that supports helpers, filters, partials, and template inheritance. 4KB minzipped, written in TypeScript ⛺

squirrelly Documentation - Chat - RunKit Demo - Playground Summary Squirrelly is a modern, configurable, and blazing fast template engine implemented

Squirrelly 451 Jan 2, 2023
The fastest + concise javascript template engine for nodejs and browsers. Partials, custom delimiters and more.

doT Created in search of the fastest and concise JavaScript templating function with emphasis on performance under V8 and nodejs. It shows great perfo

Laura Doktorova 4.9k Dec 31, 2022
Embedded JS template engine for Node, Deno, and the browser. Lighweight, fast, and pluggable. Written in TypeScript

eta (η) Documentation - Chat - RunKit Demo - Playground Summary Eta is a lightweight and blazing fast embedded JS templating engine that works inside

Eta 682 Dec 29, 2022
eXtensible Template Engine lib for node and the browser

xtemplate High Speed, eXtensible Template Engine lib on browser and nodejs. support async control, inheritance, include, logic expression, custom func

xtemplate 553 Nov 21, 2022
Examples of how to re-create the WordPress Template Hierarchy using headless clients and WPGraphQL

WPGraphQL Template Hierarchy Debugger This is a project to demonstrate how to re-create the WordPress template hierarchy with Headless WordPress using

Jason Bahl 17 Oct 29, 2022
A template to be used for creating js/scss projects and deploy them to github pages

A template to be used for creating js/scss projects and deploy them to github pages

Cariera în IT 15 Oct 30, 2022
Pug – robust, elegant, feature rich template engine for Node.js

Pug Full documentation is at pugjs.org Pug is a high-performance template engine heavily influenced by Haml and implemented with JavaScript for Node.j

Pug 21.1k Dec 30, 2022
Take a swig of the best template engine for JavaScript.

NOT MAINTAINED Fork and use at your own risk. Swig Swig is an awesome, Django/Jinja-like template engine for node.js. Features Available for node.js a

Paul Armstrong 3.1k Jan 4, 2023
Script Template Fivem in Type Script

fivem-ts ?? A Typescript Template for FiveM ?? This is a basic template for creating a FiveM resource using Typescript. It includes webpack config fil

Vinícius Pereira 3 Jun 11, 2021
A K6 Multi Scenario template applying some best practices along some examples

K6-Multi-Scenario-Template It is a performance testing template that shows how to use K6 to implement a Multi Scenario template applying some best pra

Swiss Life OSS 33 Nov 27, 2022