Date: 2021-09-10
Accepted
The primary focus from a development standpoint thusfar has been to assemble a functional "walking skeleton." The aim has been to stand up the various, interconnected subsystems according to the proposed high-level architecture, with the hope that this would allow the ATO process to begin earlier.
As we move closer to the eventual handoff of this project to a vendor, it is becoming more important that we establish a consistent software architecture to be applied where applicable across the various subsystems.
We will adopt a standard architecture for the following subsystems:
dashboard
etl
match
metrics
query-tool
For each subsystem, there will be a standard set of projects and project relationships. The following diagram illustrates the standard arrangement for a hypothetical subsystem called Subsystem. The arrows indicate a project-level dependency (e.g. Piipan.Subsystem.Core
depends on Piipan.Subsystem.Api
).
The purpose of this project is to expose the public interfaces and data models for the subsystem. Typically, this would consist of the interface for each of the subsystem APIs along with all of the request and response objects necessary for interacting with those APIs. This project should contain no implementation - only plain old CLR objects and C# interfaces. As such, no tests are needed for this project.
The purpose of this project is to provide the core functionality for the subsystem. This is a pure .NET class library with no dependencies on web frameworks such as Microsoft.NET.Sdk.Functions or Microsoft.AspNetCore.Mcv.
At the top level, the Core
library should provide implementations for each of the API interfaces exposed in the API
library.
The purpose of this project is to expose the API for this subsystem to external callers. This may take the form of an Azure Function, a .NET Web API, a .NET web application, etc. In any case, this project should be restricted to managing the interaction with its particular framework. In the case of an Azure Function or Web API, this means simply handling authentication/authorization, parsing incoming HTTP requests, invoking Core
services, and serializing HTTP responses.
The purpose of this project is to provide implementations for each of the API interfaces exposed in the API
library. Unlike the implementations in the Core
library, these are HTTP client implementations which interact with the corresponding web service or function app for this subsystem. If there is no HTTP service for a particular subsystem, this project should be omitted.
We expect that adopting a consistent subsystem architecture will ease the onboarding process for new developers and perhaps reduce the amount of documentation required for each subsystem.
Additionally, decoupling subsystem logic and data access from particular HTTP and Azure frameworks will make the system as a whole more portable -- in theory, only the .[Func,Web]
project would need to be replaced to change or extend the operating environment for a subsystem (e.g. to run as a Web API instead of an Azure Function).
Lastly, we expect that implementing the Core
logic as a standalone library will improve our ability to extend and test subsystem functionality.