diff --git a/frameworks/FSharp/falco/src/App/App.fsproj b/frameworks/FSharp/falco/src/App/App.fsproj index 2756586d20c..c85bfd45665 100644 --- a/frameworks/FSharp/falco/src/App/App.fsproj +++ b/frameworks/FSharp/falco/src/App/App.fsproj @@ -15,7 +15,7 @@ - + diff --git a/frameworks/FSharp/falco/src/App/Fortune.fs b/frameworks/FSharp/falco/src/App/Fortune.fs index e2376ce00b1..12a32ed4a10 100644 --- a/frameworks/FSharp/falco/src/App/Fortune.fs +++ b/frameworks/FSharp/falco/src/App/Fortune.fs @@ -1,57 +1,51 @@ module App.Fortune - -module Model = - open System.Threading.Tasks - open FSharp.Control.Tasks - - type FortuneModel = - { - id : int - message : string - } - module FortuneModel = - open System.Data - open Donald - - let extra = +open System.Data +open Donald +open Falco +open FSharp.Control.Tasks + +type FortuneModel = + { + id : int + message : string + } + + static member fromDataReader (rd : IDataReader) = + { + id = rd.GetInt32("id") + message = rd.GetString("message") + } + +module Service = + open System.Threading.Tasks + + module ListQuery = + type LoadFortunes = unit -> Task + + let extraFortune = { id = 0 message = "Additional fortune added at request time." } - let fromDataReader (rd : IDataReader) = - { - id = rd.GetInt32("id") - message = rd.GetString("message") - } - - module Index = - type Query = - unit -> Task - - type LoadFortunes = - unit -> Task - - let query - (loadFortunes : LoadFortunes) : Query = + let handle + (loadFortunes : LoadFortunes) = fun () -> task { let! fortunes = loadFortunes () - let fortunesWithExtra = FortuneModel.extra :: fortunes - let fortunesSorted = - fortunesWithExtra + + return + extraFortune + :: fortunes |> List.sortBy (fun f -> f.message) - - return fortunesSorted } -module Db = - open System.Data - open Donald - open Model - let selectAsync (connection : IDbConnection) = +module Db = + open System.Threading.Tasks + + let selectAsync (connection : IDbConnection) : Task = queryAsync "SELECT id, message FROM fortune" [] @@ -59,42 +53,34 @@ module Db = connection module View = - open Falco.ViewEngine - open Model - + open Falco.Markup + let index (fortunes : FortuneModel list) = UI.layout "Fortunes" [ - table [] [ - yield tr [] [ - th [] [ raw "id" ] - th [] [ raw "message" ] + Elem.table [] [ + yield Elem.tr [] [ + Elem.th [] [ Text.raw "id" ] + Elem.th [] [ Text.raw "message" ] ] for fortune in fortunes -> - tr [] [ - td [] [ raw (string fortune.id) ] - td [] [ enc fortune.message] + Elem.tr [] [ + Elem.td [] [ Text.raw (string fortune.id) ] + Elem.td [] [ Text.enc fortune.message] ] ] ] -module Controller = - open Donald - open Falco - open FSharp.Control.Tasks - open Model - - let handleIndex : HttpHandler = - fun next ctx -> - task { - let connFactory = ctx.GetService() - use conn = createConn connFactory - let selectFortunes = fun () -> Db.selectAsync conn - let! fortunes = () |> Index.query selectFortunes - - let handlerResult = - fortunes - |> View.index - |> htmlOut - - return! handlerResult next ctx - } \ No newline at end of file +let handleIndex : HttpHandler = + fun ctx -> + task { + let connFactory = ctx.GetService() + use conn = createConn connFactory + let selectFortunes = fun () -> Db.selectAsync conn + let! fortunes = () |> Service.ListQuery.handle selectFortunes + + return! + ctx + |> (fortunes + |> View.index + |> Response.ofHtml) + } \ No newline at end of file diff --git a/frameworks/FSharp/falco/src/App/Program.fs b/frameworks/FSharp/falco/src/App/Program.fs index 0509e489aaa..5400ad6a25a 100644 --- a/frameworks/FSharp/falco/src/App/Program.fs +++ b/frameworks/FSharp/falco/src/App/Program.fs @@ -1,6 +1,7 @@ module App.Program open System.Data +open Falco open Npgsql [] @@ -11,5 +12,12 @@ let connectionFactory = [] let main args = - Server.startServer args connectionFactory + Host.startWebHost + args + (Server.buildServer connectionFactory) + [ + get "/plaintext" Value.handlePlainText + get "/json" Value.handleJson + get "/fortunes" Fortune.handleIndex + ] 0 \ No newline at end of file diff --git a/frameworks/FSharp/falco/src/App/Server.fs b/frameworks/FSharp/falco/src/App/Server.fs index 55af0cb210e..dee18c499a8 100644 --- a/frameworks/FSharp/falco/src/App/Server.fs +++ b/frameworks/FSharp/falco/src/App/Server.fs @@ -1,22 +1,14 @@ module App.Server +open System.Threading.Tasks open Donald open Falco open Microsoft.AspNetCore.Builder open Microsoft.AspNetCore.Hosting -open Microsoft.AspNetCore.Server.Kestrel.Core open Microsoft.Extensions.DependencyInjection open Microsoft.Extensions.Logging -open Microsoft.Extensions.Hosting -let routes = - [ - get "/plaintext" Value.Controller.handlePlainText - get "/json" Value.Controller.handleJson - get "/fortunes" Fortune.Controller.handleIndex - ] - -module Config = +let buildServer (connectionFactory : DbConnectionFactory) : Host.ConfigureWebHost = let configureLogging (log : ILoggingBuilder) = log.ClearProviders() |> ignore @@ -30,26 +22,22 @@ module Config = let configure (routes : HttpEndpoint list) - (app : IApplicationBuilder) = + (app : IApplicationBuilder) = + let handleNotFound : HttpHandler = + fun ctx -> + Response.withStatusCode 404 ctx |> ignore + Task.CompletedTask + app.UseRouting() - .UseHttpEndPoints(routes) - .UseNotFoundHandler(setStatusCode 404) + .UseHttpEndPoints(routes) + .UseNotFoundHandler(handleNotFound) |> ignore -let builderServer - (connectionFactory : DbConnectionFactory) - (webHost : IWebHostBuilder) = - webHost - .UseKestrel() - .ConfigureLogging(Config.configureLogging) - .ConfigureServices(Config.configureServices connectionFactory) - .Configure(Config.configure routes) - |> ignore - -let startServer - (args : string[]) - (connectionFactory : DbConnectionFactory) = - Host.CreateDefaultBuilder(args) - .ConfigureWebHost(fun webHost -> builderServer connectionFactory webHost) - .Build() - .Run() + fun (routes : HttpEndpoint list) + (webHost : IWebHostBuilder) -> + webHost + .UseKestrel() + .ConfigureLogging(configureLogging) + .ConfigureServices(configureServices connectionFactory) + .Configure(configure routes) + |> ignore diff --git a/frameworks/FSharp/falco/src/App/UI.fs b/frameworks/FSharp/falco/src/App/UI.fs index 322edf171d3..aa3a4bc85da 100644 --- a/frameworks/FSharp/falco/src/App/UI.fs +++ b/frameworks/FSharp/falco/src/App/UI.fs @@ -1,11 +1,11 @@ module App.UI -open Falco.ViewEngine +open Falco.Markup let layout pageTitle content = - html [] [ - head [] [ - title [] [ raw pageTitle ] + Elem.html [] [ + Elem.head [] [ + Elem.title [] [ Text.raw pageTitle ] ] - body [] content + Elem.body [] content ] \ No newline at end of file diff --git a/frameworks/FSharp/falco/src/App/Value.fs b/frameworks/FSharp/falco/src/App/Value.fs index 7bff6cf4b27..1dbbfdb6fd3 100644 --- a/frameworks/FSharp/falco/src/App/Value.fs +++ b/frameworks/FSharp/falco/src/App/Value.fs @@ -3,14 +3,13 @@ open Falco type JsonOutputModel = { message : string } - -module Controller = - let defaultMsg = "Hello, World!" - let handleJson : HttpHandler = - fun next ctx -> - let json = { message = defaultMsg } - (jsonOut json) next ctx +let defaultMsg = "Hello, World!" + +let handleJson : HttpHandler = + fun ctx -> + let output = { message = defaultMsg } + Response.ofJson output ctx - let handlePlainText : HttpHandler = - textOut defaultMsg \ No newline at end of file +let handlePlainText : HttpHandler = + Response.ofPlainText defaultMsg \ No newline at end of file