Skip to content

Commit

Permalink
✨ feat: add api to retrieve the latest data for server and client sdks (
Browse files Browse the repository at this point in the history
#275)

* get latest data for server & client sdk

* fix

* pr feedback
  • Loading branch information
deleteLater committed Mar 21, 2023
1 parent c97109f commit d431153
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 40 deletions.
59 changes: 59 additions & 0 deletions modules/evaluation-server/src/Api/Public/SdkController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
using Domain.EndUsers;
using Domain.Services;
using Microsoft.AspNetCore.Mvc;

namespace Api.Public;

public class SdkController : PublicApiControllerBase
{
private readonly IDataSyncService _dataSyncService;

public SdkController(IDataSyncService dataSyncService)
{
_dataSyncService = dataSyncService;
}

[HttpGet("server/latest-all")]
public async Task<IActionResult> GetServerSideSdkPayloadAsync()
{
if (!Authenticated)
{
return Unauthorized();
}

var payload = await _dataSyncService.GetServerSdkPayloadAsync(EnvId, 0);

var bootstrap = new
{
messageType = "data-sync",
data = payload
};

return new JsonResult(bootstrap);
}

[HttpPost("client/latest-all")]
public async Task<IActionResult> GetClientSdkPayloadAsync(EndUser endUser)
{
if (!Authenticated)
{
return Unauthorized();
}

if (!endUser.IsValid())
{
return BadRequest("invalid end user");
}

var payload = await _dataSyncService.GetClientSdkPayloadAsync(EnvId, endUser, 0);

var bootstrap = payload.FeatureFlags.Select(x => new
{
x.Id,
x.Variation,
x.VariationType
});

return new JsonResult(bootstrap);
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Text.Json;
using Domain.EndUsers;
using Domain.Protocol;
using Domain.WebSockets;

Expand All @@ -8,6 +9,10 @@ public interface IDataSyncService
{
Task<object> GetPayloadAsync(Connection connection, DataSyncMessage message);

Task<ClientSdkPayload> GetClientSdkPayloadAsync(Guid envId, EndUser user, long timestamp);

Task<ServerSdkPayload> GetServerSdkPayloadAsync(Guid envId, long timestamp);

Task<object> GetFlagChangePayloadAsync(Connection connection, JsonElement flag);

Task<object> GetSegmentChangePayloadAsync(Connection connection, JsonElement segment, string[] affectedFlagIds);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,47 @@ public async Task<object> GetPayloadAsync(Connection connection, DataSyncMessage
return payload;
}

public async Task<ClientSdkPayload> GetClientSdkPayloadAsync(Guid envId, EndUser user, long timestamp)
{
var eventType = timestamp == 0 ? DataSyncEventTypes.Full : DataSyncEventTypes.Patch;
var flagsBytes = await _cacheService.GetFlagsAsync(envId, timestamp);

var clientSdkFlags = new List<ClientSdkFlag>();
foreach (var flagBytes in flagsBytes)
{
using var document = JsonDocument.Parse(flagBytes);
var flag = document.RootElement;

clientSdkFlags.Add(await GetClientSdkFlagAsync(flag, user));
}

return new ClientSdkPayload(eventType, user.KeyId, clientSdkFlags);
}

public async Task<ServerSdkPayload> GetServerSdkPayloadAsync(Guid envId, long timestamp)
{
var eventType = timestamp == 0 ? DataSyncEventTypes.Full : DataSyncEventTypes.Patch;
var featureFlags = new List<JsonObject>();
var segments = new List<JsonObject>();

var flagsBytes = await _cacheService.GetFlagsAsync(envId, timestamp);
foreach (var flag in flagsBytes)
{
var jsonObject = JsonNode.Parse(flag)!.AsObject();
jsonObject.Remove("");
featureFlags.Add(jsonObject);
}

var segmentsBytes = await _cacheService.GetSegmentsAsync(envId, timestamp);
foreach (var segment in segmentsBytes)
{
var jsonObject = JsonNode.Parse(segment)!.AsObject();
segments.Add(jsonObject);
}

return new ServerSdkPayload(eventType, featureFlags, segments);
}

public async Task<object> GetFlagChangePayloadAsync(Connection connection, JsonElement flag)
{
if (connection.Type == ConnectionType.Client && connection.User == null)
Expand Down Expand Up @@ -118,23 +159,6 @@ private async Task<ClientSdkFlag> GetClientSdkFlagAsync(JsonElement flag, EndUse
return new ClientSdkFlag(flag, userVariation, variations);
}

private async Task<ClientSdkPayload> GetClientSdkPayloadAsync(Guid envId, EndUser user, long timestamp)
{
var eventType = timestamp == 0 ? DataSyncEventTypes.Full : DataSyncEventTypes.Patch;
var flagsBytes = await _cacheService.GetFlagsAsync(envId, timestamp);

var clientSdkFlags = new List<ClientSdkFlag>();
foreach (var flagBytes in flagsBytes)
{
using var document = JsonDocument.Parse(flagBytes);
var flag = document.RootElement;

clientSdkFlags.Add(await GetClientSdkFlagAsync(flag, user));
}

return new ClientSdkPayload(eventType, user.KeyId, clientSdkFlags);
}

#endregion

#region get server sdk payload
Expand All @@ -157,28 +181,5 @@ private ServerSdkPayload GetServerSdkSegmentChangePayload(JsonElement segment)
);
}

private async Task<ServerSdkPayload> GetServerSdkPayloadAsync(Guid envId, long timestamp)
{
var eventType = timestamp == 0 ? DataSyncEventTypes.Full : DataSyncEventTypes.Patch;
var featureFlags = new List<JsonObject>();
var segments = new List<JsonObject>();

var flagsBytes = await _cacheService.GetFlagsAsync(envId, timestamp);
foreach (var flag in flagsBytes)
{
var jsonObject = JsonNode.Parse(flag)!.AsObject();
featureFlags.Add(jsonObject);
}

var segmentsBytes = await _cacheService.GetSegmentsAsync(envId, timestamp);
foreach (var segment in segmentsBytes)
{
var jsonObject = JsonNode.Parse(segment)!.AsObject();
segments.Add(jsonObject);
}

return new ServerSdkPayload(eventType, featureFlags, segments);
}

#endregion
}

0 comments on commit d431153

Please sign in to comment.