Skip to content

Commit ecbd247

Browse files
committed
feat(api): ✨ add flat query option for device endpoints
Added support for a "flat" query parameter to device API endpoints, allowing device data to be returned as flattened key-value pairs. Endpoints now provide more informative NotFound responses, listing available device serial numbers.
1 parent 214b4fe commit ecbd247

2 files changed

Lines changed: 63 additions & 1 deletion

File tree

src/EcoFlow.Mqtt.Api/EntryPoint.cs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@
33
using EcoFlow.Mqtt.Api.Extensions;
44
using EcoFlow.Mqtt.Api.Services;
55
using Microsoft.AspNetCore.Builder;
6+
using Microsoft.AspNetCore.Http;
67
using Microsoft.Extensions.DependencyInjection;
78
using Microsoft.Extensions.Logging;
89
using Microsoft.Extensions.Options;
910
using System.Text;
11+
using System.Text.Json;
1012

1113
Console.OutputEncoding = Encoding.UTF8;
1214

@@ -48,5 +50,18 @@
4850
foreach (var device in devices)
4951
await mqttApi.SubscribeDeviceAsync(session, mqttConfiguration, device);
5052

51-
app.MapGet("/", () => mqttApi.Devices);
53+
app.MapGet("/", (HttpRequest httpRequest) =>
54+
httpRequest.Query.ContainsKey("flat")
55+
? Results.Text(string.Join('\n', JsonSerializer.SerializeToNode(mqttApi.Devices).Flatten()))
56+
: Results.Json(mqttApi.Devices));
57+
58+
app.MapGet("/{serialNumber}", (HttpRequest httpRequest, string serialNumber) =>
59+
mqttApi.Devices.TryGetValue(serialNumber, out var device)
60+
? httpRequest.Query.ContainsKey("flat")
61+
? Results.Text(string.Join('\n', JsonSerializer.SerializeToNode(mqttApi.Devices[serialNumber]).Flatten()))
62+
: Results.Json(mqttApi.Devices[serialNumber])
63+
: httpRequest.Query.ContainsKey("flat")
64+
? Results.NotFound(string.Join(',', mqttApi.Devices.Keys))
65+
: Results.NotFound($"Device not found. Existing serial numbers: {string.Join(',', mqttApi.Devices.Keys)}"));
66+
5267
app.Run();

src/EcoFlow.Mqtt.Api/Extensions/JsonExtensions.cs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,5 +39,52 @@ public void Sort()
3939
}
4040
}
4141
}
42+
43+
public IEnumerable<string> Flatten(string keySeparator = ".", string arrayFormat = "[{0}]")
44+
{
45+
foreach (var flattenedLine in Walk(node, string.Empty))
46+
yield return flattenedLine;
47+
48+
IEnumerable<string> Walk(JsonNode? currentNode, string currentPath)
49+
{
50+
switch (currentNode)
51+
{
52+
case JsonObject jsonObject:
53+
foreach (var jsonProperty in jsonObject)
54+
{
55+
var nextPath = string.IsNullOrEmpty(currentPath)
56+
? jsonProperty.Key
57+
: currentPath + keySeparator + jsonProperty.Key;
58+
59+
foreach (var flattenedLine in Walk(jsonProperty.Value, nextPath))
60+
yield return flattenedLine;
61+
}
62+
break;
63+
64+
case JsonArray jsonArray:
65+
var arrayIndex = 0;
66+
67+
foreach (var jsonArrayItem in jsonArray)
68+
{
69+
var nextPath = currentPath + string.Format(arrayFormat, arrayIndex);
70+
71+
foreach (var flattenedLine in Walk(jsonArrayItem, nextPath))
72+
yield return flattenedLine;
73+
74+
arrayIndex++;
75+
}
76+
break;
77+
78+
case JsonValue jsonValue:
79+
var valueAsString = jsonValue.ToString() ?? string.Empty;
80+
yield return $"{currentPath}={valueAsString}";
81+
break;
82+
83+
case null:
84+
yield return $"{currentPath}=";
85+
break;
86+
}
87+
}
88+
}
4289
}
4390
}

0 commit comments

Comments
 (0)