1
Fork 0

fsharp(todolist-api): feat: got patching to work

Signed-off-by: prescientmoon <git@moonythm.dev>
This commit is contained in:
Matei Adriel 2020-01-02 17:24:57 +02:00 committed by prescientmoon
parent 3023f6c410
commit f3a4b3c957
Signed by: prescientmoon
SSH key fingerprint: SHA256:UUF9JT2s8Xfyv76b8ZuVL7XrmimH4o49p4b+iexbVH4
2 changed files with 55 additions and 17 deletions

View file

@ -1,8 +1,6 @@
// 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.Operators
open Suave.Successful
@ -19,7 +17,7 @@ module Utils =
description = todo.Description
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 =
open Utils
@ -41,7 +39,7 @@ module App =
fun ctx -> async {
let body: Types.TodoDetails = parseJson ctx.request.rawForm
do! Queries.updateTodosById todo body dbContext
do! Queries.updateTodoById todo body dbContext
let newBody: Types.Todo = {
name = body.name
@ -52,12 +50,33 @@ module App =
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 [
GET >=> pathScan "/todos/%i" todoById
PUT >=> pathScan "/todos/%i" updateTodo]
pathScan "/todos/%i" (fun (id) -> choose [
GET >=> todoById id
PUT >=> updateTodo id
PATCH >=> patchTodo id
])]
[<EntryPoint>]
let main _ =

View file

@ -54,9 +54,20 @@ module Types =
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 =
open FSharpPlus.Builders
open Context
open Types
@ -69,9 +80,17 @@ module Queries =
|> Seq.tryHead
let updateTodosById (todo: DbTodo) (details: TodoDetails) (ctx: DbContext) =
let updateTodoById (todo: DbTodo) (details: TodoDetails) (ctx: DbContext) =
todo.Name <- details.name
todo.Description <- details.description
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()