Skip to content

Commit

Permalink
webapp builder
Browse files Browse the repository at this point in the history
  • Loading branch information
pimbrouwers committed Apr 29, 2020
1 parent f9c1285 commit 0b5943e
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 112 deletions.
61 changes: 5 additions & 56 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,71 +44,20 @@ Remove the `Startup.fs` file and save the following in `Program.fs`:
```f#
module HelloWorldApp
open Microsoft.AspNetCore.Builder
open Microsoft.AspNetCore.Hosting
open Microsoft.Extensions.DependencyInjection
open Microsoft.Extensions.Logging
open Falco
// ------------
// Handlers & Routes
// ------------
let helloHandler : HttpHandler =
textOut "hello world"
let routes = [
get "/" helloHandler
]
// ------------
// Web App
// ------------
let configureApp (app : IApplicationBuilder) =
app.UseDeveloperExceptionPage()
.UseRouting()
.UseHttpEndPoints(routes)
.UseNotFoundHandler(setStatusCode 404 >=> textOut "Not found")
|> ignore
// ------------
// Logging
// ------------
let configureLogging (loggerBuilder : ILoggingBuilder) =
loggerBuilder
.AddFilter(fun l -> l.Equals LogLevel.Information)
.AddConsole()
.AddDebug() |> ignore
// ------------
// Services
// ------------
let configureServices (services : IServiceCollection) =
services
.AddRouting()
|> ignore
[<EntryPoint>]
let main _ =
try
WebHostBuilder()
.UseKestrel()
.ConfigureLogging(configureLogging)
.ConfigureServices(configureServices)
.Configure(configureApp)
.Build()
.Run()
0
with
| _ -> -1
webApp {
get "/" (textOut "hello")
notFound (setStatusCode 404 >=> textOut "Not found")
}
```

Run the application:
```
dotnet run HelloWorldApp
```

So in about 50 lines of code including comments and generous spacing/verticality, you've got an industrial-strength "hello world" web app. Which we achieved using primarily base ASP.NET libraries. Pretty sweet!
So in about 5 lines of code, you've got an industrial-strength "hello world" web app. Which we achieved using only base ASP.NET libraries. Pretty sweet!

## Sample Applications

Expand Down
59 changes: 4 additions & 55 deletions samples/HelloWorld/Program.fs
Original file line number Diff line number Diff line change
@@ -1,59 +1,8 @@
module HelloWorldApp

open Microsoft.AspNetCore.Builder
open Microsoft.AspNetCore.Hosting
open Microsoft.Extensions.DependencyInjection
open Microsoft.Extensions.Logging
open Falco

// ------------
// Handlers & Routes
// ------------
let helloHandler : HttpHandler =
textOut "hello world"

let routes = [
get "/" helloHandler
]

// ------------
// Web App
// ------------
let configureApp (app : IApplicationBuilder) =
app.UseDeveloperExceptionPage()
.UseRouting()
.UseHttpEndPoints(routes)
.UseNotFoundHandler(setStatusCode 404 >=> textOut "Not found")
|> ignore

// ------------
// Logging
// ------------
let configureLogging (loggerBuilder : ILoggingBuilder) =
loggerBuilder
.AddFilter(fun l -> l.Equals LogLevel.Information)
.AddConsole()
.AddDebug() |> ignore

// ------------
// Services
// ------------
let configureServices (services : IServiceCollection) =
services
.AddRouting()
|> ignore


[<EntryPoint>]
let main _ =
try
WebHostBuilder()
.UseKestrel()
.ConfigureLogging(configureLogging)
.ConfigureServices(configureServices)
.Configure(configureApp)
.Build()
.Run()
0
with
| _ -> -1
webApp {
get "/" (textOut "hello")
notFound (setStatusCode 404 >=> textOut "Not found")
}
3 changes: 2 additions & 1 deletion src/Falco/Falco.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

<!-- NuGet config -->
<PackageId>Falco</PackageId>
<PackageVersion>1.0.7-alpha</PackageVersion>
<PackageVersion>1.0.8-alpha</PackageVersion>
<PackageTags>fsharp;functional;falco;asp.net core;asp.net;.net core;routing;view engine;web</PackageTags>
<PackageProjectUrl>https://github.com/pimbrouwers/Falco</PackageProjectUrl>
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
Expand All @@ -45,6 +45,7 @@
<ItemGroup>
<Compile Include="Core.fs" />
<Compile Include="Routing.fs" />
<Compile Include="WebAppBuilder.fs" />
<Compile Include="ModelBinding.fs" />
<Compile Include="Validation.fs" />
<Compile Include="Multipart.fs" />
Expand Down
112 changes: 112 additions & 0 deletions src/Falco/WebAppBuilder.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
[<AutoOpen>]
module Falco.Builder

open Microsoft.AspNetCore.Builder
open Microsoft.AspNetCore.Hosting
open Microsoft.Extensions.DependencyInjection
open Microsoft.Extensions.Logging

type WebApp =
{
Configurations : IApplicationBuilder -> IApplicationBuilder
HostBuilder : IWebHostBuilder
Logging : ILoggingBuilder -> ILoggingBuilder
NotFound : HttpHandler option
Routes : HttpEndpoint list
Services : IServiceCollection -> IServiceCollection
}

static member Empty () =
{
Configurations = id
HostBuilder = WebHostBuilder().UseKestrel()
Logging = id
NotFound = None
Routes = []
Services = id
}

type WebAppBuilder() =
member __.Yield(_) = WebApp.Empty ()

member __.Run(webApp : WebApp) =
let host = webApp.HostBuilder
host.ConfigureLogging(fun logging ->
logging
|> webApp.Logging
|> ignore)
.ConfigureServices(fun services ->
services.AddRouting()
|> webApp.Services
|> ignore)
.Configure(fun app ->
app.UseRouting().UseHttpEndPoints(webApp.Routes)
|> webApp.Configurations
|> fun _ ->
match webApp.NotFound with
| Some nf -> app.UseNotFoundHandler(nf)
| None _ -> ())
|> ignore

host.Build().Run()

[<CustomOperation("configure")>]
member __.Configure (app : WebApp, appConfig : IApplicationBuilder -> IApplicationBuilder) =
{ app with Configurations = app.Configurations >> appConfig }


[<CustomOperation("logging")>]
member __.Logging (app : WebApp, logConfig : ILoggingBuilder -> ILoggingBuilder) =
{ app with Logging = app.Logging >> logConfig }

[<CustomOperation("services")>]
member __.Services (app : WebApp, servicesConfig : IServiceCollection -> IServiceCollection) =
{ app with Services = app.Services >> servicesConfig }

[<CustomOperation("route")>]
member __.Route (app : WebApp, verb : HttpVerb, pattern : string, handler : HttpHandler) =
{ app with Routes = route verb pattern handler :: app.Routes }

[<CustomOperation("any")>]
member __.Any (app : WebApp, pattern : string, handler : HttpHandler) =

{ app with Routes = any pattern handler :: app.Routes }

[<CustomOperation("get")>]
member __.Get (app : WebApp, pattern : string, handler : HttpHandler) =
{ app with Routes = get pattern handler :: app.Routes }

[<CustomOperation("head")>]
member __.Head (app : WebApp, pattern : string, handler : HttpHandler) =
{ app with Routes = head pattern handler :: app.Routes }

[<CustomOperation("post")>]
member __.Post (app : WebApp, pattern : string, handler : HttpHandler) =
{ app with Routes = post pattern handler :: app.Routes }

[<CustomOperation("put")>]
member __.Put (app : WebApp, pattern : string, handler : HttpHandler) =
{ app with Routes = put pattern handler :: app.Routes }

[<CustomOperation("patch")>]
member __.Patch (app : WebApp, pattern : string, handler : HttpHandler) =
{ app with Routes = patch pattern handler :: app.Routes }

[<CustomOperation("delete")>]
member __.Delete (app : WebApp, pattern : string, handler : HttpHandler) =
{ app with Routes = delete pattern handler :: app.Routes }

[<CustomOperation("options")>]
member __.Options (app : WebApp, pattern : string, handler : HttpHandler) =
{ app with Routes = options pattern handler :: app.Routes }

[<CustomOperation("trace")>]
member __.Trace (app : WebApp, pattern : string, handler : HttpHandler) =
{ app with Routes = trace pattern handler :: app.Routes }

[<CustomOperation("notFound")>]
member __.NotFound (app : WebApp, handler : HttpHandler) =
{ app with NotFound = Some handler }

let webApp = WebAppBuilder()

0 comments on commit 0b5943e

Please sign in to comment.