Player API and client controllers

This commit is contained in:
2020-02-29 22:11:22 +01:00
parent 1d39ae9537
commit ab43075df8
7 changed files with 146 additions and 16 deletions

View File

@@ -8,4 +8,8 @@
<ProjectReference Include="..\EstusShots.Shared\EstusShots.Shared.csproj" /> <ProjectReference Include="..\EstusShots.Shared\EstusShots.Shared.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<PackageReference Include="Z.ExtensionMethods" Version="2.1.1" />
</ItemGroup>
</Project> </Project>

View File

@@ -55,6 +55,8 @@ namespace EstusShots.Client
var response = await HttpClient.PostAsync(url, content); var response = await HttpClient.PostAsync(url, content);
response.EnsureSuccessStatusCode(); response.EnsureSuccessStatusCode();
var json = await response.Content.ReadAsStringAsync(); var json = await response.Content.ReadAsStringAsync();
if (json.IsNullOrWhiteSpace() || json == "{}")
return new ApiResponse<TResult>(new OperationResult(false, "Invalid response", "The server returned no or empty data"));
var result = JsonSerializer.Deserialize<ApiResponse<TResult>>(json, _serializerOptions); var result = JsonSerializer.Deserialize<ApiResponse<TResult>>(json, _serializerOptions);
return result; return result;
} }

View File

@@ -0,0 +1,32 @@
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using EstusShots.Shared.Interfaces;
using EstusShots.Shared.Models;
using EstusShots.Shared.Models.Parameters;
namespace EstusShots.Client.Routes
{
public class Players : IPlayersController
{
private readonly EstusShotsClient _client;
public Players(EstusShotsClient client)
{
_client = client;
}
private string ActionUrl([CallerMemberName]string caller = "") =>
$"{_client.ApiUrl}{GetType().Name}/{caller}";
public async Task<ApiResponse<GetPlayersResponse>> GetPlayers(GetPlayersParameter parameter)
=> await _client.PostToApi<GetPlayersResponse, GetPlayersParameter>(ActionUrl(), parameter);
public async Task<ApiResponse<GetPlayerDetailsResponse>> GetPlayerDetails(GetPlayerDetailsParameter parameter)
=> await _client.PostToApi<GetPlayerDetailsResponse, GetPlayerDetailsParameter>(ActionUrl(), parameter);
public async Task<ApiResponse<SavePlayerResponse>> SavePlayer(SavePlayerParameter parameter)
=> await _client.PostToApi<SavePlayerResponse, SavePlayerParameter>(ActionUrl(), parameter);
public async Task<ApiResponse<DeletePlayerResponse>> DeletePlayers(DeletePlayerParameter parameter)
=> await _client.PostToApi<DeletePlayerResponse, DeletePlayerParameter>(ActionUrl(), parameter);
}
}

View File

@@ -0,0 +1,61 @@
using System;
using System.Threading.Tasks;
using EstusShots.Server.Services;
using EstusShots.Shared.Interfaces;
using EstusShots.Shared.Models;
using EstusShots.Shared.Models.Parameters;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
namespace EstusShots.Server.Controllers
{
[ApiController]
[Route("/api/[controller]/[action]")]
public class PlayersController : ControllerBase, IPlayersController
{
private readonly ILogger _logger;
private readonly PlayersService _service;
public PlayersController(ILogger<PlayersController> logger, PlayersService service)
{
_logger = logger;
_service = service;
}
private async Task<ApiResponse<T>> ServiceCall<T>(Func<Task<ApiResponse<T>>> serviceCall)
where T : class, IApiResponse, new()
{
try
{
if (!ModelState.IsValid)
{
_logger.LogError($"Model invalid");
}
_logger.LogInformation($"Request received from client '{Request.HttpContext.Connection.RemoteIpAddress}'");
return await serviceCall();
}
catch (Exception e)
{
_logger.LogError(e, "Exception Occured");
return new ApiResponse<T>(new OperationResult(e));
}
}
[HttpPost]
public async Task<ApiResponse<GetPlayersResponse>> GetPlayers(GetPlayersParameter parameter)
=> await ServiceCall(() => _service.GetPlayers(parameter));
[HttpPost]
public async Task<ApiResponse<GetPlayerDetailsResponse>> GetPlayerDetails(GetPlayerDetailsParameter parameter)
=> await ServiceCall(() => _service.GetPlayerDetails(parameter));
[HttpPost]
public async Task<ApiResponse<SavePlayerResponse>> SavePlayer(SavePlayerParameter parameter)
=> await ServiceCall(() => _service.SavePlayer(parameter));
[HttpPost]
public async Task<ApiResponse<DeletePlayerResponse>> DeletePlayers(DeletePlayerParameter parameter)
=> await ServiceCall(() => _service.DeletePlayers(parameter));
}
}

View File

@@ -16,9 +16,11 @@ namespace EstusShots.Server
CreateHostBuilder(args).Build().Run(); CreateHostBuilder(args).Build().Run();
} }
public static IHostBuilder CreateHostBuilder(string[] args) => public static IHostBuilder CreateHostBuilder(string[] args)
Host.CreateDefaultBuilder(args) {
return Host.CreateDefaultBuilder(args)
.ConfigureLogging(builder => { builder.AddConsole(); }) .ConfigureLogging(builder => { builder.AddConsole(); })
.ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); }); .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); });
} }
}
} }

View File

@@ -0,0 +1,38 @@
using System.Threading.Tasks;
using EstusShots.Shared.Interfaces;
using EstusShots.Shared.Models;
using EstusShots.Shared.Models.Parameters;
using Microsoft.Extensions.Logging;
namespace EstusShots.Server.Services
{
public class PlayersService : IPlayersController
{
private readonly ILogger _logger;
public PlayersService(ILogger<PlayersService> logger)
{
_logger = logger;
}
public Task<ApiResponse<GetPlayersResponse>> GetPlayers(GetPlayersParameter parameter)
{
throw new System.NotImplementedException();
}
public Task<ApiResponse<GetPlayerDetailsResponse>> GetPlayerDetails(GetPlayerDetailsParameter parameter)
{
throw new System.NotImplementedException();
}
public Task<ApiResponse<SavePlayerResponse>> SavePlayer(SavePlayerParameter parameter)
{
throw new System.NotImplementedException();
}
public Task<ApiResponse<DeletePlayerResponse>> DeletePlayers(DeletePlayerParameter parameter)
{
throw new System.NotImplementedException();
}
}
}

View File

@@ -34,19 +34,17 @@ namespace EstusShots.Server
services.AddControllers().AddJsonOptions(options => services.AddControllers().AddJsonOptions(options =>
{ {
options.JsonSerializerOptions.PropertyNameCaseInsensitive = true; options.JsonSerializerOptions.PropertyNameCaseInsensitive = true;
if (IsDevelopment) if (IsDevelopment) options.JsonSerializerOptions.WriteIndented = true;
{
options.JsonSerializerOptions.WriteIndented = true;
}
}); });
services.AddSwaggerGen(options => services.AddSwaggerGen(options =>
{ {
options.SwaggerDoc("v1", new OpenApiInfo { Title = "Estus Shots API", Version = "v1" }); options.SwaggerDoc("v1", new OpenApiInfo {Title = "Estus Shots API", Version = "v1"});
}); });
// Register business logic services // Register business logic services
services.AddScoped<SeasonsService>(); services.AddScoped<SeasonsService>();
services.AddScoped<EpisodesService>(); services.AddScoped<EpisodesService>();
services.AddScoped<PlayersService>();
} }
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
@@ -54,23 +52,16 @@ namespace EstusShots.Server
{ {
IsDevelopment = env.IsDevelopment(); IsDevelopment = env.IsDevelopment();
if (IsDevelopment) if (IsDevelopment)
{
app.UseDeveloperExceptionPage(); app.UseDeveloperExceptionPage();
}
else else
{
app.UseHttpsRedirection(); app.UseHttpsRedirection();
}
// Enable middleware to serve generated Swagger as a JSON endpoint. // Enable middleware to serve generated Swagger as a JSON endpoint.
app.UseSwagger(); app.UseSwagger();
// Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.), // Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.),
// specifying the Swagger JSON endpoint. // specifying the Swagger JSON endpoint.
app.UseSwaggerUI(c => app.UseSwaggerUI(c => { c.SwaggerEndpoint("/swagger/v1/swagger.json", "Estus Shots API V1"); });
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "Estus Shots API V1");
});
app.UseRouting(); app.UseRouting();
app.UseAuthorization(); app.UseAuthorization();