fsharp(todolist-api): feat: editing todos
Signed-off-by: prescientmoon <git@moonythm.dev>
This commit is contained in:
parent
4951b6c2ca
commit
38e6717f76
|
@ -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
|
||||||
|
|
|
@ -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()
|
||||||
|
|
Loading…
Reference in a new issue