From 38e6717f76111f1ce294202317066358ac2cbed8 Mon Sep 17 00:00:00 2001 From: Matei Adriel Date: Thu, 2 Jan 2020 15:37:47 +0200 Subject: [PATCH] fsharp(todolist-api): feat: editing todos Signed-off-by: prescientmoon --- fsharp/todolist-api/src/App.fs | 55 +++++++++++++++++++++++++++++----- fsharp/todolist-api/src/Db.fs | 22 +++++++++----- 2 files changed, 63 insertions(+), 14 deletions(-) diff --git a/fsharp/todolist-api/src/App.fs b/fsharp/todolist-api/src/App.fs index adc665e..a4eede5 100644 --- a/fsharp/todolist-api/src/App.fs +++ b/fsharp/todolist-api/src/App.fs @@ -1,34 +1,75 @@ // 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.Successful open Suave.Operators -open Suave.Filters +open Suave.Successful open Suave.RequestErrors open Suave.Json +open Suave.Filters module Utils = open System.Text + open Db.Types let jsonToString json = json |> toJson |> Encoding.UTF8.GetString + let todoToRecord (todo: DbTodo) = + { id = todo.Id + description = todo.Description + name = todo.Name } + module App = open Utils + open Db let todoById (id) = - let todo = Db.Context.getContext() |> Db.Queries.getTodosById id + let todo = + Context.getContext() + |> Queries.getTodosById id + |>> todoToRecord match todo with | Some inner -> inner |> jsonToString |> OK | 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 [ - GET >=> choose [ - pathScan "/todos/%i" todoById - ]] + GET >=> pathScan "/todos/%i" todoById + PUT >=> pathScan "/todos/%i" updateTodo] [] 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 diff --git a/fsharp/todolist-api/src/Db.fs b/fsharp/todolist-api/src/Db.fs index 0f13d4e..a57faee 100644 --- a/fsharp/todolist-api/src/Db.fs +++ b/fsharp/todolist-api/src/Db.fs @@ -30,23 +30,31 @@ module Types = name: string } - let todoToRecord (todo: DbTodo) = - { id = todo.Id - description = todo.Description - name = todo.Name } + [] + type TodoDetails = + { [] + description: string + [] + name: string } + module Queries = - open FSharpPlus.Operators open Context open Types - let getTodosById id (ctx: DbContext): Todo option = + let getTodosById id (ctx: DbContext): DbTodo option = query { for todo in ctx.Public.Todos do where (todo.Id = id) select todo } |> Seq.tryHead - |>> todoToRecord + + + let updateTodosById (todo: DbTodo) (details: TodoDetails) (ctx: DbContext) = + todo.Name <- details.name + todo.Description <- details.description + + ctx.SubmitUpdatesAsync() \ No newline at end of file