*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
- C# 7+
- Typescript 3+
- HTML5 / JSX
- CSS 2+
- 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.
- Final Form
Motivation:Easier form state and validation management for react forms.
- ASP.Net Core MVC / ASP.Net Core SPA
- 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
- Azure Redis Cache
Motivation:Redis cache is an industry leading caching implementation and available as SaaS on Azure.
- 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.
- 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.
- 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.
Motivation:Messaging patterns abstraction that enforces best practice asynchronous messaging architectures. Available as a licenced NuGet package.
- 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
- redux-saga / redux-thunk / React RxJS
- Final Form
Motivation:Browser based mock REST service for unit testing or local environments.
- 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.
Motivation:NUnit is the community standard on unit testing in .Net.
- Fake Data Generation
- 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
- React alternatives (Vue.js, Preact.js, Angular)
Motivation:Typescript produces code that is less likely to produce runtime errors.
Complex business rules
Requirement: Application with complicated business rules, especially business rules that may change often.
Consider using DDD architecture.
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.
- Consider using Azure Event Hubs.
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:
- Azure Web App with a scaled App Service Plan and increased number of instances.
- Azure Redis Cache
- In memory caching
- Azure Traffic Manager configured for load, with multiple Azure WebApps
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).
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.
Requirement: Application must be available on many platforms including, i.e. Mac, PC, Android, iPhone and Windows Phone devices.