From 2fcf4e33ce814824733d2677c3ef5d9077e39190 Mon Sep 17 00:00:00 2001 From: Gabriel Sales Date: Wed, 15 Jan 2025 18:52:08 -0300 Subject: [PATCH 1/4] Fix docs --- readme.md | 2 -- readme.pt-br.md | 3 --- 2 files changed, 5 deletions(-) diff --git a/readme.md b/readme.md index 6f942fb..0c10581 100644 --- a/readme.md +++ b/readme.md @@ -115,8 +115,6 @@ SSYNC.LiteDB aims to simplify implementing data synchronization between the fron ## ![alt text](doc/flow_update_server_changes.jpg "Img Update server changes") -## Flow (en=us): -![alt text](doc/notes_ssync_en.png "Img Flow ssynclitedb en-us")

🔙 Backend

diff --git a/readme.pt-br.md b/readme.pt-br.md index a0f756d..66998a9 100644 --- a/readme.pt-br.md +++ b/readme.pt-br.md @@ -112,9 +112,6 @@ SSYNC.LiteDB tem como objetivo facilitar a implementação de sincronização de ## ![alt text](doc/flow_update_server_changes.jpg "Img Update server changes") -## Flow (pt-br): -![alt text](doc/notes_ssync_pt_br.png "Img Flow ssynclitedb pt-br") -

🔙 Backend

From 56673953912a4d22a2066ca335b84c8cb442be71 Mon Sep 17 00:00:00 2001 From: Gabriel Sales Date: Wed, 15 Jan 2025 21:52:54 -0300 Subject: [PATCH 2/4] To create map endpoint api --- src/SSync.Server.LiteDB.PlayGround/Program.cs | 82 ++++++++++--------- .../Properties/launchSettings.json | 2 +- .../Extensions/SSyncApiEndPointExtension.cs | 76 +++++++++++++++++ .../SSync.Server.LitebDB.csproj | 10 +++ 4 files changed, 131 insertions(+), 39 deletions(-) create mode 100644 src/SSync.Server.LitebDB/Extensions/SSyncApiEndPointExtension.cs diff --git a/src/SSync.Server.LiteDB.PlayGround/Program.cs b/src/SSync.Server.LiteDB.PlayGround/Program.cs index d148bbd..b600f8d 100644 --- a/src/SSync.Server.LiteDB.PlayGround/Program.cs +++ b/src/SSync.Server.LiteDB.PlayGround/Program.cs @@ -4,6 +4,7 @@ using SSync.Server.LitebDB.Abstractions; using SSync.Server.LitebDB.Engine; using SSync.Server.LitebDB.Enums; +using SSync.Server.LitebDB.Extensions; using SSync.Server.LiteDB.PlayGround.Data; using SSync.Server.LiteDB.PlayGround.Model; using SSync.Server.LiteDB.PlayGround.Sync; @@ -34,44 +35,49 @@ app.UseHttpsRedirection(); -app.MapGet("/pull", async ([AsParameters] PlayParamenter parameter, [FromServices] ISchemaCollection schemaCollection) => -{ - var pullChangesRemoter = await schemaCollection.PullChangesAsync(parameter, new SSyncOptions() - { - Mode = Mode.DEBUG - }); - - return Results.Ok(pullChangesRemoter); -}); - -app.MapPost("/push", async (HttpContext httpContext, JsonArray changes, [FromServices] ISchemaCollection schemaCollection) => -{ - var query = httpContext.Request.Query; - - var parameter = new PlayParamenter - { - Time = Convert.ToInt32(query["time"]), - Colletions = query["colletions"].ToArray()!, - Timestamp = DateTime.TryParse(query["timestamp"], out DateTime timestamp) ? timestamp : DateTime.MinValue - }; - - var isOk = await schemaCollection.PushChangesAsync(changes, parameter, new SSyncOptions() - { - Mode = Mode.DEBUG - }); - - return Results.Ok(isOk); -}); - -app.MapGet("/pull-stream", ([AsParameters] PlayParamenter parameter, [FromServices] ISchemaCollection schemaCollection) => -{ - var pullChangesRemoter = schemaCollection.PullStreamChanges(parameter, new SSyncOptions() - { - Mode = Mode.DEBUG - }); - - return Results.Ok(pullChangesRemoter); -}); +app.MapApiEndpointsSync(); + + +//custom endpoints + +// app.MapGet("/pull", async ([AsParameters] SSyncParameter parameter, [FromServices] ISchemaCollection schemaCollection) => +// { +// var pullChangesRemoter = await schemaCollection.PullChangesAsync(parameter, new SSyncOptions() +// { +// Mode = Mode.DEBUG +// }); +// +// return Results.Ok(pullChangesRemoter); +// }); +// +// app.MapPost("/push", async (HttpContext httpContext, JsonArray changes, [FromServices] ISchemaCollection schemaCollection) => +// { +// var query = httpContext.Request.Query; +// +// var parameter = new SSyncParameter +// { +// // Time = Convert.ToInt32(query["time"]), +// Colletions = query["colletions"].ToArray()!, +// Timestamp = DateTime.TryParse(query["timestamp"], out DateTime timestamp) ? timestamp : DateTime.MinValue +// }; +// +// var isOk = await schemaCollection.PushChangesAsync(changes, parameter, new SSyncOptions() +// { +// Mode = Mode.DEBUG +// }); +// +// return Results.Ok(isOk); +// }); + +// app.MapGet("/pull-stream", ([AsParameters] SSyncParameter parameter, [FromServices] ISchemaCollection schemaCollection) => +// { +// var pullChangesRemoter = schemaCollection.PullStreamChanges(parameter, new SSyncOptions() +// { +// Mode = Mode.DEBUG +// }); +// +// return Results.Ok(pullChangesRemoter); +// }); app.MapGet("/list", async ([FromServices] TestDbContext cxt) => diff --git a/src/SSync.Server.LiteDB.PlayGround/Properties/launchSettings.json b/src/SSync.Server.LiteDB.PlayGround/Properties/launchSettings.json index e85037d..c408b62 100644 --- a/src/SSync.Server.LiteDB.PlayGround/Properties/launchSettings.json +++ b/src/SSync.Server.LiteDB.PlayGround/Properties/launchSettings.json @@ -24,7 +24,7 @@ "commandName": "Project", "dotnetRunMessages": true, "launchBrowser": true, - "launchUrl": "pull?Colletions=User&Timestamp=1/1/0001 12:00:00 AM&Time=34234", + "launchUrl": "api/v1/sync/pull?Colletions=User&Timestamp=1/1/0001 12:00:00 AM&Time=34234", "applicationUrl": "https://localhost:7208;http://localhost:5130", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" diff --git a/src/SSync.Server.LitebDB/Extensions/SSyncApiEndPointExtension.cs b/src/SSync.Server.LitebDB/Extensions/SSyncApiEndPointExtension.cs new file mode 100644 index 0000000..333df44 --- /dev/null +++ b/src/SSync.Server.LitebDB/Extensions/SSyncApiEndPointExtension.cs @@ -0,0 +1,76 @@ +using System.Text.Encodings.Web; +using System.Text.Json; +using System.Text.Json.Nodes; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Routing; +using SSync.Server.LitebDB.Abstractions; +using SSync.Server.LitebDB.Engine; + + +namespace SSync.Server.LitebDB.Extensions; + +public static class SSyncApiEndPointExtension +{ + /// + /// Add endpoints pull, push and pull stream (IasyncEnumerable) + /// + /// + /// + /// + /// + /// + /// + public static IEndpointConventionBuilder MapApiEndpointsSync(this IEndpointRouteBuilder endpoints, + SSyncOptions? options = null, + string version = "v1", + string route = "sync") + where TParamenterSync : SSyncParameter, new() + { + var routeGroup = endpoints.MapGroup($"api/{version}/{route}"); + + + routeGroup.MapGet("/pull", + async ([AsParameters] TParamenterSync parameter, [FromServices] ISchemaCollection schemaCollection) => + { + var pullChangesRemoter = await schemaCollection.PullChangesAsync(parameter, options); + + return Results.Ok(pullChangesRemoter); + }); + + //fix: minimal api not support two complex object, like [FromBody] JsonArray changes and [AsParameters/FromQuery] TParamenterSync paramenter + // Create this workaround + routeGroup.MapPost("/push", async ( + [FromBody] JsonArray changes, + HttpContext httpContext, + [FromServices] ISchemaCollection schemaCollection) => + { + var query = httpContext.Request.Query; + + var parameter = new TParamenterSync + { + Colletions = query["colletions"].ToArray()!, + Timestamp = DateTime.TryParse(query["timestamp"], out DateTime timestamp) + ? timestamp + : DateTime.MinValue + }; + + var isOk = await schemaCollection.PushChangesAsync(changes, parameter, options); + + return Results.Ok(isOk); + }); + + + routeGroup.MapGet("/pull-stream", + ([AsParameters] TParamenterSync parameter, [FromServices] ISchemaCollection schemaCollection) => + { + var pullChangesRemoter = schemaCollection.PullStreamChanges(parameter, options); + + return Results.Ok(pullChangesRemoter); + }); + + + return routeGroup; + } +} \ No newline at end of file diff --git a/src/SSync.Server.LitebDB/SSync.Server.LitebDB.csproj b/src/SSync.Server.LitebDB/SSync.Server.LitebDB.csproj index 904c151..8dfd1fe 100644 --- a/src/SSync.Server.LitebDB/SSync.Server.LitebDB.csproj +++ b/src/SSync.Server.LitebDB/SSync.Server.LitebDB.csproj @@ -36,4 +36,14 @@ + + + + + + + ..\..\..\..\..\..\..\Program Files\dotnet\shared\Microsoft.AspNetCore.App\8.0.11\Microsoft.AspNetCore.dll + + + From 8d7c227caeaabd3f82224246dab9d698d29d3b5c Mon Sep 17 00:00:00 2001 From: Gabriel Sales Date: Wed, 15 Jan 2025 21:53:00 -0300 Subject: [PATCH 3/4] update doc --- readme.md | 7 +++++++ readme.pt-br.md | 11 +++++++++++ 2 files changed, 18 insertions(+) diff --git a/readme.md b/readme.md index 0c10581..52c8991 100644 --- a/readme.md +++ b/readme.md @@ -441,8 +441,15 @@ public class CustomParamenterSync : SSyncParameter public Guid? UserId { get; set; } public string? phoneId { get; set; } } +``` + +9. (optional) If you do not want to manually create pull and push endpoints, you can call the MapApiEndpointsSync function. + It is mandatory to provide a custom type that inherits from SSyncParameter, as this will automatically inject endpoints to perform the operations. +```cs +app.MapApiEndpointsSync(); ``` +
diff --git a/readme.pt-br.md b/readme.pt-br.md index 66998a9..fec5434 100644 --- a/readme.pt-br.md +++ b/readme.pt-br.md @@ -374,6 +374,7 @@ builder.Services.AddSSyncSchemaCollection( + 7. Agora você pode utilizar as interface ISchemaCollection para realizar pull ou push no seu controller ou endpoint ```cs @@ -433,6 +434,16 @@ public class CustomParamenterSync : SSyncParameter } ``` + + +9. (opcional) Caso não queira criar endpoint de pull e push manualmente, você pode chamada função MapApiEndpointsSync, é obrigatório passar um tipo customizado que herda de SSyncParameter, +assim que irá injectar automaticamente endpoints para realizar as operações + +```cs +app.MapApiEndpointsSync(); +``` + +
From 6c7315716fbf4f14ca44aa32fc40a43bcd67e00a Mon Sep 17 00:00:00 2001 From: Gabriel Sales Date: Wed, 15 Jan 2025 22:00:04 -0300 Subject: [PATCH 4/4] To fix routes apis integration tests --- src/SSync.Server.LiteDB.PlayGround/Program.cs | 6 +++--- .../MockServerApp/Sync/Handlers/PullRequest_Test.cs | 4 ++-- .../MockServerApp/Sync/Handlers/PushRequest_Test.cs | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/SSync.Server.LiteDB.PlayGround/Program.cs b/src/SSync.Server.LiteDB.PlayGround/Program.cs index b600f8d..affaa4b 100644 --- a/src/SSync.Server.LiteDB.PlayGround/Program.cs +++ b/src/SSync.Server.LiteDB.PlayGround/Program.cs @@ -40,7 +40,7 @@ //custom endpoints -// app.MapGet("/pull", async ([AsParameters] SSyncParameter parameter, [FromServices] ISchemaCollection schemaCollection) => +// app.MapGet("/api/v1/sync/pull", async ([AsParameters] SSyncParameter parameter, [FromServices] ISchemaCollection schemaCollection) => // { // var pullChangesRemoter = await schemaCollection.PullChangesAsync(parameter, new SSyncOptions() // { @@ -50,7 +50,7 @@ // return Results.Ok(pullChangesRemoter); // }); // -// app.MapPost("/push", async (HttpContext httpContext, JsonArray changes, [FromServices] ISchemaCollection schemaCollection) => +// app.MapPost("/api/v1/sync/push", async (HttpContext httpContext, JsonArray changes, [FromServices] ISchemaCollection schemaCollection) => // { // var query = httpContext.Request.Query; // @@ -69,7 +69,7 @@ // return Results.Ok(isOk); // }); -// app.MapGet("/pull-stream", ([AsParameters] SSyncParameter parameter, [FromServices] ISchemaCollection schemaCollection) => +// app.MapGet("/api/v1/sync/pull-stream", ([AsParameters] SSyncParameter parameter, [FromServices] ISchemaCollection schemaCollection) => // { // var pullChangesRemoter = schemaCollection.PullStreamChanges(parameter, new SSyncOptions() // { diff --git a/test/SSync.Server.LitebDB.Integration.Tests/MockServerApp/Sync/Handlers/PullRequest_Test.cs b/test/SSync.Server.LitebDB.Integration.Tests/MockServerApp/Sync/Handlers/PullRequest_Test.cs index 1b2b0f5..70d0553 100644 --- a/test/SSync.Server.LitebDB.Integration.Tests/MockServerApp/Sync/Handlers/PullRequest_Test.cs +++ b/test/SSync.Server.LitebDB.Integration.Tests/MockServerApp/Sync/Handlers/PullRequest_Test.cs @@ -28,7 +28,7 @@ public async Task SetTimestamp_To_PullAllChanges_Should_Return_Only_Created_Valu Assert.True(createResult.IsSuccessStatusCode); - var pullResult = await Client.GetAsync($"/pull?Time=0&Colletions=User&Timestamp={DateTime.MinValue:o}", CancellationToken.None); + var pullResult = await Client.GetAsync($"/api/v1/sync/pull?Time=0&Colletions=User&Timestamp={DateTime.MinValue:o}", CancellationToken.None); Assert.True(pullResult.IsSuccessStatusCode); var content = await pullResult.Content.ReadAsStringAsync(); @@ -54,7 +54,7 @@ public async Task Set_Current_Timestamp_To_PullChanges_Should_Return_Value_From_ Assert.True(createResult.IsSuccessStatusCode); - var pullResult = await Client.GetAsync($"/pull?Time=0&Colletions=User&Timestamp={currentTime:o}", CancellationToken.None); + var pullResult = await Client.GetAsync($"/api/v1/sync/pull?Time=0&Colletions=User&Timestamp={currentTime:o}", CancellationToken.None); Assert.True(pullResult.IsSuccessStatusCode); var content = await pullResult.Content.ReadAsStringAsync(); diff --git a/test/SSync.Server.LitebDB.Integration.Tests/MockServerApp/Sync/Handlers/PushRequest_Test.cs b/test/SSync.Server.LitebDB.Integration.Tests/MockServerApp/Sync/Handlers/PushRequest_Test.cs index 288716b..ff332ea 100644 --- a/test/SSync.Server.LitebDB.Integration.Tests/MockServerApp/Sync/Handlers/PushRequest_Test.cs +++ b/test/SSync.Server.LitebDB.Integration.Tests/MockServerApp/Sync/Handlers/PushRequest_Test.cs @@ -43,7 +43,7 @@ public async Task Create_New_Users_From_Json_Should_Return_Created_Users_Databas var content = new StringContent(jsonChangesFromClient, Encoding.UTF8, "application/json"); var pullResult = - await Client.PostAsync($"/push?Time=0&Colletions=User&Timestamp={DateTime.MinValue:o}", content); + await Client.PostAsync($"/api/v1/sync/push?Time=0&Colletions=User&Timestamp={DateTime.MinValue:o}", content); Assert.True(pullResult.IsSuccessStatusCode); var user = DbContext.User.FirstOrDefault(u => u.Id == Guid.Parse("1851d7ed-ea2b-4b17-8e77-ab6fb2cb8f81")); @@ -107,7 +107,7 @@ public async Task Update_Users_From_Json_Should_Return_Updated_Users_Database() var content = new StringContent(jsonChangesFromClient, Encoding.UTF8, "application/json"); var pullResult = - await Client.PostAsync($"/push?Time=0&Colletions=User&Timestamp={DateTime.MinValue:o}", content); + await Client.PostAsync($"/api/v1/sync/push?Time=0&Colletions=User&Timestamp={DateTime.MinValue:o}", content); Assert.True(pullResult.IsSuccessStatusCode); DbContext.ChangeTracker.Clear(); @@ -163,7 +163,7 @@ public async Task Delete_Users_From_Json_Should_Return_Delete_Users_Database() var content = new StringContent(jsonChangesFromClient, Encoding.UTF8, "application/json"); var pullResult = - await Client.PostAsync($"/push?Time=0&Colletions=User&Timestamp={DateTime.MinValue:o}", content); + await Client.PostAsync($"/api/v1/sync/push?Time=0&Colletions=User&Timestamp={DateTime.MinValue:o}", content); Assert.True(pullResult.IsSuccessStatusCode); DbContext.ChangeTracker.Clear();