Skip to content

Commit

Permalink
com.utilities.rest 3.1.0 (#79)
Browse files Browse the repository at this point in the history
- refactor Server Sent Event Implementation
- added Response.ctr with reference to UnityWebRequest
- added Response.ServerSentEvents list
- sealed all public classes
  • Loading branch information
StephenHodgson committed Jun 7, 2024
1 parent 1b96408 commit 243cd19
Show file tree
Hide file tree
Showing 12 changed files with 300 additions and 128 deletions.
21 changes: 3 additions & 18 deletions Documentation~/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ Advanced features includes progress notifications, authentication and native mul
- [Rest Parameters](#rest-parameters)
- [Get](#get)
- [Post](#post)
- [Server Sent Events](#server-sent-events)
- [Server Sent Events](#server-sent-events) :new:
- [Data Received Callbacks](#data-received-callbacks)
- [Put](#put)
- [Patch](#patch)
Expand Down Expand Up @@ -115,25 +115,10 @@ response.Validate(debug: true);

#### Server Sent Events

> [!WARNING]
> Breaking change. `eventData` payloads are now json objects where the type is the key and field data is value.
> For existing data callbacks, they are now nested: `{"data":"{<payload data>}"}`
Handles [server sent event](https://html.spec.whatwg.org/multipage/server-sent-events.html#server-sent-events) messages.

`eventData` json Schema:

```json
{
"type":"value",
"data":"{<payload data>}" // nullable
}
```

```csharp
var jsonData = "{\"data\":\"content\"}";
var response = await Rest.PostAsync("www.your.api/endpoint", jsonData, eventData => {
Debug.Log(eventData);
var response = await Rest.PostAsync("www.your.api/endpoint", jsonData, (sseResponse, ssEvent) => {
Debug.Log(ssEvent);
});
// Validates the response for you and will throw a RestException if the response is unsuccessful.
response.Validate(debug: true);
Expand Down
2 changes: 1 addition & 1 deletion Runtime/Extensions/EmptyToNullStringContractResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ namespace Utilities.Rest.Extensions
/// Converts empty strings to null values so they are properly ignored by the serializer.
/// https://stackoverflow.com/questions/39855694/convert-empty-strings-to-null-with-json-net
/// </summary>
public class EmptyToNullStringContractResolver : DefaultContractResolver
public sealed class EmptyToNullStringContractResolver : DefaultContractResolver
{
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
=> type.GetProperties()
Expand Down
2 changes: 1 addition & 1 deletion Runtime/Extensions/EmptyToNullStringValueProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace Utilities.Rest.Extensions
/// <summary>
/// https://stackoverflow.com/questions/39855694/convert-empty-strings-to-null-with-json-net
/// </summary>
public class EmptyToNullStringValueProvider : IValueProvider
public sealed class EmptyToNullStringValueProvider : IValueProvider
{
private readonly PropertyInfo memberInfo;

Expand Down
89 changes: 75 additions & 14 deletions Runtime/Response.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,17 @@
using System;
using System.Collections.Generic;
using System.Text;
using UnityEngine.Networking;

namespace Utilities.WebRequestRest
{
/// <summary>
/// Response to a REST Call.
/// </summary>
public class Response
public sealed class Response
{
private static readonly Dictionary<string, string> invalidHeaders = new() { { "Invalid Headers", "Invalid Headers" } };

/// <summary>
/// The original request that prompted the response.
/// </summary>
Expand Down Expand Up @@ -63,6 +66,66 @@ public class Response
/// </summary>
public RestParameters Parameters { get; }

/// <summary>
/// Full list of server sent events.
/// </summary>
public IReadOnlyList<ServerSentEvent> ServerSentEvents => Parameters?.ServerSentEvents;

/// <summary>
/// Constructor.
/// </summary>
/// <param name="webRequest">The request that prompted the response.</param>
/// <param name="requestBody">The request body that prompted the response.</param>
/// <param name="successful">Was the request successful?</param>
/// <param name="parameters">The parameters of the request.</param>
/// <param name="responseBody">Optional, response body override.</param>
public Response(UnityWebRequest webRequest, string requestBody, bool successful, RestParameters parameters, string responseBody = null)
{
Request = webRequest.url;
RequestBody = requestBody;
Method = webRequest.method;
Successful = successful;

if (string.IsNullOrWhiteSpace(responseBody))
{
switch (webRequest.downloadHandler)
{
case DownloadHandlerFile:
case DownloadHandlerTexture:
case DownloadHandlerAudioClip:
case DownloadHandlerAssetBundle:
Body = null;
Data = null;
break;
case DownloadHandlerBuffer downloadHandlerBuffer:
Body = downloadHandlerBuffer.text;
Data = downloadHandlerBuffer.data;
break;
case DownloadHandlerScript downloadHandlerScript:
Body = downloadHandlerScript.text;
Data = downloadHandlerScript.data;
break;
default:
Body = webRequest.responseCode == 401 ? "Invalid Credentials" : webRequest.downloadHandler?.text;
Data = webRequest.downloadHandler?.data;
break;
}
}
else
{
Body = responseBody;
}

Code = webRequest.responseCode;
Headers = webRequest.GetResponseHeaders() ?? invalidHeaders;
Parameters = parameters;

if (!successful)
{
Error = $"{webRequest.error}\n{webRequest.downloadHandler?.error}";
}
}

/// <summary>
/// Constructor.
/// </summary>
Expand Down Expand Up @@ -158,29 +221,27 @@ public string ToString(string methodName)
{
if (Parameters.ServerSentEvents.Count > 0)
{
debugMessageObject["response"]["body"] = new JArray();
var array = new JArray();

foreach (var (type, value, data) in Parameters.ServerSentEvents)
foreach (var @event in Parameters.ServerSentEvents)
{
var eventObject = new JObject
{
[type] = value
[@event.Event.ToString().ToLower()] = @event.Value
};

if (!string.IsNullOrWhiteSpace(data))
if (@event.Data != null)
{
try
{
eventObject[nameof(data)] = JToken.Parse(data);
}
catch
{
eventObject[nameof(data)] = data;
}
eventObject["data"] = @event.Data;
}

((JArray)debugMessageObject["response"]["body"]).Add(eventObject);
array.Add(eventObject);
}

debugMessageObject["response"]["body"] = new JObject
{
["events"] = array
};
}
else
{
Expand Down
Loading

0 comments on commit 243cd19

Please sign in to comment.