ReportService/Program.fs

93 lines
3.3 KiB
Forth

open Giraffe
open Microsoft.AspNetCore.Http
open Microsoft.AspNetCore.Builder
open Microsoft.Extensions.DependencyInjection
open Microsoft.Extensions.Hosting
open Thoth.Json
type QueryFilter =
| Equal of string * string
| GreaterThan of string * float
| LessThan of string * float
type QueryDSL = {
Select : string list
Filters : QueryFilter list
Sort : (string * string) list // Field and direction
}
let parseQuery (body: string) =
// Example JSON parsing (using FSharp.Data or similar)
// Example query JSON:
// { "select": ["name", "age"], "filters": [{"field": "age", "op": "gt", "value": 30}], "sort": [["name", "asc"]] }
try
let query = Decode.Auto.fromString<QueryDSL> body
// let parsed = FSharp.Data.JsonValue.Parse(body)
//let selectFields = parsed.["select"].AsArray() |> Array.map string |> List.ofArray
//let filters =
// parsed.["filters"].AsArray()
// |> Array.map (fun filter ->
// match filter.["op"].AsString() with
// | "eq" -> Equal(filter.["field"].AsString(), filter.["value"].AsString())
// | "gt" -> GreaterThan(filter.["field"].AsString(), filter.["value"].AsFloat())
// | "lt" -> LessThan(filter.["field"].AsString(), filter.["value"].AsFloat())
// | _ -> failwith "Unsupported filter")
// |> List.ofArray
//let sort =
// parsed.["sort"].AsArray()
// |> Array.map (fun s -> s.[0].AsString(), s.[1].AsString())
// |> List.ofArray
//{ Select = selectFields; Filters = filters; Sort = sort }
query
with
| ex -> failwithf "Failed to parse query: %s" ex.Message
let fetchData (queryDsl: QueryDSL) =
// Mock database query (replace with actual DB logic)
let mockData = [
{| name = "Alice"; age = 30 |}
{| name = "Bob"; age = 25 |}
{| name = "Charlie"; age = 35 |}
]
// Filter and transform the data based on the DSL
mockData
|> List.filter (fun row ->
queryDsl.Filters |> List.forall (function
| Equal(field, value) -> row.[field] = value
| GreaterThan(field, num) -> row.[field] |> float > num
| LessThan(field, num) -> row.[field] |> float < num))
|> List.map (fun row ->
queryDsl.Select |> List.map (fun field -> field, row.[field]) |> dict)
|> fun result -> result
let queryHandler (next: HttpFunc) (ctx: HttpContext) =
task {
let! body = ctx.ReadBodyAsStringAsync()
let queryDsl = parseQuery body
let data = fetchData queryDsl
return! json data next ctx
}
let webApp =
choose [
POST "/query" >=> queryHandler
RequestErrors.notFound "Not Found"
]
let configureApp (app: IApplicationBuilder) =
app.UseGiraffe webApp
let configureServices (services: IServiceCollection) =
services.AddGiraffe() |> ignore
[<EntryPoint>]
let main args =
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(fun webBuilder ->
webBuilder
//.Configure(configureApp)
.ConfigureServices(configureServices)
|> ignore)
.Build()
.Run()
0