From dd1edb7c98621d70e1dd67d096a4daf84d2c1b5b Mon Sep 17 00:00:00 2001 From: Eris Date: Fri, 14 Apr 2023 15:59:54 +0200 Subject: [PATCH 1/2] Leverage API request srcgen metadata for Twitch Helix API service --- .../JSON/TwitchHelixSerializerContext.cs | 22 +++++++++- .../Twitch/TwitchHelixApiService.Calls.cs | 44 +++++++++++++++---- .../Services/Twitch/TwitchHelixApiService.cs | 25 ++++++----- 3 files changed, 70 insertions(+), 21 deletions(-) diff --git a/CatCore/Helpers/JSON/TwitchHelixSerializerContext.cs b/CatCore/Helpers/JSON/TwitchHelixSerializerContext.cs index 740b2b0..ac938c0 100644 --- a/CatCore/Helpers/JSON/TwitchHelixSerializerContext.cs +++ b/CatCore/Helpers/JSON/TwitchHelixSerializerContext.cs @@ -1,4 +1,8 @@ using System.Text.Json.Serialization; +using CatCore.Models.Twitch.Helix.Requests; +using CatCore.Models.Twitch.Helix.Requests.Bans; +using CatCore.Models.Twitch.Helix.Requests.Polls; +using CatCore.Models.Twitch.Helix.Requests.Predictions; using CatCore.Models.Twitch.Helix.Responses; using CatCore.Models.Twitch.Helix.Responses.Badges; using CatCore.Models.Twitch.Helix.Responses.Bans; @@ -6,24 +10,38 @@ using CatCore.Models.Twitch.Helix.Responses.Emotes; using CatCore.Models.Twitch.Helix.Responses.Polls; using CatCore.Models.Twitch.Helix.Responses.Predictions; +using HelixRequests = CatCore.Models.Twitch.Helix.Requests; +using HelixResponses = CatCore.Models.Twitch.Helix.Responses; namespace CatCore.Helpers.JSON { [JsonSerializable(typeof(ResponseBase))] + [JsonSerializable(typeof(CreateStreamMarkerRequestDto))] [JsonSerializable(typeof(ResponseBase))] [JsonSerializable(typeof(ResponseBaseWithPagination))] - [JsonSerializable(typeof(ResponseBase))] + [JsonSerializable(typeof(HelixRequests.Polls.PollChoice), TypeInfoPropertyName = "RequestPollChoice")] + [JsonSerializable(typeof(HelixResponses.Polls.PollChoice), TypeInfoPropertyName = "ResponsePollChoice")] [JsonSerializable(typeof(ResponseBaseWithPagination))] - [JsonSerializable(typeof(ResponseBase))] + [JsonSerializable(typeof(CreatePollRequestDto))] + [JsonSerializable(typeof(EndPollRequestDto))] + [JsonSerializable(typeof(ResponseBase))] + [JsonSerializable(typeof(HelixRequests.Predictions.Outcome), TypeInfoPropertyName = "RequestOutcome")] + [JsonSerializable(typeof(HelixResponses.Predictions.Outcome), TypeInfoPropertyName = "ResponseOutcome")] [JsonSerializable(typeof(ResponseBaseWithPagination))] + [JsonSerializable(typeof(CreatePredictionsRequestDto))] + [JsonSerializable(typeof(EndPredictionRequestDto))] + [JsonSerializable(typeof(ResponseBase))] [JsonSerializable(typeof(ResponseBase))] [JsonSerializable(typeof(ResponseBase))] [JsonSerializable(typeof(ResponseBaseWithPagination))] [JsonSerializable(typeof(ResponseBaseWithTemplate))] [JsonSerializable(typeof(ResponseBaseWithTemplate))] + [JsonSerializable(typeof(ChatSettingsRequestDto))] [JsonSerializable(typeof(ResponseBase))] [JsonSerializable(typeof(ResponseBaseWithPagination))] + [JsonSerializable(typeof(LegacyRequestDataWrapper))] [JsonSerializable(typeof(ResponseBase))] + [JsonSerializable(typeof(SendChatAnnouncementRequestDto))] [JsonSerializable(typeof(ResponseBase))] [JsonSerializable(typeof(ResponseBase))] internal partial class TwitchHelixSerializerContext : JsonSerializerContext diff --git a/CatCore/Services/Twitch/TwitchHelixApiService.Calls.cs b/CatCore/Services/Twitch/TwitchHelixApiService.Calls.cs index 2de9d09..09ba7fb 100644 --- a/CatCore/Services/Twitch/TwitchHelixApiService.Calls.cs +++ b/CatCore/Services/Twitch/TwitchHelixApiService.Calls.cs @@ -84,7 +84,11 @@ void CheckCount(ref string[]? array, out bool hasBool) } var body = new CreateStreamMarkerRequestDto(userId, description); - return await PostAsync(TWITCH_HELIX_BASEURL + "streams/markers", body, TwitchHelixSerializerContext.Default.ResponseBaseCreateStreamMarkerData, cancellationToken).ConfigureAwait(false); + return await PostAsync(TWITCH_HELIX_BASEURL + "streams/markers", body, + TwitchHelixSerializerContext.Default.CreateStreamMarkerRequestDto, + TwitchHelixSerializerContext.Default.ResponseBaseCreateStreamMarkerData, + cancellationToken) + .ConfigureAwait(false); } /// @@ -187,7 +191,11 @@ void CheckCount(ref string[]? array, out bool hasBool) var body = new ChatSettingsRequestDto(emoteMode, followerMode, followerModeDurationMinutes, nonModeratorChatDelay, nonModeratorChatDelayDurationSeconds, slowMode, slowModeWaitTimeSeconds, subscriberMode, uniqueChatMode); - return await PatchAsync(urlBuilder, body, TwitchHelixSerializerContext.Default.ResponseBaseChatSettings, cancellationToken).ConfigureAwait(false); + return await PatchAsync(urlBuilder, body, + TwitchHelixSerializerContext.Default.ChatSettingsRequestDto, + TwitchHelixSerializerContext.Default.ResponseBaseChatSettings, + cancellationToken) + .ConfigureAwait(false); } /// @@ -258,7 +266,11 @@ void CheckCount(ref string[]? array, out bool hasBool) var body = new BanUserRequestDto(userId, durationSeconds, reason); var bodyWrapper = new LegacyRequestDataWrapper(body); - return await PostAsync(urlBuilder, bodyWrapper, TwitchHelixSerializerContext.Default.ResponseBaseBanUser, cancellationToken).ConfigureAwait(false); + return await PostAsync(urlBuilder, bodyWrapper, + TwitchHelixSerializerContext.Default.LegacyRequestDataWrapperBanUserRequestDto, + TwitchHelixSerializerContext.Default.ResponseBaseBanUser, + cancellationToken) + .ConfigureAwait(false); } /// @@ -279,7 +291,7 @@ public async Task SendChatAnnouncement(string broadcasterId, string messag var urlBuilder = TWITCH_HELIX_BASEURL + "chat/announcements?broadcaster_id=" + broadcasterId + "&moderator_id=" + loggedInUser.UserId; var body = new SendChatAnnouncementRequestDto(message, color); - return await PostAsync(urlBuilder, body, cancellationToken).ConfigureAwait(false); + return await PostAsync(urlBuilder, body, TwitchHelixSerializerContext.Default.SendChatAnnouncementRequestDto, cancellationToken).ConfigureAwait(false); } /// @@ -484,7 +496,11 @@ void OptionalParametersValidation(ref bool? voteEnabled, ref uint? costPerVote, OptionalParametersValidation(ref channelPointsVotingEnabled, ref channelPointsPerVote, 1000000); var body = new CreatePollRequestDto(loggedInUser.UserId, title, pollChoices, duration, channelPointsVotingEnabled, channelPointsPerVote); - return await PostAsync(TWITCH_HELIX_BASEURL + "polls", body, TwitchHelixSerializerContext.Default.ResponseBasePollData, cancellationToken).ConfigureAwait(false); + return await PostAsync(TWITCH_HELIX_BASEURL + "polls", body, + TwitchHelixSerializerContext.Default.CreatePollRequestDto, + TwitchHelixSerializerContext.Default.ResponseBasePollData, + cancellationToken) + .ConfigureAwait(false); } /// @@ -503,7 +519,11 @@ void OptionalParametersValidation(ref bool? voteEnabled, ref uint? costPerVote, } var body = new EndPollRequestDto(loggedInUser.UserId, pollId, pollStatus); - return await PatchAsync(TWITCH_HELIX_BASEURL + "polls", body, TwitchHelixSerializerContext.Default.ResponseBasePollData, cancellationToken).ConfigureAwait(false); + return await PatchAsync(TWITCH_HELIX_BASEURL + "polls", body, + TwitchHelixSerializerContext.Default.EndPollRequestDto, + TwitchHelixSerializerContext.Default.ResponseBasePollData, + cancellationToken) + .ConfigureAwait(false); } /// @@ -586,7 +606,11 @@ void OptionalParametersValidation(ref bool? voteEnabled, ref uint? costPerVote, } var body = new CreatePredictionsRequestDto(loggedInUser.UserId, title, predictionOutcomes, duration); - return await PostAsync(TWITCH_HELIX_BASEURL + "predictions", body, TwitchHelixSerializerContext.Default.ResponseBasePredictionData, cancellationToken).ConfigureAwait(false); + return await PostAsync(TWITCH_HELIX_BASEURL + "predictions", body, + TwitchHelixSerializerContext.Default.CreatePredictionsRequestDto, + TwitchHelixSerializerContext.Default.ResponseBasePredictionData, + cancellationToken) + .ConfigureAwait(false); } /// @@ -610,7 +634,11 @@ void OptionalParametersValidation(ref bool? voteEnabled, ref uint? costPerVote, } var body = new EndPredictionRequestDto(loggedInUser.UserId, predictionId, predictionStatus, winningOutcomeId); - return await PatchAsync(TWITCH_HELIX_BASEURL + "predictions", body, TwitchHelixSerializerContext.Default.ResponseBasePredictionData, cancellationToken).ConfigureAwait(false); + return await PatchAsync(TWITCH_HELIX_BASEURL + "predictions", body, + TwitchHelixSerializerContext.Default.EndPredictionRequestDto, + TwitchHelixSerializerContext.Default.ResponseBasePredictionData, + cancellationToken) + .ConfigureAwait(false); } /// diff --git a/CatCore/Services/Twitch/TwitchHelixApiService.cs b/CatCore/Services/Twitch/TwitchHelixApiService.cs index 455d159..75e09dd 100644 --- a/CatCore/Services/Twitch/TwitchHelixApiService.cs +++ b/CatCore/Services/Twitch/TwitchHelixApiService.cs @@ -88,25 +88,27 @@ private async Task CheckUserLoggedIn() => CallEndpointNoBodyExpectBody(HttpMethod.Get, url, jsonResponseTypeInfo, cancellationToken); [MethodImpl(MethodImplOptions.AggressiveInlining)] - private Task PostAsync(string url, TBody body, JsonTypeInfo jsonResponseTypeInfo, CancellationToken cancellationToken = default) - where TResponse : struct => CallEndpointWithBodyExpectBody(HttpMethod.Post, url, body, jsonResponseTypeInfo, cancellationToken); + private Task PostAsync(string url, TBody body, JsonTypeInfo jsonRequestTypeInfo, JsonTypeInfo jsonResponseTypeInfo, CancellationToken cancellationToken = default) + where TResponse : struct => CallEndpointWithBodyExpectBody(HttpMethod.Post, url, body, jsonRequestTypeInfo, jsonResponseTypeInfo, cancellationToken); [MethodImpl(MethodImplOptions.AggressiveInlining)] private Task PostAsync(string url, JsonTypeInfo jsonResponseTypeInfo, CancellationToken cancellationToken = default) where TResponse : struct => CallEndpointNoBodyExpectBody(HttpMethod.Post, url, jsonResponseTypeInfo, cancellationToken); [MethodImpl(MethodImplOptions.AggressiveInlining)] - private Task PostAsync(string url, TBody body, CancellationToken cancellationToken = default) => CallEndpointWithBodyNoBody(HttpMethod.Post, url, body, cancellationToken); + private Task PostAsync(string url, TBody body, JsonTypeInfo jsonRequestTypeInfo, CancellationToken cancellationToken = default) + => CallEndpointWithBodyNoBody(HttpMethod.Post, url, body, jsonRequestTypeInfo, cancellationToken); [MethodImpl(MethodImplOptions.AggressiveInlining)] private Task PutAsync(string url, CancellationToken cancellationToken = default) => CallEndpointNoBodyNoBody(HttpMethod.Put, url, cancellationToken); [MethodImpl(MethodImplOptions.AggressiveInlining)] - private Task PatchAsync(string url, TBody body, JsonTypeInfo jsonResponseTypeInfo, CancellationToken cancellationToken = default) - where TResponse : struct => CallEndpointWithBodyExpectBody(HttpMethodPatch, url, body, jsonResponseTypeInfo, cancellationToken); + private Task PatchAsync(string url, TBody body, JsonTypeInfo jsonRequestTypeInfo, JsonTypeInfo jsonResponseTypeInfo, CancellationToken cancellationToken = default) + where TResponse : struct => CallEndpointWithBodyExpectBody(HttpMethodPatch, url, body, jsonRequestTypeInfo, jsonResponseTypeInfo, cancellationToken); [MethodImpl(MethodImplOptions.AggressiveInlining)] - private Task PatchAsync(string url, TBody body, CancellationToken cancellationToken = default) => CallEndpointWithBodyNoBody(HttpMethodPatch, url, body, cancellationToken); + private Task PatchAsync(string url, TBody body, JsonTypeInfo jsonRequestTypeInfo, CancellationToken cancellationToken = default) + => CallEndpointWithBodyNoBody(HttpMethodPatch, url, body, jsonRequestTypeInfo, cancellationToken); [MethodImpl(MethodImplOptions.AggressiveInlining)] private Task DeleteAsync(string url, CancellationToken cancellationToken = default) => CallEndpointNoBodyNoBody(HttpMethod.Delete, url, cancellationToken); @@ -221,8 +223,9 @@ private async Task CallEndpointNoBodyNoBody(HttpMethod httpMethod, string } } - private async Task CallEndpointWithBodyExpectBody(HttpMethod httpMethod, string url, TBody body, JsonTypeInfo jsonResponseTypeInfo, - CancellationToken cancellationToken = default) where TResponse : struct + private async Task CallEndpointWithBodyExpectBody(HttpMethod httpMethod, string url, TBody body, JsonTypeInfo jsonRequestTypeInfo, + JsonTypeInfo jsonResponseTypeInfo, CancellationToken cancellationToken = default) + where TResponse : struct { #if DEBUG if (string.IsNullOrWhiteSpace(url)) @@ -252,7 +255,7 @@ private async Task CallEndpointNoBodyNoBody(HttpMethod httpMethod, string { using var httpResponseMessage = await _combinedHelixPolicy.ExecuteAsync(async ct => { - using var jsonContent = JsonContent.Create(body); + using var jsonContent = JsonContent.Create(body, options: jsonRequestTypeInfo.Options); using var httpRequestMessage = new HttpRequestMessage(httpMethod, url) { Content = jsonContent }; return await _helixClient.SendAsync(httpRequestMessage, HttpCompletionOption.ResponseHeadersRead, ct).ConfigureAwait(false); }, cancellationToken).ConfigureAwait(false); @@ -283,7 +286,7 @@ private async Task CallEndpointNoBodyNoBody(HttpMethod httpMethod, string } } - private async Task CallEndpointWithBodyNoBody(HttpMethod httpMethod, string url, TBody body, CancellationToken cancellationToken = default) + private async Task CallEndpointWithBodyNoBody(HttpMethod httpMethod, string url, TBody body, JsonTypeInfo jsonRequestTypeInfo, CancellationToken cancellationToken = default) { #if DEBUG if (string.IsNullOrWhiteSpace(url)) @@ -313,7 +316,7 @@ private async Task CallEndpointWithBodyNoBody(HttpMethod httpMethod { using var httpResponseMessage = await _combinedHelixPolicy.ExecuteAsync(async ct => { - using var jsonContent = JsonContent.Create(body); + using var jsonContent = JsonContent.Create(body, options: jsonRequestTypeInfo.Options); using var httpRequestMessage = new HttpRequestMessage(httpMethod, url) { Content = jsonContent }; return await _helixClient.SendAsync(httpRequestMessage, HttpCompletionOption.ResponseHeadersRead, ct).ConfigureAwait(false); }, cancellationToken).ConfigureAwait(false); From cf5a9cc92f1a39dfebf5c7b4a37597ffa2a3fcb4 Mon Sep 17 00:00:00 2001 From: Eris Date: Fri, 14 Apr 2023 16:00:27 +0200 Subject: [PATCH 2/2] Redo usings in TwitchHelixSerializerContext --- .../JSON/TwitchHelixSerializerContext.cs | 61 ++++++++----------- 1 file changed, 25 insertions(+), 36 deletions(-) diff --git a/CatCore/Helpers/JSON/TwitchHelixSerializerContext.cs b/CatCore/Helpers/JSON/TwitchHelixSerializerContext.cs index ac938c0..a2a289b 100644 --- a/CatCore/Helpers/JSON/TwitchHelixSerializerContext.cs +++ b/CatCore/Helpers/JSON/TwitchHelixSerializerContext.cs @@ -1,49 +1,38 @@ using System.Text.Json.Serialization; -using CatCore.Models.Twitch.Helix.Requests; -using CatCore.Models.Twitch.Helix.Requests.Bans; -using CatCore.Models.Twitch.Helix.Requests.Polls; -using CatCore.Models.Twitch.Helix.Requests.Predictions; -using CatCore.Models.Twitch.Helix.Responses; -using CatCore.Models.Twitch.Helix.Responses.Badges; -using CatCore.Models.Twitch.Helix.Responses.Bans; -using CatCore.Models.Twitch.Helix.Responses.Bits.Cheermotes; -using CatCore.Models.Twitch.Helix.Responses.Emotes; -using CatCore.Models.Twitch.Helix.Responses.Polls; -using CatCore.Models.Twitch.Helix.Responses.Predictions; using HelixRequests = CatCore.Models.Twitch.Helix.Requests; using HelixResponses = CatCore.Models.Twitch.Helix.Responses; namespace CatCore.Helpers.JSON { - [JsonSerializable(typeof(ResponseBase))] - [JsonSerializable(typeof(CreateStreamMarkerRequestDto))] - [JsonSerializable(typeof(ResponseBase))] - [JsonSerializable(typeof(ResponseBaseWithPagination))] + [JsonSerializable(typeof(HelixResponses.ResponseBase))] + [JsonSerializable(typeof(HelixRequests.CreateStreamMarkerRequestDto))] + [JsonSerializable(typeof(HelixResponses.ResponseBase))] + [JsonSerializable(typeof(HelixResponses.ResponseBaseWithPagination))] [JsonSerializable(typeof(HelixRequests.Polls.PollChoice), TypeInfoPropertyName = "RequestPollChoice")] [JsonSerializable(typeof(HelixResponses.Polls.PollChoice), TypeInfoPropertyName = "ResponsePollChoice")] - [JsonSerializable(typeof(ResponseBaseWithPagination))] - [JsonSerializable(typeof(CreatePollRequestDto))] - [JsonSerializable(typeof(EndPollRequestDto))] - [JsonSerializable(typeof(ResponseBase))] + [JsonSerializable(typeof(HelixResponses.ResponseBaseWithPagination))] + [JsonSerializable(typeof(HelixRequests.Polls.CreatePollRequestDto))] + [JsonSerializable(typeof(HelixRequests.Polls.EndPollRequestDto))] + [JsonSerializable(typeof(HelixResponses.ResponseBase))] [JsonSerializable(typeof(HelixRequests.Predictions.Outcome), TypeInfoPropertyName = "RequestOutcome")] [JsonSerializable(typeof(HelixResponses.Predictions.Outcome), TypeInfoPropertyName = "ResponseOutcome")] - [JsonSerializable(typeof(ResponseBaseWithPagination))] - [JsonSerializable(typeof(CreatePredictionsRequestDto))] - [JsonSerializable(typeof(EndPredictionRequestDto))] - [JsonSerializable(typeof(ResponseBase))] - [JsonSerializable(typeof(ResponseBase))] - [JsonSerializable(typeof(ResponseBase))] - [JsonSerializable(typeof(ResponseBaseWithPagination))] - [JsonSerializable(typeof(ResponseBaseWithTemplate))] - [JsonSerializable(typeof(ResponseBaseWithTemplate))] - [JsonSerializable(typeof(ChatSettingsRequestDto))] - [JsonSerializable(typeof(ResponseBase))] - [JsonSerializable(typeof(ResponseBaseWithPagination))] - [JsonSerializable(typeof(LegacyRequestDataWrapper))] - [JsonSerializable(typeof(ResponseBase))] - [JsonSerializable(typeof(SendChatAnnouncementRequestDto))] - [JsonSerializable(typeof(ResponseBase))] - [JsonSerializable(typeof(ResponseBase))] + [JsonSerializable(typeof(HelixResponses.ResponseBaseWithPagination))] + [JsonSerializable(typeof(HelixRequests.Predictions.CreatePredictionsRequestDto))] + [JsonSerializable(typeof(HelixRequests.Predictions.EndPredictionRequestDto))] + [JsonSerializable(typeof(HelixResponses.ResponseBase))] + [JsonSerializable(typeof(HelixResponses.ResponseBase))] + [JsonSerializable(typeof(HelixResponses.ResponseBase))] + [JsonSerializable(typeof(HelixResponses.ResponseBaseWithPagination))] + [JsonSerializable(typeof(HelixResponses.ResponseBaseWithTemplate))] + [JsonSerializable(typeof(HelixResponses.ResponseBaseWithTemplate))] + [JsonSerializable(typeof(HelixRequests.ChatSettingsRequestDto))] + [JsonSerializable(typeof(HelixResponses.ResponseBase))] + [JsonSerializable(typeof(HelixResponses.ResponseBaseWithPagination))] + [JsonSerializable(typeof(HelixRequests.LegacyRequestDataWrapper))] + [JsonSerializable(typeof(HelixResponses.ResponseBase))] + [JsonSerializable(typeof(HelixRequests.SendChatAnnouncementRequestDto))] + [JsonSerializable(typeof(HelixResponses.ResponseBase))] + [JsonSerializable(typeof(HelixResponses.ResponseBase))] internal partial class TwitchHelixSerializerContext : JsonSerializerContext { }