Skip to content

Commit 6fb72bc

Browse files
committed
chore: api doc
1 parent 2ea0c0a commit 6fb72bc

File tree

7 files changed

+127
-6
lines changed

7 files changed

+127
-6
lines changed
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
using Microsoft.Extensions.Options;
2+
using Microsoft.OpenApi.Models;
3+
using Swashbuckle.AspNetCore.SwaggerGen;
4+
5+
namespace StrDss.Api
6+
{
7+
public class ConfigureSwaggerOptions : IConfigureOptions<SwaggerGenOptions>
8+
{
9+
/// <summary>
10+
/// Initializes a new instance of the <see cref="ConfigureSwaggerOptions"/> class.
11+
/// </summary>
12+
/// <param name="options">The options specified by <see cref="SwaggerGenOptions"/> object</param>
13+
/// <inheritdoc />
14+
public void Configure(SwaggerGenOptions options)
15+
{
16+
17+
// Create Swagger documents per version and consumer
18+
options.SwaggerDoc(Common.ApiTags.Default, CreateInfoForApiVersion(Common.ApiTags.Default, "StrData"));
19+
options.SwaggerDoc(Common.ApiTags.Aps, CreateInfoForApiVersion(Common.ApiTags.Aps, $"StrData {Common.ApiTags.Aps}"));
20+
21+
// Include all paths
22+
options.DocInclusionPredicate((name, api) => true);
23+
24+
// Filter endpoints based on consumer
25+
options.DocumentFilter<SwaggerDocumentFilter>();
26+
27+
// Take first description on any conflict
28+
options.ResolveConflictingActions(apiDescriptions => apiDescriptions.First());
29+
}
30+
31+
static OpenApiInfo CreateInfoForApiVersion(string version, string title)
32+
{
33+
var info = new OpenApiInfo()
34+
{
35+
Title = title,
36+
Version = version
37+
};
38+
39+
return info;
40+
}
41+
}
42+
}

server/StrDss.Api/Controllers/OrganizationsController.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using StrDss.Model;
77
using StrDss.Model.OrganizationDtos;
88
using StrDss.Service;
9+
using Swashbuckle.AspNetCore.Annotations;
910

1011
namespace StrDss.Api.Controllers
1112
{
@@ -44,7 +45,15 @@ public async Task<ActionResult<List<DropdownNumDto>>> GetOrganizationsDropdown(s
4445
return Ok(await _orgService.GetOrganizationsDropdownAsync(type));
4546
}
4647

47-
[ApiAuthorize]
48+
/// <summary>
49+
/// Retrieves the Short-Term Rental (STR) requirements for a specified location based on longitude and latitude coordinates.
50+
/// Validates the geographical boundaries of the input values to ensure they fall within acceptable ranges.
51+
/// </summary>
52+
/// <param name="longitude">The longitude of the location, must be between -180 and 180 degrees.</param>
53+
/// <param name="latitude">The latitude of the location, must be between -90 and 90 degrees.</param>
54+
/// <returns>An object containing STR requirements for the given location, or a validation error if the input is invalid.</returns>
55+
[ApiAuthorize] //todo: specify permission
56+
[SwaggerOperation(Tags = new string[] { Common.ApiTags.Aps })]
4857
[HttpGet("strrequirements", Name = "GetStrRequirements")]
4958
public async Task<ActionResult<StrRequirementsDto>> GetStrRequirements(double longitude, double latitude)
5059
{

server/StrDss.Api/Program.cs

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@
1818
using StrDss.Service.Bceid;
1919
using Npgsql;
2020
using Serilog;
21-
using Microsoft.AspNetCore.Authentication;
21+
using Microsoft.Extensions.Options;
22+
using Swashbuckle.AspNetCore.SwaggerGen;
23+
using StrDss.Common;
2224

2325
var builder = WebApplication.CreateBuilder(args);
2426

@@ -158,7 +160,15 @@
158160

159161
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
160162
builder.Services.AddEndpointsApiExplorer();
161-
builder.Services.AddSwaggerGen();
163+
builder.Services.AddTransient<IConfigureOptions<SwaggerGenOptions>, ConfigureSwaggerOptions>();
164+
builder.Services.AddSwaggerGen(options =>
165+
{
166+
options.EnableAnnotations();
167+
options.UseAllOfToExtendReferenceSchemas();
168+
var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
169+
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
170+
options.IncludeXmlComments(xmlPath);
171+
});
162172

163173
var healthCheck = new HealthCheck(connString);
164174
builder.Services.AddHealthChecks().AddCheck("DbConnection", healthCheck);
@@ -168,8 +178,18 @@
168178
// Configure the HTTP request pipeline.
169179
if (app.Environment.IsDevelopment())
170180
{
171-
app.UseSwagger();
172-
app.UseSwaggerUI();
181+
app.UseSwagger(option =>
182+
{
183+
option.RouteTemplate = "api/swagger/{documentName}/swagger.json";
184+
});
185+
186+
app.UseSwaggerUI(option =>
187+
{
188+
option.SwaggerEndpoint($"/api/swagger/{ApiTags.Default}/swagger.json", ApiTags.Default);
189+
option.SwaggerEndpoint($"/api/swagger/{ApiTags.Aps}/swagger.json", ApiTags.Aps);
190+
191+
option.RoutePrefix = "api/swagger";
192+
});
173193
}
174194

175195
app.UseHealthChecks("/healthz");

server/StrDss.Api/StrDss.Api.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
<TargetFramework>net7.0</TargetFramework>
55
<Nullable>enable</Nullable>
66
<ImplicitUsings>enable</ImplicitUsings>
7+
<GenerateDocumentationFile>True</GenerateDocumentationFile>
78
</PropertyGroup>
89

910
<ItemGroup>
@@ -19,6 +20,7 @@
1920
<PackageReference Include="Serilog.AspNetCore" Version="7.0.0" />
2021
<PackageReference Include="Serilog.Extensions.Logging" Version="7.0.0" />
2122
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
23+
<PackageReference Include="Swashbuckle.AspNetCore.Annotations" Version="6.7.3" />
2224
</ItemGroup>
2325

2426
<ItemGroup>
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
using Microsoft.OpenApi.Models;
2+
using Swashbuckle.AspNetCore.SwaggerGen;
3+
4+
namespace StrDss.Api
5+
{
6+
public class SwaggerDocumentFilter : IDocumentFilter
7+
{
8+
public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
9+
{
10+
// Key is read-only so make a copy of the Paths property
11+
var pathsPerConsumer = new OpenApiPaths();
12+
var referencedSchemas = new HashSet<string>();
13+
14+
if (swaggerDoc.Info.Version == Common.ApiTags.Aps)
15+
{
16+
foreach (var path in swaggerDoc.Paths)
17+
{
18+
// If there are any tags (all methods are decorated with "SwaggerOperation(Tags = new[]...") with the current consumer name
19+
var p = path.Value?.Operations?.Values?.FirstOrDefault();
20+
if (p != null && p.Tags
21+
.Where(t => Common.ApiTags.ApsTagList.Contains(t.Name)).Any())
22+
{
23+
// Add the path to the collection of paths for current consumer
24+
pathsPerConsumer.Add(path.Key, path.Value);
25+
}
26+
}
27+
28+
29+
}
30+
else
31+
{
32+
foreach (var path in swaggerDoc.Paths)
33+
{
34+
if (path.Key != null && path.Value != null) pathsPerConsumer.Add(path.Key, path.Value);
35+
}
36+
}
37+
38+
swaggerDoc.Paths = pathsPerConsumer;
39+
}
40+
}
41+
}

server/StrDss.Common/Constants.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -356,4 +356,11 @@ public static class ListingExportFileNames
356356
public const string All = "BC";
357357
public const string AllPr = "BC_PR";
358358
}
359+
360+
public static class ApiTags
361+
{
362+
public const string Default = "stadata";
363+
public const string Aps = "aps";
364+
public static readonly string[] ApsTagList = { "aps" };
365+
}
359366
}

server/StrDss.Data/Repositories/OrganizationRepository.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ FROM dss_organization
140140
OrganizationNm = o.OrganizationNm,
141141
IsPrincipalResidenceRequired = o.IsPrincipalResidenceRequired,
142142
IsBusinessLicenceRequired = o.IsBusinessLicenceRequired,
143-
IsStrProhibited = null
143+
IsStrProhibited = null //todo: map with the new column
144144
})
145145
.OrderBy(o => o.OrganizationNm)
146146
.FirstOrDefaultAsync();

0 commit comments

Comments
 (0)