Skip to content

Commit

Permalink
Renamed APIResponse to ApiResult
Browse files Browse the repository at this point in the history
Simplified ApiResult implementation
Removed Produces application/json
  • Loading branch information
Aragas committed Dec 7, 2023
1 parent 2855578 commit cd67fa2
Show file tree
Hide file tree
Showing 42 changed files with 464 additions and 707 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -52,36 +52,36 @@ public async Task<PagingStreamingData<CrashReportModel2>> PaginatedStreamingAsyn
return await _implementation.PaginatedStreamingAsync(new PaginatedQuery(body.Page, body.PageSize, body.Filters, body.Sotings), ct);

Check warning on line 52 in src/BUTR.Site.NexusMods.Client/Services/CrashReportsClientWithDemo.cs

View workflow job for this annotation

GitHub Actions / build

Dereference of a possibly null reference.
}

public async Task<CrashReportModel2PagingDataAPIResponseActionResult> PaginatedAsync(PaginatedQuery? body, CancellationToken ct)
public async Task<CrashReportModel2PagingDataApiResult> PaginatedAsync(PaginatedQuery? body, CancellationToken ct)
{
var token = await _tokenContainer.GetTokenAsync(ct);
if (token?.Type.Equals("demo", StringComparison.OrdinalIgnoreCase) == true)
{
var crashReports = await DemoUser.GetCrashReports(_httpClientFactory).ToListAsync(ct);
return new CrashReportModel2PagingDataAPIResponseActionResult(new CrashReportModel2PagingData(PagingAdditionalMetadata.Empty, crashReports, new PagingMetadata(1, (int) Math.Ceiling((double) crashReports.Count / body.PageSize), body.PageSize, crashReports.Count)), null!);
return new CrashReportModel2PagingDataApiResult(new CrashReportModel2PagingData(PagingAdditionalMetadata.Empty, crashReports, new PagingMetadata(1, (int) Math.Ceiling((double) crashReports.Count / body.PageSize), body.PageSize, crashReports.Count)), null!);

Check warning on line 61 in src/BUTR.Site.NexusMods.Client/Services/CrashReportsClientWithDemo.cs

View workflow job for this annotation

GitHub Actions / build

Dereference of a possibly null reference.
}

return await _implementation.PaginatedAsync(new PaginatedQuery(body.Page, body.PageSize, body.Filters, body.Sotings), ct);

Check warning on line 64 in src/BUTR.Site.NexusMods.Client/Services/CrashReportsClientWithDemo.cs

View workflow job for this annotation

GitHub Actions / build

Dereference of a possibly null reference.
}

public async Task<StringIQueryableAPIResponseActionResult> AutocompleteAsync(string? modId, CancellationToken ct)
public async Task<StringIQueryableApiResult> AutocompleteAsync(string? modId, CancellationToken ct)
{
var token = await _tokenContainer.GetTokenAsync(ct);
if (token?.Type.Equals("demo", StringComparison.OrdinalIgnoreCase) == true)
{
var crashReports = await DemoUser.GetCrashReports(_httpClientFactory).ToListAsync(ct);
return new StringIQueryableAPIResponseActionResult(crashReports.SelectMany(x => x.InvolvedModules).Where(x => x.StartsWith(modId)).ToArray(), null!);
return new StringIQueryableApiResult(crashReports.SelectMany(x => x.InvolvedModules).Where(x => x.StartsWith(modId)).ToArray(), null!);

Check warning on line 73 in src/BUTR.Site.NexusMods.Client/Services/CrashReportsClientWithDemo.cs

View workflow job for this annotation

GitHub Actions / build

Possible null reference argument for parameter 'value' in 'bool string.StartsWith(string value)'.
}

return new StringIQueryableAPIResponseActionResult((await _implementation.AutocompleteAsync(modId, ct)).Value ?? Array.Empty<string>(), null!);
return new StringIQueryableApiResult((await _implementation.AutocompleteAsync(modId, ct)).Value ?? Array.Empty<string>(), null!);
}

public async Task<StringAPIResponseActionResult> UpdateAsync(CrashReportModel2? body, CancellationToken ct)
public async Task<StringApiResult> UpdateAsync(CrashReportModel2? body, CancellationToken ct)
{
var token = await _tokenContainer.GetTokenAsync(ct);
if (token?.Type.Equals("demo", StringComparison.OrdinalIgnoreCase) == true)
{
return new StringAPIResponseActionResult("demo", null!);
return new StringApiResult("demo", null!);
}

return await _implementation.UpdateAsync(body, ct);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,27 +17,27 @@ public NexusModsModClientWithDemo(IServiceProvider serviceProvider, ITokenContai
_tokenContainer = tokenContainer ?? throw new ArgumentNullException(nameof(tokenContainer));
}

public async Task<RawNexusModsModModelAPIResponseActionResult> RawAsync(string gameDomain, int modId, CancellationToken ct = default)
public async Task<RawNexusModsModModelApiResult> RawAsync(string gameDomain, int modId, CancellationToken ct = default)
{
return await _implementation.RawAsync(gameDomain, modId, ct);
}

public async Task<StringAPIResponseActionResult> ToModuleManualLinkAsync(string? moduleId = null, int? nexusModsModId = null, CancellationToken ct = default)
public async Task<StringApiResult> ToModuleManualLinkAsync(string? moduleId = null, int? nexusModsModId = null, CancellationToken ct = default)
{
return await _implementation.ToModuleManualLinkAsync(moduleId, nexusModsModId, ct);
}

public async Task<StringAPIResponseActionResult> ToModuleManualUnlinkAsync(string? moduleId = null, int? nexusModsModId = null, CancellationToken ct = default)
public async Task<StringApiResult> ToModuleManualUnlinkAsync(string? moduleId = null, int? nexusModsModId = null, CancellationToken ct = default)
{
return await _implementation.ToModuleManualUnlinkAsync(moduleId, nexusModsModId, ct);
}

public async Task<NexusModsModToModuleModelPagingDataAPIResponseActionResult> ToModuleManualLinkPaginatedAsync(PaginatedQuery? body = null, CancellationToken ct = default)
public async Task<NexusModsModToModuleModelPagingDataApiResult> ToModuleManualLinkPaginatedAsync(PaginatedQuery? body = null, CancellationToken ct = default)
{
return await _implementation.ToModuleManualLinkPaginatedAsync(body, ct);
}

public async Task<NexusModsModAvailableModelPagingDataAPIResponseActionResult> AvailablePaginatedAsync(PaginatedQuery? body = null, CancellationToken ct = default)
public async Task<NexusModsModAvailableModelPagingDataApiResult> AvailablePaginatedAsync(PaginatedQuery? body = null, CancellationToken ct = default)
{
return await _implementation.AvailablePaginatedAsync(body, ct);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@ public NexusModsUserClientWithDemo(IServiceProvider serviceProvider, ITokenConta
_cache = cache ?? throw new ArgumentNullException(nameof(cache));
}

public async Task<ProfileModelAPIResponseActionResult> ProfileAsync(CancellationToken ct)
public async Task<ProfileModelApiResult> ProfileAsync(CancellationToken ct)
{
var token = await _tokenContainer.GetTokenAsync(ct);
if (token?.Type.Equals("demo", StringComparison.OrdinalIgnoreCase) == true)
return new ProfileModelAPIResponseActionResult(await DemoUser.GetProfile(), null!);
return new ProfileModelApiResult(await DemoUser.GetProfile(), null!);

async Task<(ProfileModelAPIResponseActionResult, CacheOptions)?> Factory()
async Task<(ProfileModelApiResult, CacheOptions)?> Factory()
{
try
{
Expand All @@ -46,43 +46,43 @@ public async Task<ProfileModelAPIResponseActionResult> ProfileAsync(Cancellation
}
}

return await _cache.GetAsync("profile", Factory, ct) ?? new ProfileModelAPIResponseActionResult(await DemoUser.GetProfile(), new(null, null, null, detail: "error", null));
return await _cache.GetAsync("profile", Factory, ct) ?? new ProfileModelApiResult(await DemoUser.GetProfile(), null!);
}

public async Task<StringAPIResponseActionResult> SetRoleAsync(int? userId, string? role, CancellationToken ct)
public async Task<StringApiResult> SetRoleAsync(int? userId, string? role, CancellationToken ct)
{
var token = await _tokenContainer.GetTokenAsync(ct);
if (token?.Type.Equals("demo", StringComparison.OrdinalIgnoreCase) == true)
return new StringAPIResponseActionResult("demo", null!);
return new StringApiResult("demo", null!);

return await _implementation.SetRoleAsync(userId, role, ct);
}

public async Task<StringAPIResponseActionResult> RemoveRoleAsync(int? userId, CancellationToken ct)
public async Task<StringApiResult> RemoveRoleAsync(int? userId, CancellationToken ct)
{
var token = await _tokenContainer.GetTokenAsync(ct);
if (token?.Type.Equals("demo", StringComparison.OrdinalIgnoreCase) == true)
return new StringAPIResponseActionResult("demo", null!);
return new StringApiResult("demo", null!);

return await _implementation.RemoveRoleAsync(userId, ct);
}

public async Task<NexusModsModModelPagingDataAPIResponseActionResult> ToNexusModsModPaginatedAsync(PaginatedQuery? body = null, CancellationToken ct = default)
public async Task<NexusModsModModelPagingDataApiResult> ToNexusModsModPaginatedAsync(PaginatedQuery? body = null, CancellationToken ct = default)
{
var token = await _tokenContainer.GetTokenAsync(ct);
if (token?.Type.Equals("demo", StringComparison.OrdinalIgnoreCase) == true)
{
var mods = await DemoUser.GetMods().ToListAsync(ct);
return new NexusModsModModelPagingDataAPIResponseActionResult(new NexusModsModModelPagingData(PagingAdditionalMetadata.Empty, mods, new PagingMetadata(1, (int) Math.Ceiling((double) mods.Count / (double) body.PageSize), body.PageSize, mods.Count)), null!);
return new NexusModsModModelPagingDataApiResult(new NexusModsModModelPagingData(PagingAdditionalMetadata.Empty, mods, new PagingMetadata(1, (int) Math.Ceiling((double) mods.Count / (double) body.PageSize), body.PageSize, mods.Count)), null!);

Check warning on line 76 in src/BUTR.Site.NexusMods.Client/Services/NexusModsUserClientWithDemo.cs

View workflow job for this annotation

GitHub Actions / build

Dereference of a possibly null reference.
}

return await _implementation.ToNexusModsModPaginatedAsync(new PaginatedQuery(body.Page, body.PageSize, Array.Empty<Filtering>(), Array.Empty<Sorting>()), ct);
}

public async Task<StringAPIResponseActionResult> ToNexusModsModUpdateAsync(NexusModsUserToNexusModsModQuery? body = null, CancellationToken ct = default) =>
public async Task<StringApiResult> ToNexusModsModUpdateAsync(NexusModsUserToNexusModsModQuery? body = null, CancellationToken ct = default) =>
await _implementation.ToNexusModsModUpdateAsync(body, ct);

public async Task<StringAPIResponseActionResult> ToNexusModsModLinkAsync(int? nexusModsModId = null, CancellationToken ct = default)
public async Task<StringApiResult> ToNexusModsModLinkAsync(int? nexusModsModId = null, CancellationToken ct = default)
{
var token = await _tokenContainer.GetTokenAsync(ct);
if (token?.Type.Equals("demo", StringComparison.OrdinalIgnoreCase) == true)
Expand All @@ -91,16 +91,16 @@ public async Task<StringAPIResponseActionResult> ToNexusModsModLinkAsync(int? ne
if (mods.Find(m => m.NexusModsModId == nexusModsModId) is null)
{
mods.Add(new(nexusModsModId ?? 0, $"Demo Mod {nexusModsModId}", ImmutableArray<int>.Empty, ImmutableArray<int>.Empty, ImmutableArray<string>.Empty, ImmutableArray<string>.Empty));
return new StringAPIResponseActionResult("demo", null!);
return new StringApiResult("demo", null!);
}

return new StringAPIResponseActionResult(null, new(null, null, null, detail: "error", null));
return new StringApiResult(null, null!);
}

return await _implementation.ToNexusModsModLinkAsync(nexusModsModId, ct);
}

public async Task<StringAPIResponseActionResult> ToNexusModsModUnlinkAsync(int? nexusModsModId = null, CancellationToken ct = default)
public async Task<StringApiResult> ToNexusModsModUnlinkAsync(int? nexusModsModId = null, CancellationToken ct = default)
{
var token = await _tokenContainer.GetTokenAsync(ct);
if (token?.Type.Equals("demo", StringComparison.OrdinalIgnoreCase) == true)
Expand All @@ -109,65 +109,65 @@ public async Task<StringAPIResponseActionResult> ToNexusModsModUnlinkAsync(int?
if (mods.Find(m => m.NexusModsModId == nexusModsModId) is { } mod)
{
mods.Remove(mod);
return new StringAPIResponseActionResult("demo", null!);
return new StringApiResult("demo", null!);
}

return new StringAPIResponseActionResult(null, new(null, null, null, detail: "error", null));
return new StringApiResult(null!, null);
}

return await _implementation.ToNexusModsModUnlinkAsync(nexusModsModId, ct);
}

public async Task<StringAPIResponseActionResult> ToModuleManualLinkAsync(int? nexusModsUserId = null, string? moduleId = null, CancellationToken ct = default)
public async Task<StringApiResult> ToModuleManualLinkAsync(int? nexusModsUserId = null, string? moduleId = null, CancellationToken ct = default)
{
var token = await _tokenContainer.GetTokenAsync(ct);
if (token?.Type.Equals("demo", StringComparison.OrdinalIgnoreCase) == true)
return new StringAPIResponseActionResult("demo", null!);
return new StringApiResult("demo", null!);

return await _implementation.ToModuleManualLinkAsync(nexusModsUserId, moduleId, ct);
}

public async Task<StringAPIResponseActionResult> ToModuleManualUnlinkAsync(int? nexusModsUserId = null, string? moduleId = null, CancellationToken ct = default)
public async Task<StringApiResult> ToModuleManualUnlinkAsync(int? nexusModsUserId = null, string? moduleId = null, CancellationToken ct = default)
{
var token = await _tokenContainer.GetTokenAsync(ct);
if (token?.Type.Equals("demo", StringComparison.OrdinalIgnoreCase) == true)
return new StringAPIResponseActionResult("demo", null!);
return new StringApiResult("demo", null!);

return await _implementation.ToModuleManualUnlinkAsync(nexusModsUserId, moduleId, ct);
}

public async Task<NexusModsUserToModuleManualLinkModelPagingDataAPIResponseActionResult> ToModuleManualLinkPaginatedAsync(PaginatedQuery? body = null, CancellationToken ct = default)
public async Task<NexusModsUserToModuleManualLinkModelPagingDataApiResult> ToModuleManualLinkPaginatedAsync(PaginatedQuery? body = null, CancellationToken ct = default)
{
var token = await _tokenContainer.GetTokenAsync(ct);
if (token?.Type.Equals("demo", StringComparison.OrdinalIgnoreCase) == true)
return new NexusModsUserToModuleManualLinkModelPagingDataAPIResponseActionResult(new NexusModsUserToModuleManualLinkModelPagingData(PagingAdditionalMetadata.Empty, new List<NexusModsUserToModuleManualLinkModel>(), new PagingMetadata(1, 1, body.PageSize, 1)), null!);
return new NexusModsUserToModuleManualLinkModelPagingDataApiResult(new NexusModsUserToModuleManualLinkModelPagingData(PagingAdditionalMetadata.Empty, new List<NexusModsUserToModuleManualLinkModel>(), new PagingMetadata(1, 1, body.PageSize, 1)), null!);

return await _implementation.ToModuleManualLinkPaginatedAsync(new PaginatedQuery(body.Page, body.PageSize, Array.Empty<Filtering>(), Array.Empty<Sorting>()), ct);
}

public async Task<StringAPIResponseActionResult> ToNexusModsModManualLinkAsync(int? userId = null, int? nexusModsModId = null, CancellationToken ct = default)
public async Task<StringApiResult> ToNexusModsModManualLinkAsync(int? userId = null, int? nexusModsModId = null, CancellationToken ct = default)
{
var token = await _tokenContainer.GetTokenAsync(ct);
if (token?.Type.Equals("demo", StringComparison.OrdinalIgnoreCase) == true)
return new StringAPIResponseActionResult("demo", null!);
return new StringApiResult("demo", null!);

return await _implementation.ToNexusModsModManualLinkAsync(userId, nexusModsModId, ct);
}

public async Task<StringAPIResponseActionResult> ToNexusModsModManualUnlinkAsync(int? userId = null, int? nexusModsModId = null, CancellationToken ct = default)
public async Task<StringApiResult> ToNexusModsModManualUnlinkAsync(int? userId = null, int? nexusModsModId = null, CancellationToken ct = default)
{
var token = await _tokenContainer.GetTokenAsync(ct);
if (token?.Type.Equals("demo", StringComparison.OrdinalIgnoreCase) == true)
return new StringAPIResponseActionResult("demo", null!);
return new StringApiResult("demo", null!);

return await _implementation.ToNexusModsModManualUnlinkAsync(userId, nexusModsModId, ct);
}

public async Task<NexusModsUserToNexusModsModManualLinkModelPagingDataAPIResponseActionResult> ToNexusModsModManualLinkPaginatedAsync(PaginatedQuery? body = null, CancellationToken ct = default)
public async Task<NexusModsUserToNexusModsModManualLinkModelPagingDataApiResult> ToNexusModsModManualLinkPaginatedAsync(PaginatedQuery? body = null, CancellationToken ct = default)
{
var token = await _tokenContainer.GetTokenAsync(ct);
if (token?.Type.Equals("demo", StringComparison.OrdinalIgnoreCase) == true)
return new NexusModsUserToNexusModsModManualLinkModelPagingDataAPIResponseActionResult(new NexusModsUserToNexusModsModManualLinkModelPagingData(PagingAdditionalMetadata.Empty, new List<NexusModsUserToNexusModsModManualLinkModel>(), new PagingMetadata(1, 1, body.PageSize, 1)), null!);
return new NexusModsUserToNexusModsModManualLinkModelPagingDataApiResult(new NexusModsUserToNexusModsModManualLinkModelPagingData(PagingAdditionalMetadata.Empty, new List<NexusModsUserToNexusModsModManualLinkModel>(), new PagingMetadata(1, 1, body.PageSize, 1)), null!);

return await _implementation.ToNexusModsModManualLinkPaginatedAsync(body, ct);
}
Expand Down
79 changes: 79 additions & 0 deletions src/BUTR.Site.NexusMods.Server/Controllers/ApiControllerBase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
using BUTR.Site.NexusMods.Server.Models.API;
using BUTR.Site.NexusMods.Server.Models.Database;
using BUTR.Site.NexusMods.Server.Utils.Http.ApiResults;
using BUTR.Site.NexusMods.Server.Utils.Http.StreamingMultipartResults;

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;

namespace BUTR.Site.NexusMods.Server.Controllers;

public class ApiControllerBase : ControllerBase
{
[NonAction]
protected ApiResult<PagingData<TResult>?> ApiPagingResult<TResult, TSource>(Paging<TSource> data, Func<IAsyncEnumerable<TSource>, IAsyncEnumerable<TResult>> func)
where TResult : class
where TSource : class
{
return ApiResult(PagingData<TResult>.Create(data, func));
}

[NonAction]
protected StreamingMultipartResult ApiPagingStreamingResult<TResult, TSource>(Paging<TSource> data, Func<IAsyncEnumerable<TSource>, IAsyncEnumerable<TResult>> func)
where TResult : class
where TSource : class
{
var options = HttpContext.RequestServices.GetRequiredService<IOptions<JsonOptions>>().Value;
IEnumerable<Func<Stream, CancellationToken, Task>> GetContent()
{
yield return (stream, ct_) => JsonSerializer.SerializeAsync(stream, Utils.Http.ApiResults.ApiResult.FromError(null), options.JsonSerializerOptions, ct_);
yield return (stream, ct_) => JsonSerializer.SerializeAsync(stream, data.Metadata, options.JsonSerializerOptions, ct_);
yield return (stream, ct_) => JsonSerializer.SerializeAsync(stream, func(data.Items), options.JsonSerializerOptions, ct_);
yield return (stream, ct_) => JsonSerializer.SerializeAsync(stream, new PagingAdditionalMetadata
{
QueryExecutionTimeMilliseconds = (uint) Stopwatch.GetElapsedTime(data.StartTime).Milliseconds
}, options.JsonSerializerOptions, ct_);
}

return new StreamingMultipartResult(GetContent(), "application/x-ndjson-butr-paging");
}

[NonAction]
protected ApiResult<PagingData<TResult>?> ApiPagingResult<TResult>(Paging<TResult> paginated)
where TResult : class
{
return ApiResult(PagingData<TResult>.Create(paginated));
}

[NonAction]
protected ApiResult<T?> ApiResult<T>([ActionResultObjectValue] T? value) => Utils.Http.ApiResults.ApiResult<T>.FromResult(value);

[NonAction]
protected ApiResult ApiResultError(string error) => Utils.Http.ApiResults.ApiResult.FromError(new ProblemDetails
{
Detail = error,
});

[NonAction]
protected ApiResult ApiResultError(int statusCode) => Utils.Http.ApiResults.ApiResult.FromError(new ProblemDetails
{
Status = statusCode,
});

[NonAction]
protected ApiResult ApiResultError(string error, int statusCode) => Utils.Http.ApiResults.ApiResult.FromError(new ProblemDetails
{
Detail = error,
Status = statusCode,
});
}
Loading

0 comments on commit cd67fa2

Please sign in to comment.