A proof of concept API to explore best-practices and new ideas
Explore the docs »
View Demo
·
Report Bug
·
Request Feature
Table of Contents
A proof of concept API to explore best-practices and new ideas
This application depends on Docker for databases and an API deployment location.
Docker install and setup details can be found here: Local Docker
The design of this application was based upon the OpenAPI specification, found in the shared\PilotSharedSource directory (which is a submodule of PilotSharedSource).
-
Clone the repo (including submodules)
git clone --recurse-submodules https://github.com/MikeLooper/PilotApiDotNet.git -
If the repository was cloned without submodules, initialize them:
git submodule update --init --recursive -
Open the .sln file in Visual Studio.
-
Press F5 to build and run the application.
This repository includes PilotSharedSource as a Git submodule at shared/PilotSharedSource/.
To pull the latest submodule changes from its tracked branch:
git submodule update --remote --recursive shared/PilotSharedSource
After updating, commit the changed submodule pointer in this repository:
git add shared/PilotSharedSource .gitmodules
git commit -m "Update PilotSharedSource submodule"
When Executing locally, a User Secrets file will be needed to provide local connection details.
This User Secrets file will look like the following:
{
"Application": {
"DataConnections": [
{
"Active": true,
"ConnectTimeout": 30,
"DataSourceName": "NorthWind_SQL",
"Host": "localhost",
"Password": "<DevUser password for SQL Server>",
"Port": 1433,
"UserName": "DevUser"
},
{
"Active": false,
"ConnectTimeout": 30,
"DataSourceName": "NorthWind_Pgs",
"Host": "localhost",
"Password": "<DevUser password for PostgreSQL>",
"Port": 5432,
"UserName": "DevUser"
}
],
"OpenTelemetry": {
"Server": "localhost",
"Port": 4318
}
}
}
The User Secrets file is located at %APPDATA%\Microsoft\UserSecrets\<user_secrets_id>\secrets.json.
The application configuration is broken into three files:
- appsettings.json
- appsettings.Development.json
- appsettings.Production.json
This separation simplifies changing which data connection is active for a specific deployment and provides separated locations for sensitive values.
The data source values for Development are included in the local development config file, which can be found in the Web project:
- appsettings.Development.json
The data source values for Production are included in the docker-deploy config files, as noted here:
- SQL Server:
- ..\docker\SqlServer\appsettings.Production.json
- PostgreSQL:
- ..\docker\PostgreSQL\appsettings.Production.json
{
"Application": {
"DataSources": [
{
"Active": true,
"DataSourceName": "NorthWind_SQL",
"DataSource": "NorthWind",
"DataSourceType": "SqlServer",
"Schema": "dbo"
},
{
"Active": true,
"DataSourceName": "NorthWind_Pgs",
"DataSource": "northwind",
"DataSourceType": "PostgreSQL",
"Schema": "pilot"
}
],
"OpenApi": {
"Title": "PilotApiDotNet",
"Contact": {
"Email": "MikelLooper@gmail.com",
"Name": "Michael Looper",
"URL": "https://github.com/MikeLooper/PilotApiDotNet"
},
"Description": "A proof of concept API to explore best-practices and new ideas (.NET/C#)",
"License": "MIT",
"Summary": "Proof of concept API",
"Version": "0.1.1"
},
"OpenTelemetry": {
"Server": "otel-collector",
"Port": 4318
}
},
"Serilog": {
"MinimumLevel": {
"Default": "Information",
"Override": {
"Microsoft": "Warning",
"Microsoft.AspNetCore.Hosting.Diagnostics": "Error",
"Microsoft.Hosting.Lifetime": "Information",
"System": "Warning"
}
},
"WriteTo": [
{ "Name": "Console" },
{
"Name": "File",
"Args": {
"path": "logs/log-.json",
"rollingInterval": "Day",
"rollOnFileSizeLimit": true,
"fileSizeLimitBytes": 104857600,
"retainedFileCountLimit": 14,
"formatter": "Serilog.Formatting.Compact.CompactJsonFormatter, Serilog.Formatting.Compact"
}
}
],
"Enrich": [
"FromLogContext",
"WithMachineName",
"WithProcessId",
"WithThreadId",
"WithExceptionDetails"
]
},
"AllowedHosts": "*"
}{
"Application": {
"DataConnections": [
{
"Active": true,
"ConnectTimeout": 30,
"DataSourceName": "NorthWind_SQL",
"Host": "local_mssql",
"Password": "<DevUser password>",
"Port": 1433,
"UserName": "DevUser"
},
{
"Active": false,
"ConnectTimeout": 30,
"DataSourceName": "NorthWind_Pgs",
"Host": "local_postgres",
"Password": "<DevUser password>",
"Port": 5432,
"UserName": "DevUser"
}
]
}
}The configuration that controls the application logic is in the "Application" section.
An array of data connections settings.
Is the current section of settings active? Available options: true, false.
Within the DataConnections section, only one setting group can be active at one time.
The number of seconds for the data source timeout.
The name of the current data source section.
This name will match A DataSources.DataSourceName setting.
The name of the host for the data source.
When running locally for development, this value would typically be "localhost".
When deployed to a Docker container, this value would typically be the name of the data source container.
Examples: "local_mssql", "local_postgres"
The password for the user for the data source.
The active port for the target data source.
The name of the user for the data source.
The available data sources (such as a database).
Is the current section of settings active? Available options: true, false.
The name of the current data source section.
This name will match A DataConnections.DataSourceName setting.
The name of the data source, such as a database name.
The type of data source. Available values: "SqlServer", "PostgreSQL"
The schema where the target tables would be found.
The settings that control how the OpenAPI specification is define within the application.
These values will typically appear in an API UI or in an extracted OpenAPI specification.
The API title.
A section of settings regarding who the point of contact is for this application.
The email address of the contact person.
The name of the contact person.
A web address relating to the contact person.
A description of this API.
The license relating to the source code for this application.
A summary of this API.
The application version.
The settings that control how OpenTelemetry (OTEL) is configured within the application.
The OpenTelemetry server address.
The OpenTelemetry server port.
When troubleshooting OTEL, you can check for port usages, at the command line:
netstat -ano | findstr 4318
When working correctly, this will result in something similar to the following:
Proto Local Address Foreign Address State PID
...
TCP 0.0.0.0:4318 0.0.0.0:0 LISTENING 25384
TCP [::]:4318 [::]:0 LISTENING 25384
TCP [::1]:4318 [::]:0 LISTENING 46888
TCP [::1]:4318 [::1]:59028 TIME_WAIT 0
...
The, start the command (via Win+R) the resmon.exe application. Locate the PID, from the port listing, on the PID column.
Examples fro the above:
| PID | Application |
|---|---|
| 25384 | Docker Desktop Backend |
| 46888 | Windows Subsystem for Linux |
You can also add tracing with this command, added to the PilotApi.Shared.OpenApi.Extensions.OpenTelemetryExtensions.OpenTelemetryWebApplicationBuilder(...) method.
OpenTelemetry.Sdk.SetDefaultTextMapPropagator(new TraceContextPropagator());
This application will be deployed to a Docker container. Deploy instructions can be found in the Docker README.
Once deployed to Docker, the application will be accessible at https://localhost:55551/....
For Exmaple, the Categories endpoint for GetAll will be accessible at http://localhost:55551/categories/get-all.
The API contract for this project is defined in the OpenAPI specification file located at docs/openapi.yaml.
You can use this file to generate client code or to explore the API using tools like Swagger UI or Bruno.
To get a visual representation of the API, you can use the Swagger editor by navigating to https://editor.swagger.io/.
You can also interact with the API using the Swagger UI by navigating to https://localhost:5001/swagger after running the application locally with Visual Studio.
- API (.NET) version of the API (this code)
- Java version of the API
- Deploy API to Docker
- Angular Frontend User Interface (UI) to consume APIs in Docker
See the open issues for a full list of proposed features (and known issues).
Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated.
If you have a suggestion that would make this better, please fork the repo and create a pull request. You can also simply open an issue with the tag "enhancement". Don't forget to give the project a star! Thanks again!
- Fork the Project
- Create your Feature Branch (
git checkout -b feature/AmazingFeature) - Commit your Changes (
git commit -m 'Add some AmazingFeature') - Push to the Branch (
git push origin feature/AmazingFeature) - Open a Pull Request
This repository uses two Copilot instruction layers:
- Repository-wide guidance:
.github/copilot-instructions.md - Unit-test-specific guidance:
.github/instructions/unit-tests.instructions.md
How to use them:
- The repository-wide file is intentionally minimal and applies across all work.
- The unit-test file is scoped to
test/**/*.csand applies to unit test creation and maintenance tasks. - For unit test work, follow the NUnit and test-structure rules in the scoped instruction file.
Distributed under the MIT License. See LICENSE.txt for more information.
Michael Looper - MikelLooper@gmail.com
Project Link: https://github.com/MikeLooper/PilotApi