NML

Architectural Guidance

*A one-size-fits-all architecture is never optimal as there are many ways to skin the proverbial cat.

This guide describes types of systems based on their particular "special requirements", and then types of architectures and technologies to consider using when designing the solution for those systems.

NML Preferred Technology Stack

Development Languages

  • C# 7+
  • Typescript 3+
  • TSQL
  • HTML5 / JSX
  • CSS 2+

UX

  • HTML5
  • SASS
  • React (Hooks)
    • Motivation: Existing NML skillset. Good available tooling in NML IDEs. Component nature of React allows for UX composition, which makes design and implementation easier.
    • Redux
      • Redux Saga
        • Motivation: Simplified implementation for handling asynchronous side-effects
      • redux-thunk
        • Motivation: Best known implemantation for handling asychronous side effects
      • React RxJS
        • Motivation: Powerful but complicated implementation for handling asynchronous side effects
    • Final Form
      • Motivation: Easier form state and validation management for react forms.
  • Webpack
    • Motivation: The most popular JavaScript bundler that therefore also has the most online help available
  • ASP.Net Core MVC / ASP.Net Core SPA

Web Server

Transactional Applications

  • ASP.Net 5+
    • Motivation: Microsoft stack aligns with NML technologies. Well established and stable platform
    • If .Net 5 cannot be used: ASP.Net Core 3.1 or ASP.Net Framework 4.6.1+
  • MVC 5+
    • Razor Views if React is not used
    • Web API for REST API implementations

Caching

  • Azure Redis Cache
    • Motivation: Redis cache is an industry leading caching implementation and available as SaaS on Azure.

Static Sites

CMS

  • Netlify CMS
    • Motivation: Simple and easy to get started, although it's ruby/jenkins based and does not easily integrate with other NML technology stack items
  • Piranna CMS
    • Motivation: Well supported open source headless CMS that can be used as a service but also integrated directly with ASP.Net Core MVC.

Back-ends

Data

  • Azure SQL / MS SQL Server
    • Motivation: Aligns with the NML technology stack and is available as SaaS on Azure.
  • Cosmos DB
    • Motivation: Flexible document DB availble as SaaS on Azure.
  • Entity Framework Core / Entity Framework
    • Motivation: Widely accepted and Microsoft support ORM that support SQL Server and CosmosDB. Allows for code-first database design and has schema migrations and data seeding.

Messaging

  • Azure ServiceBus
    • Motivation: Fast, flexible reliable messaging platform that supports Queues and Topics for various messaging patterns, like pub/sub. Available as SaaS on Azure
  • Azure Storage Queues
  • RabbitMQ / CloudAMQP
    • Motivation: Fast flexible reliable messaging platform that support various messaging patterns, like pub/sub. Availble as SaaS on CloudAMQP.
  • NServiceBus
    • Motivation: Messaging patterns abstraction that enforces best practice asynchronous messaging architectures. Available as a licenced NuGet package.

Processing

  • Azure Logic Apps
    • Motivation: Flexible control flow with integration connectors to many systems. Visual designer for developing flows. SaaS on Azure.
  • Azure Functions
    • Motivation: Serverless execution that is easily scaled and support various triggering mechanisms, like schedules or REST calls.
  • Azure API Manager / Azure Front-door
    • Motivation: API consolidation and standardization from disparate sources.
  • Azure Traffic Manager
    • Helps with load balancing and/or fail-over configurations
  • Windows Services on VMs

General Preferred Dependencies

NPM

NUGET

General
  • Autofac for Dependency Injection
    • Motivation: Eases object lifetime management and allows for more flexible code.
  • Automapper for model mapping
    • Motivation: Allows for clean model separation between architectural boundaries.
Unit testing
  • NUnit
    • Motivation: NUnit is the community standard on unit testing in .Net.
  • Fake Data Generation
    • AutoBogus & Bogus
      • Motivation: It is an anti-pattern to hard-code test data of any sort as it can lead the passing unit tests because of developer bias.
    • AutoFixture
      • Motivation: It is an anti-pattern to hard-code test data of any sort as it can lead the passing unit tests because of developer bias.
  • Fluent Assertions
    • Motivation: Allows for more readable test assertions.

Technologies to avoid and replace

  • .Net Core 2.1, 2.2, 3.1
  • .Net Framework 4.8<
  • Unity dependency injection
  • jQuery
  • React alternatives (Vue.js, Preact.js, Angular)
  • JavaScript (over Typescript)
    • Motivation: Typescript produces code that is less likely to produce runtime errors.

Architectural guidance

Complex business rules

Requirement: Application with complicated business rules, especially business rules that may change often.

Event stream processing

Requirement: the system needs to take action based on a large number of inter-related events. For example, thousands of "person location update" events need to be processed in order to determine if two "friends" are close to one another.

Workflow with user-interaction

Requirement: the system has complicated workflows that include user interaction, for example: "Loan" message arrives at service, service calls another service to do a credit check, then a person has to review the request and "approve" or "deny" it.

  • Consider Azure Logic Apps and Functions, Power Automate
  • Unsure. Is there any good workflow technology out there?
  • Nasty option nr 1: BizTalk orchestrations
  • Nasty option nr 2: K2
  • Workflow Foundation with custom code to handle user interaction.
  • Custom implementation from scratch.

High load website

Requirement: public-facing website must be able to handle thousands of requests per minute. Data does not change frequently (i.e. a news site).

Remember, accessing data from the database or from a web service is slow. Often implementing these strategies make a big difference:

Reliable messaging

Requirement: the system must accept messages and return messages in a reliable way, ensuring no messages get lost, and ensuring that the system can endure temporary internet outages.

  • Consider using Azure Service Bus Queues (more feature-rich) or Azure Storage Queues (faster and simpler, but less features).
  • Use NServiceBus to get auto-retries, error queue monitoring and much more useful reliability, maintenance and monitoring features.
  • On VMs, consider using message queues instead of calling web services directly (the simplest kind is MSMQ built into Windows).

High availability

Requirement: Application must always be online.

  • Consider hosting in Azure (i.e. Azure Web Apps), but keep in mind that even Azure only has a 99.9% uptime guarantee, meaning as much as 40 minutes downtime per month.
  • Leverage Azure Traffic Manager configured for fail-over across multiple Azure Web Apps.
  • Use a load-balanced architecture with multiple servers, when one goes down, the other servers can pick up the slack. This requires a load balancer or use of the Azure Traffic Manager.
  • Have a hot-standby server ready to switch over to in-case the main server is unavailable. This can be triggered by an automated DNS switch-over.
  • Geo-replication: replicate the system to more than one physical location, and use DNS fail-over to switch to another location if the primary location becomes unavailable.

Strict security requirements

Requirement: Application is used in a Banking environment, and as such must be very secure.

  • Use HTTPS for all communications, do not allow HTTP.
  • Protect against cross-site forgery (XSRF) by using a XSRF-token on all HTML Forms.
  • Get a security audit from a company like Sensepost. They test software for vulnerabilities.
  • Do not allow common passwords (i.e. anything that contains the word "Password"). Check against a list like the following: 500 most common passwords.
  • Ensure authentication and authorization is done on all REST endpoints. This can be easy to overlook.

Very simple requirements

Requirement: Application is very simple, minimal business logic, mostly saving/loading of simple entities.

In this case, simpler architectures can be used to save time, but beware that these architectures generally don't "scale" well when the system gets more complex, so make extra sure that the system probably won't get more complicated in future.

  • Consider using a micro ORM, like Dapper or PetaPoco.
  • Consider using Active Record instead of a full-featured ORM.
  • For smaller projects, consider the NML repository pattern.

Cross-platform app

Requirement: Application must be available on many platforms including, i.e. Mac, PC, Android, iPhone and Windows Phone devices.

  • First choice is Progressive Web Apps.
  • Consider a technology like Ionic (cross platform ReactJS + Typescript)
  • Refer the client to an NML partner for native mobile application development.