Skip to content

Commit

Permalink
Merge pull request #6 from salesHgabriel/feat/add_endpoints
Browse files Browse the repository at this point in the history
Map endpoints builder
  • Loading branch information
salesHgabriel authored Jan 16, 2025
2 parents 0d1366f + 6c73157 commit 1fa5e07
Show file tree
Hide file tree
Showing 8 changed files with 154 additions and 49 deletions.
9 changes: 7 additions & 2 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -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")

<details open>
<summary><h2>🔙 Backend</h2></summary>
Expand Down Expand Up @@ -443,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<CustomParamenterSync>();
```

</details>

<details open>
Expand Down
14 changes: 11 additions & 3 deletions readme.pt-br.md
Original file line number Diff line number Diff line change
Expand Up @@ -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")

<details open>
<summary><h2>🔙 Backend</h2></summary>

Expand Down Expand Up @@ -377,6 +374,7 @@ builder.Services.AddSSyncSchemaCollection<PocDbContext>(




7. Agora você pode utilizar as interface ISchemaCollection para realizar pull ou push no seu controller ou endpoint

```cs
Expand Down Expand Up @@ -436,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<CustomParamenterSync>();
```


</details>

<details open>
Expand Down
82 changes: 44 additions & 38 deletions src/SSync.Server.LiteDB.PlayGround/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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<PlayParamenter>();


//custom endpoints

// app.MapGet("/api/v1/sync/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("/api/v1/sync/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("/api/v1/sync/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) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
76 changes: 76 additions & 0 deletions src/SSync.Server.LitebDB/Extensions/SSyncApiEndPointExtension.cs
Original file line number Diff line number Diff line change
@@ -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
{
/// <summary>
/// Add endpoints pull, push and pull stream (IasyncEnumerable)
/// </summary>
/// <param name="endpoints"></param>
/// <param name="options"></param>
/// <param name="version"></param>
/// <param name="route"></param>
/// <param name="enablePullChangesStream"></param>
/// <returns></returns>
public static IEndpointConventionBuilder MapApiEndpointsSync<TParamenterSync>(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;
}
}
10 changes: 10 additions & 0 deletions src/SSync.Server.LitebDB/SSync.Server.LitebDB.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,14 @@
<PackageReference Include="Scrutor" Version="5.0.1" />
</ItemGroup>

<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>

<ItemGroup>
<Reference Include="Microsoft.AspNetCore">
<HintPath>..\..\..\..\..\..\..\Program Files\dotnet\shared\Microsoft.AspNetCore.App\8.0.11\Microsoft.AspNetCore.dll</HintPath>
</Reference>
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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"));
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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();
Expand Down

0 comments on commit 1fa5e07

Please sign in to comment.