Skip to content

Instantly share code, notes, and snippets.

@ianrussellsoftwarepark
Created March 12, 2021 14:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ianrussellsoftwarepark/f1c0815efe309ee6dd4bebf397d75f8d to your computer and use it in GitHub Desktop.
Save ianrussellsoftwarepark/f1c0815efe309ee6dd4bebf397d75f8d to your computer and use it in GitHub Desktop.
Code for INTRODUCTION TO WEB PROGRAMMING IN F# WITH GIRAFFE - PART 2
open System
open System.IO
open Microsoft.AspNetCore.Builder
open Microsoft.AspNetCore.Hosting
open Microsoft.Extensions.Hosting
open Microsoft.Extensions.DependencyInjection
open Microsoft.AspNetCore.Http
open Giraffe
open Giraffe.ViewEngine
open FSharp.Control.Tasks
open Todos
open System.Collections.Generic
type PingModel = {
Response: string
}
let indexView =
html [] [
head [] [
title [] [ str "Giraffe Sample" ]
]
body [] [
h1 [] [ str "Welcome to F#" ]
p [ _class "some-css-class"; _id "someId" ] [
str "Hello World"
]
]
]
module Handlers =
let sayHelloNameHandler (name:string) =
fun (next : HttpFunc) (ctx : HttpContext) ->
task {
let msg = sprintf "Hello, %s" name
return! json { Response = msg } next ctx
}
let viewTasksHandler =
fun (next : HttpFunc) (ctx : HttpContext) ->
task {
let store = ctx.GetService<TodoStore>()
let todos = store.GetAll()
return! json todos next ctx
}
let viewTaskHandler (id:Guid) =
fun (next : HttpFunc) (ctx : HttpContext) ->
task {
let store = ctx.GetService<TodoStore>()
let todo = store.Get(id)
return! json todo next ctx
}
let createTaskHandler =
fun (next : HttpFunc) (ctx : HttpContext) ->
task {
let! newTodo = ctx.BindJsonAsync<NewTodo>()
let store = ctx.GetService<TodoStore>()
let created = store.Create({ Id = Guid.NewGuid(); Description = newTodo.Description; Created = DateTime.UtcNow; IsCompleted = false })
return! json created next ctx
}
let updateTaskHandler =
fun (next : HttpFunc) (ctx : HttpContext) ->
task {
let! todo = ctx.BindJsonAsync<Todo>()
let store = ctx.GetService<TodoStore>()
let created = store.Update(todo)
return! json created next ctx
}
let deleteTaskHandler (id:Guid) =
fun (next : HttpFunc) (ctx : HttpContext) ->
task {
let store = ctx.GetService<TodoStore>()
let existing = store.Get(id)
let deleted = store.Delete(KeyValuePair<TodoId, Todo>(id, existing))
return! json deleted next ctx
}
let apiTodoRoutes : HttpHandler =
subRoute "/todos"
(choose [
GET >=> choose [
routef "/%O" Handlers.viewTaskHandler
route "" >=> Handlers.viewTasksHandler
]
POST >=> route "" >=> Handlers.updateTaskHandler
PUT >=> route "" >=> Handlers.createTaskHandler
DELETE >=> routef "/%O" Handlers.deleteTaskHandler
])
let webApp =
choose [
GET >=> route "/" >=> htmlView todoView
subRoute "/api"
(choose [
apiTodoRoutes
GET >=> route "" >=> json { Response = "ToDo List API" }
GET >=> routef "/%s" Handlers.sayHelloNameHandler
])
setStatusCode 404 >=> text "Not Found"
]
let configureApp (app : IApplicationBuilder) =
app.UseGiraffe webApp
let configureServices (services : IServiceCollection) =
services.AddGiraffe()
.AddSingleton<TodoStore>(TodoStore()) |> ignore
[<EntryPoint>]
let main _ =
Host.CreateDefaultBuilder()
.ConfigureWebHostDefaults(fun webHost ->
webHost
.Configure(configureApp)
.ConfigureServices(configureServices)
|> ignore)
.Build()
.Run()
0
module Todos
open System
open System.Collections.Concurrent
type TodoId = Guid
type NewTodo = {
Description: string
}
type Todo = {
Id: TodoId
Description: string
Created: DateTime
IsCompleted: bool
}
type TodoStore() =
let data = ConcurrentDictionary<TodoId, Todo>()
member _.Create todo = data.TryAdd(todo.Id, todo)
member _.Update todo = data.TryUpdate(todo.Id, todo, data.[todo.Id])
member _.Delete id = data.TryRemove id
member _.Get id = data.[id]
member _.GetAll () = data.ToArray()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment