1
Fork 0

fsharp(todolist-api): feat: editing todos

Signed-off-by: prescientmoon <git@moonythm.dev>
This commit is contained in:
Matei Adriel 2020-01-02 15:37:47 +02:00 committed by prescientmoon
parent 4951b6c2ca
commit 38e6717f76
Signed by: prescientmoon
SSH key fingerprint: SHA256:UUF9JT2s8Xfyv76b8ZuVL7XrmimH4o49p4b+iexbVH4
2 changed files with 63 additions and 14 deletions

View file

@ -1,34 +1,75 @@
// Learn more about F# at http://fsharp.org // Learn more about F# at http://fsharp.org
open System
// suave overwrites some stuff from f#+, so the order matters
open FSharpPlus.Operators
open Suave open Suave
open Suave.Successful
open Suave.Operators open Suave.Operators
open Suave.Filters open Suave.Successful
open Suave.RequestErrors open Suave.RequestErrors
open Suave.Json open Suave.Json
open Suave.Filters
module Utils = module Utils =
open System.Text open System.Text
open Db.Types
let jsonToString json = json |> toJson |> Encoding.UTF8.GetString let jsonToString json = json |> toJson |> Encoding.UTF8.GetString
let todoToRecord (todo: DbTodo) =
{ id = todo.Id
description = todo.Description
name = todo.Name }
module App = module App =
open Utils open Utils
open Db
let todoById (id) = let todoById (id) =
let todo = Db.Context.getContext() |> Db.Queries.getTodosById id let todo =
Context.getContext()
|> Queries.getTodosById id
|>> todoToRecord
match todo with match todo with
| Some inner -> inner |> jsonToString |> OK | Some inner -> inner |> jsonToString |> OK
| None -> id |> sprintf "Cannot find todo with id %i" |> NOT_FOUND | None -> id |> sprintf "Cannot find todo with id %i" |> NOT_FOUND
let updateTodo (id) =
let dbContext = Context.getContext()
let todo = dbContext |> Queries.getTodosById id
match todo with
| Some todo ->
fun ctx -> async {
let body: Types.TodoDetails = ctx.request.rawForm |> fromJson
do! Queries.updateTodosById todo body dbContext
let newBody: Types.Todo = {
name = body.name
description = body.description
id = id
}
let withNewBody = newBody |> toJson |> ok
return! withNewBody ctx
}
| None -> id |> sprintf "Cannot find todo with id %i" |> NOT_FOUND
let mainWebPart: WebPart = choose [ let mainWebPart: WebPart = choose [
GET >=> choose [ GET >=> pathScan "/todos/%i" todoById
pathScan "/todos/%i" todoById PUT >=> pathScan "/todos/%i" updateTodo]
]]
[<EntryPoint>] [<EntryPoint>]
let main _ = let main _ =
startWebServer defaultConfig App.mainWebPart
let handleErrors (e: Exception) (message: string): WebPart =
sprintf "%s: %s" message e.Message |> BAD_REQUEST
let config = { defaultConfig with errorHandler = handleErrors }
startWebServer config App.mainWebPart
0 // return an integer exit code 0 // return an integer exit code

View file

@ -30,23 +30,31 @@ module Types =
name: string } name: string }
let todoToRecord (todo: DbTodo) = [<DataContract>]
{ id = todo.Id type TodoDetails =
description = todo.Description { [<field:DataMember(Name = "description")>]
name = todo.Name } description: string
[<field:DataMember(Name = "name")>]
name: string }
module Queries = module Queries =
open FSharpPlus.Operators
open Context open Context
open Types open Types
let getTodosById id (ctx: DbContext): Todo option = let getTodosById id (ctx: DbContext): DbTodo option =
query { query {
for todo in ctx.Public.Todos do for todo in ctx.Public.Todos do
where (todo.Id = id) where (todo.Id = id)
select todo select todo
} }
|> Seq.tryHead |> Seq.tryHead
|>> todoToRecord
let updateTodosById (todo: DbTodo) (details: TodoDetails) (ctx: DbContext) =
todo.Name <- details.name
todo.Description <- details.description
ctx.SubmitUpdatesAsync()