Skip to content
This repository has been archived by the owner on Aug 27, 2024. It is now read-only.

Commit

Permalink
Provide minimal API (#20)
Browse files Browse the repository at this point in the history
* Ignore API docs

Signed-off-by: Tom Kerkhove <kerkhove.tom@gmail.com>

* Create minimal API with health endpoint and Open API docs

Signed-off-by: Tom Kerkhove <kerkhove.tom@gmail.com>

* Remove version in general API docs

* Add welcome + refactor

Signed-off-by: Tom Kerkhove <kerkhove.tom@gmail.com>

* Improve docs

Signed-off-by: Tom Kerkhove <kerkhove.tom@gmail.com>
  • Loading branch information
tomkerkhove committed Jan 3, 2019
1 parent 929e6ff commit 47b7e66
Show file tree
Hide file tree
Showing 12 changed files with 286 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -328,3 +328,4 @@ ASALocalRun/

# MFractors (Xamarin productivity tool) working folder
.mfractor/
/src/Arcus.EventGrid.Sidecar.Api/Open-Api-Docs.xml
9 changes: 9 additions & 0 deletions src/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.dockerignore
.env
.git
.gitignore
.vs
.vscode
*/bin
*/obj
**/.toolstarget
31 changes: 31 additions & 0 deletions src/Arcus.EventGrid.Sidecar.Api/Arcus.EventGrid.Sidecar.Api.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework>
<AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
<UserSecretsId>aa61febe-79be-4baf-88d0-232f0e260b93</UserSecretsId>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DocumentationFile>Open-Api-Docs.xml</DocumentationFile>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<DocumentationFile>Open-Api-Docs.xml</DocumentationFile>
</PropertyGroup>

<ItemGroup>
<None Remove="Open-Api-Docs.xml" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.2.0" PrivateAssets="All" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.1.1" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.2.0" />
<PackageReference Include="Swashbuckle.AspNetCore.Annotations" Version="4.0.1" />
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="4.0.1" />
</ItemGroup>

</Project>
24 changes: 24 additions & 0 deletions src/Arcus.EventGrid.Sidecar.Api/Controllers/v1/HealthController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using System.Net;
using Microsoft.AspNetCore.Mvc;
using Swashbuckle.AspNetCore.Annotations;

namespace Arcus.EventGrid.Sidecar.Api.Controllers.v1
{
[Route("api/v1/health")]
[ApiController]
public class HealthController : ControllerBase
{
/// <summary>
/// Get Health
/// </summary>
/// <remarks>Provides an indication about the health of the runtime</remarks>
[HttpGet]
[SwaggerOperation(OperationId = "Health_Get")]
[SwaggerResponse((int) HttpStatusCode.OK, Description = "Runtime is up and running in a healthy state")]
[SwaggerResponse((int) HttpStatusCode.ServiceUnavailable, Description = "Runtime is not healthy")]
public IActionResult Get()
{
return Ok();
}
}
}
20 changes: 20 additions & 0 deletions src/Arcus.EventGrid.Sidecar.Api/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
FROM microsoft/dotnet:2.2-aspnetcore-runtime AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM microsoft/dotnet:2.2-sdk AS build
WORKDIR /src
COPY ["Arcus.EventGrid.Sidecar.Api/Arcus.EventGrid.Sidecar.Api.csproj", "Arcus.EventGrid.Sidecar.Api/"]
RUN dotnet restore "Arcus.EventGrid.Sidecar.Api/Arcus.EventGrid.Sidecar.Api.csproj"
COPY . .
WORKDIR "/src/Arcus.EventGrid.Sidecar.Api"
RUN dotnet build "Arcus.EventGrid.Sidecar.Api.csproj" -c Release -o /app

FROM build AS publish
RUN dotnet publish "Arcus.EventGrid.Sidecar.Api.csproj" -c Release -o /app

FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "Arcus.EventGrid.Sidecar.Api.dll"]
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using Swashbuckle.AspNetCore.SwaggerUI;

namespace Microsoft.AspNetCore.Builder
{
public static class IApplicationBuilderExtensions
{
/// <summary>
/// Add support for Open API documentation with API explorer
/// </summary>
/// <param name="applicationBuilder">Application Builder</param>
public static void UseOpenApiDocsWithExplorer(this IApplicationBuilder applicationBuilder)
{
applicationBuilder.UseSwagger();
applicationBuilder.UseSwaggerUI(swaggerUiOptions =>
{
swaggerUiOptions.SwaggerEndpoint("/swagger/v1/swagger.json", "Arcus Event Grid v1 API");
swaggerUiOptions.DisplayOperationId();
swaggerUiOptions.EnableDeepLinking();
swaggerUiOptions.DocumentTitle = "Arcus Event Grid API";
swaggerUiOptions.DocExpansion(DocExpansion.List);
swaggerUiOptions.DisplayRequestDuration();
swaggerUiOptions.EnableFilter();
});
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
using System.IO;
using System.Linq;
using Microsoft.AspNetCore.Hosting;
using Swashbuckle.AspNetCore.Swagger;

namespace Microsoft.Extensions.DependencyInjection
{
public static class IServiceCollectionExtensions
{
/// <summary>
/// Use OpenAPI specification
/// </summary>
/// <param name="services">Collections of services in application</param>
public static void UseOpenApiSpecifications(this IServiceCollection services)
{
var openApiInformation = new Info
{
Contact = new Contact
{
Name = "Arcus",
Url = "https://github.com/arcus-azure/arcus.eventgrid.sidecar"
},
Title = "Arcus",
Description = "Push events to Azure Event Grid in a breeze - API allows you to send events over REST without having to worry about how Azure Event Grid works.",
License = new License
{
Name = "MIT",
Url = "https://github.com/arcus-azure/arcus.eventgrid.sidecar/blob/master/LICENSE"
}
};

var xmlDocumentationPath = GetXmlDocumentationPath(services);

services.AddSwaggerGen(swaggerGenerationOptions =>
{
swaggerGenerationOptions.EnableAnnotations();
swaggerGenerationOptions.SwaggerDoc("v1", openApiInformation);
swaggerGenerationOptions.DescribeAllEnumsAsStrings();
if (string.IsNullOrEmpty(xmlDocumentationPath) == false)
{
swaggerGenerationOptions.IncludeXmlComments(xmlDocumentationPath);
}
});
}

private static string GetXmlDocumentationPath(IServiceCollection services)
{
var hostingEnvironment = services.FirstOrDefault(service => service.ServiceType == typeof(IHostingEnvironment));
if (hostingEnvironment == null)
{
return string.Empty;
}

var contentRootPath = ((IHostingEnvironment)hostingEnvironment.ImplementationInstance).ContentRootPath;
var xmlDocumentationPath = $"{contentRootPath}/Open-Api-Docs.xml";

return File.Exists(xmlDocumentationPath) ? xmlDocumentationPath : string.Empty;
}
}
}
35 changes: 35 additions & 0 deletions src/Arcus.EventGrid.Sidecar.Api/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using System;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;

namespace Arcus.EventGrid.Sidecar.Api
{
public class Program
{
private const string WelcomeText = @"
█████╗ ██████╗ ██████╗██╗ ██╗███████╗
██╔══██╗██╔══██╗██╔════╝██║ ██║██╔════╝
███████║██████╔╝██║ ██║ ██║███████╗
██╔══██║██╔══██╗██║ ██║ ██║╚════██║
██║ ██║██║ ██║╚██████╗╚██████╔╝███████║
╚═╝ ╚═╝╚═╝ ╚═╝ ╚═════╝ ╚═════╝ ╚══════╝";

public static void Main(string[] args)
{
Welcome();

CreateWebHostBuilder(args)
.Build()
.Run();
}

private static void Welcome()
{
Console.WriteLine(WelcomeText);
}

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>();
}
}
50 changes: 50 additions & 0 deletions src/Arcus.EventGrid.Sidecar.Api/Startup.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

namespace Arcus.EventGrid.Sidecar.Api
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}

public IConfiguration Configuration { get; }

// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc()
.AddJsonOptions(jsonOptions =>
{
jsonOptions.SerializerSettings.Converters.Add(new Newtonsoft.Json.Converters.StringEnumConverter());
jsonOptions.SerializerSettings.NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore;
})
.SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

services.UseOpenApiSpecifications();
}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}

app.UseHttpsRedirection();
app.UseMvc();
app.UseOpenApiDocsWithExplorer();
}
}
}
9 changes: 9 additions & 0 deletions src/Arcus.EventGrid.Sidecar.Api/appsettings.Development.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Debug",
"System": "Information",
"Microsoft": "Information"
}
}
}
8 changes: 8 additions & 0 deletions src/Arcus.EventGrid.Sidecar.Api/appsettings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Warning"
}
},
"AllowedHosts": "*"
}
12 changes: 12 additions & 0 deletions src/Arcus.EventGrid.Sidecar.sln
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,19 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.28307.168
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Arcus.EventGrid.Sidecar.Api", "Arcus.EventGrid.Sidecar.Api\Arcus.EventGrid.Sidecar.Api.csproj", "{CF1BA281-352B-41E0-B2AD-DC35C85358B7}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{CF1BA281-352B-41E0-B2AD-DC35C85358B7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CF1BA281-352B-41E0-B2AD-DC35C85358B7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CF1BA281-352B-41E0-B2AD-DC35C85358B7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CF1BA281-352B-41E0-B2AD-DC35C85358B7}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
Expand Down

0 comments on commit 47b7e66

Please sign in to comment.