Skip to content

Commit 178cdec

Browse files
RodrigoDevRodrigoDev
authored andcommitted
First commit
1 parent e06375e commit 178cdec

File tree

159 files changed

+7237
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

159 files changed

+7237
-0
lines changed

.gitignore

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
################################################################################
2+
# Este arquivo .gitignore foi criado automaticamente pelo Microsoft(R) Visual Studio.
3+
################################################################################
4+
5+
/.vs
6+
/Api/bin/Debug/net8.0
7+
/Api/obj
8+
/Application/bin/Debug/net8.0
9+
/Application/obj
10+
/Domain/bin/Debug/net8.0
11+
/Domain/obj
12+
/Infra/bin/Debug/net8.0
13+
/Infra/obj
14+
/IoC/bin/Debug/net8.0
15+
/IoC/obj
16+
/UnitTests/bin/Debug/net8.0
17+
/UnitTests/obj
18+
/Tests/IntegrationTests/bin/Debug/net8.0
19+
/Tests/IntegrationTests/obj
20+
/Tests/UnitTests/bin/Debug/net8.0
21+
/Tests/UnitTests/obj
22+
/Api/appsettings.Development.json
23+
/Api/appsettings.Tests.json

Api/Api.csproj

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<Project Sdk="Microsoft.NET.Sdk.Web">
2+
<PropertyGroup>
3+
<TargetFramework>net8.0</TargetFramework>
4+
<Nullable>disable</Nullable>
5+
<ImplicitUsings>enable</ImplicitUsings>
6+
</PropertyGroup>
7+
<PropertyGroup>
8+
<GenerateDocumentationFile>true</GenerateDocumentationFile>
9+
<NoWarn>$(NoWarn);1591</NoWarn>
10+
</PropertyGroup>
11+
<ItemGroup>
12+
<PackageReference Include="Swashbuckle.AspNetCore.Annotations" Version="7.3.1" />
13+
</ItemGroup>
14+
<ItemGroup>
15+
<ProjectReference Include="..\Domain\Domain.csproj" />
16+
<ProjectReference Include="..\Application\Application.csproj" />
17+
<ProjectReference Include="..\IoC\IoC.csproj" />
18+
</ItemGroup>
19+
</Project>

Api/Api.csproj.user

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3+
<PropertyGroup>
4+
<ActiveDebugProfile>https</ActiveDebugProfile>
5+
</PropertyGroup>
6+
</Project>

Api/Base/BaseController.cs

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
using MediatR;
2+
using System.Text.Json;
3+
using Application.Enums;
4+
using Microsoft.AspNetCore.Mvc;
5+
using System.Text.Encodings.Web;
6+
using Application.Interfaces.Logging;
7+
using Domain.Interfaces.Authentication;
8+
using Application.Interfaces.Transaction;
9+
10+
namespace Api.Base
11+
{
12+
/// <summary>
13+
/// Base controller
14+
/// Provide a generic way to decide the api response
15+
/// Provide automatic rollback
16+
/// Provide automatic logging
17+
/// </summary>
18+
public class BaseController : ControllerBase
19+
{
20+
private readonly IMediator _mediator;
21+
private readonly IServiceProvider _provider;
22+
private readonly ILoggingService _logger;
23+
private readonly ITokenService _tokenService;
24+
25+
public BaseController(IServiceProvider provider)
26+
{
27+
_mediator = provider.GetService<IMediator>();
28+
_provider = provider.GetService<IServiceProvider>();
29+
_logger = provider.GetService<ILoggingService>();
30+
_tokenService = provider.GetService<ITokenService>();
31+
}
32+
33+
private void SetToken()
34+
{
35+
var authorizationHeader = Request?.Headers?.ContainsKey("Authorization") ?? false
36+
? Request?.Headers["Authorization"].ToString()
37+
: null;
38+
39+
if(!string.IsNullOrEmpty(authorizationHeader))
40+
_tokenService.SetCurrentToken(authorizationHeader);
41+
}
42+
43+
private async Task Log(object request, BaseResponse response, Exception ex)
44+
{
45+
var url = $"{Request.Scheme}://{Request.Host}{Request.Path}{Request.QueryString}";
46+
var headers = string.Join(", ", Request.Headers.Select(h => $"{h.Key}: {h.Value}"));
47+
var body = string.Empty;
48+
49+
if (!Request.Body.CanSeek)
50+
Request.EnableBuffering();
51+
52+
Request.Body.Position = 0;
53+
54+
using (var reader = new StreamReader(Request.Body, leaveOpen: true))
55+
{
56+
body = await reader.ReadToEndAsync();
57+
Request.Body.Position = 0;
58+
}
59+
60+
var information = new
61+
{
62+
url = url,
63+
headers = headers,
64+
exception = ex?.Message + ex?.StackTrace + ex?.InnerException?.Message + ex?.InnerException?.StackTrace,
65+
token = _tokenService.GetToken(),
66+
request = request,
67+
body = body,
68+
response = response,
69+
};
70+
71+
var jsonConfig = new JsonSerializerOptions();
72+
jsonConfig.WriteIndented = true;
73+
jsonConfig.Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping;
74+
75+
_logger.Log(
76+
request.GetType().Name,
77+
JsonSerializer.Serialize(information, options: jsonConfig),
78+
response.Success
79+
? LogTypeEnum.Information
80+
: LogTypeEnum.Error
81+
);
82+
}
83+
84+
private async Task<ObjectResult> GetApiResponse(BaseResponse response, object request = null, Exception ex = null)
85+
{
86+
await Log(request, response, ex);
87+
88+
return StatusCode(response.Code, response);
89+
}
90+
91+
protected async Task<ObjectResult> HandleApplicationResponse<R>(object request, Func<R, BaseResponse> apiAction)
92+
{
93+
SetToken();
94+
95+
try
96+
{
97+
if(request == null)
98+
{
99+
return await GetApiResponse
100+
(
101+
new()
102+
{
103+
Response = null,
104+
Success = false,
105+
ErrorMessage = "Invalid request",
106+
Code = 400
107+
},
108+
request
109+
);
110+
}
111+
112+
if(!ModelState.IsValid)
113+
{
114+
string error = ModelState.Values
115+
.FirstOrDefault()
116+
?.Errors?
117+
.FirstOrDefault()?
118+
.ErrorMessage ?? "Unknow error";
119+
120+
if(error.EndsWith('.'))
121+
error = error[..^1];
122+
123+
return await GetApiResponse
124+
(
125+
new()
126+
{
127+
Response = null,
128+
Success = false,
129+
ErrorMessage = error,
130+
Code = 400
131+
},
132+
request
133+
);
134+
}
135+
136+
var appResponse = await _mediator.Send(request);
137+
var apiResponse = apiAction((R)appResponse);
138+
139+
return await GetApiResponse(apiResponse, request);
140+
}
141+
catch (Exception ex)
142+
{
143+
var uow = _provider.GetService<IUnityOfWork>();
144+
145+
uow?.Rollback();
146+
147+
return await GetApiResponse
148+
(
149+
new()
150+
{
151+
Response = null,
152+
Success = false,
153+
ErrorMessage = ex.Message,
154+
Code = 500
155+
},
156+
request,
157+
ex
158+
);
159+
}
160+
finally
161+
{
162+
await _logger.Persist();
163+
}
164+
}
165+
}
166+
}

Api/Base/BaseResponse.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
namespace Api.Base
2+
{
3+
/// <summary>
4+
/// Base response for the API
5+
/// </summary>
6+
public class BaseResponse
7+
{
8+
public object Response { get; set; }
9+
public bool Success { get; set; }
10+
public string ErrorMessage { get; set; }
11+
public int Code { get; set; }
12+
}
13+
14+
/// <summary>
15+
/// Base response for the API
16+
/// </summary>
17+
public class BaseResponse<T>
18+
{
19+
public T Response { get; set; }
20+
public bool Success { get; set; }
21+
public string ErrorMessage { get; set; }
22+
public int Code { get; set; }
23+
}
24+
}

0 commit comments

Comments
 (0)