From c1f6054e15aa7da68ff73be4bb6216ba513e8d99 Mon Sep 17 00:00:00 2001 From: "Daniel J. Summers" Date: Fri, 17 Sep 2021 21:17:26 -0400 Subject: [PATCH] Convert API to .NET 6 --- src/MyPrayerJournal.Api/Data.fs | 1 - src/MyPrayerJournal.Api/Domain.fs | 26 ++++++------ src/MyPrayerJournal.Api/Handlers.fs | 42 +++++++++---------- .../MyPrayerJournal.Api.fsproj | 17 +++----- src/MyPrayerJournal.Api/Program.fs | 12 +++--- 5 files changed, 47 insertions(+), 51 deletions(-) diff --git a/src/MyPrayerJournal.Api/Data.fs b/src/MyPrayerJournal.Api/Data.fs index f921af1..1ab0537 100644 --- a/src/MyPrayerJournal.Api/Data.fs +++ b/src/MyPrayerJournal.Api/Data.fs @@ -79,7 +79,6 @@ module Indexes = /// All data manipulations within myPrayerJournal module Data = - open FSharp.Control.Tasks.V2.ContextInsensitive open Indexes open Microsoft.FSharpLu open Raven.Client.Documents diff --git a/src/MyPrayerJournal.Api/Domain.fs b/src/MyPrayerJournal.Api/Domain.fs index c13431a..fecf0d3 100644 --- a/src/MyPrayerJournal.Api/Domain.fs +++ b/src/MyPrayerJournal.Api/Domain.fs @@ -2,6 +2,8 @@ /// The data model for myPrayerJournal module MyPrayerJournal.Domain +// fsharplint:disable RecordFieldNames + open Cuid /// Request ID is a CUID @@ -9,9 +11,9 @@ type RequestId = | RequestId of Cuid module RequestId = /// The string representation of the request ID - let toString x = match x with RequestId y -> (Cuid.toString >> sprintf "Requests/%s") y + let toString = function RequestId x -> $"Requests/{Cuid.toString x}" /// Create a request ID from a string representation - let fromIdString (y : string) = (Cuid >> RequestId) <| y.Replace("Requests/", "") + let fromIdString (x : string) = x.Replace ("Requests/", "") |> (Cuid >> RequestId) /// User ID is a string (the "sub" part of the JWT) @@ -19,7 +21,7 @@ type UserId = | UserId of string module UserId = /// The string representation of the user ID - let toString x = match x with UserId y -> y + let toString = function UserId x -> x /// A long integer representing seconds since the epoch @@ -27,7 +29,7 @@ type Ticks = | Ticks of int64 module Ticks = /// The int64 (long) representation of ticks - let toLong x = match x with Ticks y -> y + let toLong = function Ticks x -> x /// How frequently a request should reappear after it is marked "Prayed" @@ -38,16 +40,16 @@ type Recurrence = | Weeks module Recurrence = /// Create a recurrence value from a string - let fromString x = - match x with + let fromString = + function | "Immediate" -> Immediate | "Hours" -> Hours | "Days" -> Days | "Weeks" -> Weeks - | _ -> invalidOp (sprintf "%s is not a valid recurrence" x) + | it -> invalidOp $"{it} is not a valid recurrence" /// The duration of the recurrence - let duration x = - match x with + let duration = + function | Immediate -> 0L | Hours -> 3600000L | Days -> 86400000L @@ -62,13 +64,13 @@ type RequestAction = | Answered module RequestAction = /// Create a RequestAction from a string - let fromString x = - match x with + let fromString = + function | "Created" -> Created | "Prayed" -> Prayed | "Updated" -> Updated | "Answered" -> Answered - | _ -> (sprintf "Bad request action %s" >> invalidOp) x + | it -> invalidOp $"Bad request action {it}" /// History is a record of action taken on a prayer request, including updates to its text diff --git a/src/MyPrayerJournal.Api/Handlers.fs b/src/MyPrayerJournal.Api/Handlers.fs index b3a625f..5760732 100644 --- a/src/MyPrayerJournal.Api/Handlers.fs +++ b/src/MyPrayerJournal.Api/Handlers.fs @@ -2,6 +2,8 @@ [] module MyPrayerJournal.Handlers +// fsharplint:disable RecordFieldNames + open Giraffe /// Handler to return Vue files @@ -60,11 +62,10 @@ module private Helpers = /// Create a request ID from a string let toReqId x = - let reqId = - match Cuid.ofString x with - | Ok cuid -> cuid - | Error msg -> invalidOp msg - RequestId reqId + match Cuid.ofString x with + | Ok cuid -> cuid + | Error msg -> invalidOp msg + |> RequestId /// Return a 201 CREATED response let created next ctx = @@ -88,12 +89,12 @@ module private Helpers = /// Work-around to let the Json.NET serializer synchronously deserialize from the request stream // TODO: Remove this once there is an async serializer - let allowSyncIO : HttpHandler = - fun next ctx -> - match ctx.Features.Get() with - | null -> () - | f -> f.AllowSynchronousIO <- true - next ctx + // let allowSyncIO : HttpHandler = + // fun next ctx -> + // match ctx.Features.Get() with + // | null -> () + // | f -> f.AllowSynchronousIO <- true + // next ctx /// Strongly-typed models for post requests @@ -142,8 +143,6 @@ module Models = until : int64 } -open FSharp.Control.Tasks.V2.ContextInsensitive - /// /api/journal URLs module Journal = @@ -165,7 +164,7 @@ module Request = /// POST /api/request let add : HttpHandler = authorize - >=> allowSyncIO + // >=> allowSyncIO >=> fun next ctx -> task { let! r = ctx.BindJsonAsync () @@ -197,7 +196,7 @@ module Request = /// POST /api/request/[req-id]/history let addHistory requestId : HttpHandler = authorize - >=> allowSyncIO + // >=> allowSyncIO >=> fun next ctx -> task { use sess = session ctx @@ -229,7 +228,7 @@ module Request = /// POST /api/request/[req-id]/note let addNote requestId : HttpHandler = authorize - >=> allowSyncIO + // >=> allowSyncIO >=> fun next ctx -> task { use sess = session ctx @@ -309,7 +308,7 @@ module Request = /// PATCH /api/request/[req-id]/snooze let snooze requestId : HttpHandler = authorize - >=> allowSyncIO + // >=> allowSyncIO >=> fun next ctx -> task { use sess = session ctx @@ -327,7 +326,7 @@ module Request = /// PATCH /api/request/[req-id]/recurrence let updateRecurrence requestId : HttpHandler = authorize - >=> allowSyncIO + // >=> allowSyncIO >=> fun next ctx -> task { use sess = session ctx @@ -344,12 +343,11 @@ module Request = | None -> return! Error.notFound next ctx } -open Giraffe.TokenRouter +open Giraffe.EndpointRouting /// The routes for myPrayerJournal -let webApp : HttpHandler = - router Error.notFound [ - route "/" Vue.app +let routes = + [ route "/" Vue.app subRoute "/api/" [ GET [ route "journal" Journal.journal diff --git a/src/MyPrayerJournal.Api/MyPrayerJournal.Api.fsproj b/src/MyPrayerJournal.Api/MyPrayerJournal.Api.fsproj index 8bdd62f..bf6ade7 100644 --- a/src/MyPrayerJournal.Api/MyPrayerJournal.Api.fsproj +++ b/src/MyPrayerJournal.Api/MyPrayerJournal.Api.fsproj @@ -1,7 +1,7 @@  - netcoreapp3.1 + net6.0 3.0.0.0 @@ -14,17 +14,12 @@ - - - - - + + + + - - - - - + diff --git a/src/MyPrayerJournal.Api/Program.fs b/src/MyPrayerJournal.Api/Program.fs index 9a40810..3efae6f 100644 --- a/src/MyPrayerJournal.Api/Program.fs +++ b/src/MyPrayerJournal.Api/Program.fs @@ -36,7 +36,6 @@ module Configure = (Path.Combine >> bldr.UseWebRoot) pathSegments open Giraffe - open Giraffe.Serialization open Microsoft.AspNetCore.Authentication.JwtBearer open Microsoft.Extensions.DependencyInjection open MyPrayerJournal.Indexes @@ -51,7 +50,7 @@ module Configure = let svcs (sc : IServiceCollection) = /// Custom settings for the JSON serializer (uses compact representation for options and DUs) let jsonSettings = - let x = NewtonsoftJsonSerializer.DefaultSettings + let x = NewtonsoftJson.Serializer.DefaultSettings Converters.all |> List.ofSeq |> List.iter x.Converters.Add x.NullValueHandling <- NullValueHandling.Ignore x.MissingMemberHandling <- MissingMemberHandling.Error @@ -61,7 +60,8 @@ module Configure = use sp = sc.BuildServiceProvider () let cfg = sp.GetRequiredService () - sc.AddGiraffe() + sc.AddRouting() + .AddGiraffe() .AddAuthentication( /// Use HTTP "Bearer" authentication with JWTs fun opts -> @@ -75,7 +75,7 @@ module Configure = opts.Audience <- jwtCfg.["Id"] ) |> ignore - sc.AddSingleton (NewtonsoftJsonSerializer jsonSettings) + sc.AddSingleton (NewtonsoftJson.Serializer jsonSettings) |> ignore let config = sc.BuildServiceProvider().GetRequiredService().GetSection "RavenDB" let store = new DocumentStore () @@ -104,6 +104,7 @@ module Configure = bldr.ConfigureLogging logz open System + open Giraffe.EndpointRouting /// Configure the web application let application (bldr : IWebHostBuilder) = @@ -118,7 +119,8 @@ module Configure = | a -> a.UseAuthentication() .UseStaticFiles() - .UseGiraffe Handlers.webApp + .UseRouting() + .UseEndpoints (fun e -> e.MapGiraffeEndpoints Handlers.routes) |> ignore) bldr.Configure appConfig