What it is...

It is the foundation for you next project.

Out of the box, it ships with with the ability to register, login, change your password, reset your password, and manage users with role based permissions, show and hide content and actions based on feature flags. Four dashboard UI variations are available: Who is it for? The architecture, structure, and tooling are authored with developers in mind however, all are welcome to its use.

Quick Start Guide

For Macs:

For Windows:

Lay of the Land (Architecture Overview)

Backend
Most people like to start and the beginning. For this architecture primer however, i'll start at the backend (insert inapproriate joke here). This is where the meat and potatoes are, where all my favorite parts are, and where all the magic happens. Don't side eye me you sick bastards... I separated it into three projects. Core, Framework, and Types.

Types
It is exactly what you'd think it would be. The storage area for all the types that are shared across the projects. BTW, if you haven't guessed already, for good, bad, right, or wrong reasons, this project is written in TypeScript.

Core
Core is where all the abstractions reside. Where the fundamental decisions on structure and relationships are made explicit. Your authenticator, authority interfaces or abstracted classes are here, your logging interfaces, your implied non-side-effect free repositories are here. Your side-effect free data readers are inferred here. This is where you story board the plot and define the characters.

Framework
The Framework project is where you cast explicit actors. This is where 3rd party implementations and dependencies are kept. This is where your concrete implementation of providers and repositories go. Things like ddbUserRepository or your postgreSQL provider of tiddlywinks reside.

As a general rule, the core project should have no 3rd party dependencies. It's a pita, but it's worth it. Framework is where the bulk of dependencies are but that doesn't mean open season on dependencies. Be judicious and deliberate. This brings us to the next section...

IoC / Dependency Injection
There are a number of existing libraries and frameworks that provide IoC / Dependency Injection. All the ones i've looked at were full featured and extremely well made. That being said, for my purposes, I didn't need a full featured library that panders to every possible use case. I needed a simple, lightweight library that adhered to my preferred implementation patterns. So I wrote my own so I could do things like:

container.bind(SessionRepository).to(DynamoDbSessionRepository).asSingleton();
container.bind(ApiKeyRepository).to(DynamoDbApiKeyRepository).asSingleton();
container.bind(UserRepository).to(DynamoDbUserRepository).asSingleton();

container
	.bind(ApiLogger)
	.toFactory(() => {
		const logLevel = AppContainer.getLogLevelForEnvironment(AppContainer.getEnvironment());
		return new ApiLogger(logLevel);
	})
	.asSingleton();
Building it was surprisingly easy and quite pleasant to be honest. It was a quick TDD project. The grind was the build process. It required a fairly deep dive into the wild west of Typescsript compilers. Such a vast array of opinions and tooling for specific use cases. The desire was tooling that honored the typescript annotations. @#*$^*@#$ it was such a PITA but the result allowed cross cutting techniques like the following:
@Injectable()
export class UsersController extends BaseController {
	constructor(private userRepository: UserRepository, private router: Router) {
		super();
	}

	@Log()
	@Protected()
	@Route("GET", "/users/{userId}")
	async getUser(event: AuthenticatedALBEvent): Promise {
		// Parse and validate request
		const { params } = this.parseRequest(event, UserSchema);
		const { userId } = params;
Hypermedia API
A long, long, time ago in a beach town close, close by... we use to have lunch and learns at the company I worked for. We'd take turns presenting on a variety of topics or an exceptionally insightful video presentation. One of my favorite presentations was on a Hypermedia API and its use for cable boxes - https://vimeo.com/channels/374924/20781278.

The idea of having a front-end take direction from the API resonated with me. Having the front-end tooled to primarily take direction from the API but still allow for customization was a very alluring idea. Leveraging the HAL (Hypertext Application Language) specification, https://github.com/mikekelly/hal_specification, the Hypermedia API was built to support both xhtml and json. XHTML was chosen mostly for the purpose of providing a self-documenting API. Once you have a session established you can navigate the API and take a learning journey.

Frontend Frameworks
TBH, this is the portion I spent the least time on, thankfully there are a lot of great libraries and frameworks out there that makes it quite a bit easier to make something look decent with minimal effort. It has been quite awhile since i've been responsible for anything UI related. Four dashboard UI variations are available:

Get In Touch

There are going to be problems, bugs, and issues. Hit me up on GitHub or make a branch and submit a pull request. I will do my best to respond and address the issues as soon as possible.

  • Email

    kgar(at)serverlesslaunchpad(dot)com