fsharp(todolist-api): feat: got patching to work
Signed-off-by: prescientmoon <git@moonythm.dev>
This commit is contained in:
parent
3023f6c410
commit
f3a4b3c957
|
@ -1,8 +1,6 @@
|
||||||
// Learn more about F# at http://fsharp.org
|
// Learn more about F# at http://fsharp.org
|
||||||
open System
|
open System
|
||||||
|
|
||||||
// suave overwrites some stuff from f#+, so the order matters
|
|
||||||
open FSharpPlus.Operators
|
|
||||||
open Suave
|
open Suave
|
||||||
open Suave.Operators
|
open Suave.Operators
|
||||||
open Suave.Successful
|
open Suave.Successful
|
||||||
|
@ -19,7 +17,7 @@ module Utils =
|
||||||
description = todo.Description
|
description = todo.Description
|
||||||
name = todo.Name }
|
name = todo.Name }
|
||||||
|
|
||||||
let parseJson (input: byte array) = input |> Encoding.UTF8.GetString |> Json.parse |> Json.deserialize
|
let inline parseJson (input: byte array) = input |> Encoding.UTF8.GetString |> Json.parse |> Json.deserialize
|
||||||
|
|
||||||
module App =
|
module App =
|
||||||
open Utils
|
open Utils
|
||||||
|
@ -39,25 +37,46 @@ module App =
|
||||||
let updateTodo =
|
let updateTodo =
|
||||||
withTodoById (fun (todo, dbContext, id) ->
|
withTodoById (fun (todo, dbContext, id) ->
|
||||||
fun ctx -> async {
|
fun ctx -> async {
|
||||||
let body: Types.TodoDetails = parseJson ctx.request.rawForm
|
let body: Types.TodoDetails = parseJson ctx.request.rawForm
|
||||||
|
|
||||||
do! Queries.updateTodosById todo body dbContext
|
do! Queries.updateTodoById todo body dbContext
|
||||||
|
|
||||||
let newBody: Types.Todo = {
|
let newBody: Types.Todo = {
|
||||||
name = body.name
|
name = body.name
|
||||||
description = body.description
|
description = body.description
|
||||||
id = id
|
id = id
|
||||||
}
|
|
||||||
|
|
||||||
let writeBody = newBody |> Json.serialize |> Json.format |> OK
|
|
||||||
|
|
||||||
return! writeBody ctx
|
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
let writeBody = newBody |> Json.serialize |> Json.format |> OK
|
||||||
|
|
||||||
|
return! writeBody ctx
|
||||||
|
})
|
||||||
|
|
||||||
|
let patchTodo = withTodoById (fun (todo, dbContext, id) ->
|
||||||
|
let originalTodo = todoToRecord todo
|
||||||
|
|
||||||
|
fun ctx -> async {
|
||||||
|
let body: Types.PartialTodoDetails = parseJson ctx.request.rawForm
|
||||||
|
|
||||||
|
do! Queries.patchTodoById todo body dbContext
|
||||||
|
|
||||||
|
let newBody: Types.Todo = {
|
||||||
|
name = Option.defaultValue originalTodo.name body.name
|
||||||
|
description = Option.defaultValue originalTodo.description body.description
|
||||||
|
id = id
|
||||||
|
}
|
||||||
|
|
||||||
|
let writeBody = newBody |> Json.serialize |> Json.format |> OK
|
||||||
|
|
||||||
|
return! writeBody ctx
|
||||||
|
})
|
||||||
|
|
||||||
let mainWebPart: WebPart = choose [
|
let mainWebPart: WebPart = choose [
|
||||||
GET >=> pathScan "/todos/%i" todoById
|
pathScan "/todos/%i" (fun (id) -> choose [
|
||||||
PUT >=> pathScan "/todos/%i" updateTodo]
|
GET >=> todoById id
|
||||||
|
PUT >=> updateTodo id
|
||||||
|
PATCH >=> patchTodo id
|
||||||
|
])]
|
||||||
|
|
||||||
[<EntryPoint>]
|
[<EntryPoint>]
|
||||||
let main _ =
|
let main _ =
|
||||||
|
|
|
@ -54,9 +54,20 @@ module Types =
|
||||||
description = description }
|
description = description }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type PartialTodoDetails =
|
||||||
|
{ description: string option
|
||||||
|
name: string option }
|
||||||
|
static member FromJson(_: PartialTodoDetails) =
|
||||||
|
json {
|
||||||
|
let! name = Json.tryRead "name"
|
||||||
|
let! description = Json.tryRead "description"
|
||||||
|
return { name = name
|
||||||
|
description = description }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
module Queries =
|
module Queries =
|
||||||
|
open FSharpPlus.Builders
|
||||||
open Context
|
open Context
|
||||||
open Types
|
open Types
|
||||||
|
|
||||||
|
@ -69,9 +80,17 @@ module Queries =
|
||||||
|> Seq.tryHead
|
|> Seq.tryHead
|
||||||
|
|
||||||
|
|
||||||
let updateTodosById (todo: DbTodo) (details: TodoDetails) (ctx: DbContext) =
|
let updateTodoById (todo: DbTodo) (details: TodoDetails) (ctx: DbContext) =
|
||||||
todo.Name <- details.name
|
todo.Name <- details.name
|
||||||
todo.Description <- details.description
|
todo.Description <- details.description
|
||||||
|
|
||||||
ctx.SubmitUpdatesAsync()
|
ctx.SubmitUpdatesAsync()
|
||||||
|
|
||||||
|
let patchTodoById (todo: DbTodo) (details: PartialTodoDetails) (ctx: DbContext) =
|
||||||
|
Option.iter (fun name -> todo.Name <- name) details.name
|
||||||
|
Option.iter (fun description -> todo.Description <- description) details.description
|
||||||
|
|
||||||
|
if Option.orElse details.name details.description |> Option.isSome
|
||||||
|
then ctx.SubmitUpdatesAsync()
|
||||||
|
else Async.result()
|
||||||
|
|
Loading…
Reference in a new issue