diff --git a/ConsumePlugin/GeneratedRestClient.fs b/ConsumePlugin/GeneratedRestClient.fs index 63ada16..5a090d7 100644 --- a/ConsumePlugin/GeneratedRestClient.fs +++ b/ConsumePlugin/GeneratedRestClient.fs @@ -414,6 +414,72 @@ module PureGymApi = } |> (fun a -> Async.StartAsTask (a, ?cancellationToken = ct)) + member _.CreateUserSerialisedUrlBody (user : Uri, ct : CancellationToken option) = + async { + let! ct = Async.CancellationToken + + let uri = + System.Uri ( + (match client.BaseAddress with + | null -> System.Uri "https://whatnot.com" + | v -> v), + System.Uri ("users/new", System.UriKind.Relative) + ) + + let httpMessage = + new System.Net.Http.HttpRequestMessage ( + Method = System.Net.Http.HttpMethod.Post, + RequestUri = uri + ) + + let queryParams = + new System.Net.Http.StringContent ( + user + |> System.Text.Json.Nodes.JsonValue.Create + |> (fun node -> node.ToJsonString ()) + ) + + do httpMessage.Content <- queryParams + let! response = client.SendAsync (httpMessage, ct) |> Async.AwaitTask + let response = response.EnsureSuccessStatusCode () + let! responseString = response.Content.ReadAsStringAsync ct |> Async.AwaitTask + return responseString + } + |> (fun a -> Async.StartAsTask (a, ?cancellationToken = ct)) + + member _.CreateUserSerialisedIntBody (user : int, ct : CancellationToken option) = + async { + let! ct = Async.CancellationToken + + let uri = + System.Uri ( + (match client.BaseAddress with + | null -> System.Uri "https://whatnot.com" + | v -> v), + System.Uri ("users/new", System.UriKind.Relative) + ) + + let httpMessage = + new System.Net.Http.HttpRequestMessage ( + Method = System.Net.Http.HttpMethod.Post, + RequestUri = uri + ) + + let queryParams = + new System.Net.Http.StringContent ( + user + |> System.Text.Json.Nodes.JsonValue.Create + |> (fun node -> node.ToJsonString ()) + ) + + do httpMessage.Content <- queryParams + let! response = client.SendAsync (httpMessage, ct) |> Async.AwaitTask + let response = response.EnsureSuccessStatusCode () + let! responseString = response.Content.ReadAsStringAsync ct |> Async.AwaitTask + return responseString + } + |> (fun a -> Async.StartAsTask (a, ?cancellationToken = ct)) + member _.CreateUserHttpContent (user : System.Net.Http.HttpContent, ct : CancellationToken option) = async { let! ct = Async.CancellationToken diff --git a/ConsumePlugin/RestApiExample.fs b/ConsumePlugin/RestApiExample.fs index ea51ff9..f475cf3 100644 --- a/ConsumePlugin/RestApiExample.fs +++ b/ConsumePlugin/RestApiExample.fs @@ -53,6 +53,12 @@ type IPureGymApi = [] abstract CreateUserSerialisedBody : [] user : PureGym.Member * ?ct : CancellationToken -> Task + [] + abstract CreateUserSerialisedUrlBody : [] user : Uri * ?ct : CancellationToken -> Task + + [] + abstract CreateUserSerialisedIntBody : [] user : int * ?ct : CancellationToken -> Task + [] abstract CreateUserHttpContent : [] user : System.Net.Http.HttpContent * ?ct : CancellationToken -> Task diff --git a/README.md b/README.md index 19c9f16..e586540 100644 --- a/README.md +++ b/README.md @@ -319,7 +319,6 @@ thereby allowing the programmer to use F#'s record-update syntax. ### Limitations -* We currently only support interfaces with tupled arguments. * We make the resulting record type at most internal (never public), since this is intended only to be used in tests. You will therefore need an `AssemblyInfo.fs` file [like the one in WoofWare.Myriad's own tests](./ConsumePlugin/AssemblyInfo.fs). diff --git a/WoofWare.Myriad.Plugins.Test/TestHttpClient/TestBodyParam.fs b/WoofWare.Myriad.Plugins.Test/TestHttpClient/TestBodyParam.fs index f86032f..5e31d59 100644 --- a/WoofWare.Myriad.Plugins.Test/TestHttpClient/TestBodyParam.fs +++ b/WoofWare.Myriad.Plugins.Test/TestHttpClient/TestBodyParam.fs @@ -148,3 +148,41 @@ module TestBodyParam = |> System.Text.Json.Nodes.JsonNode.Parse |> PureGym.Member.jsonParse |> shouldEqual expected + + [] + let ``Body param of primitive: int`` () = + let proc (message : HttpRequestMessage) : HttpResponseMessage Async = + async { + message.Method |> shouldEqual HttpMethod.Post + let! content = message.Content.ReadAsStringAsync () |> Async.AwaitTask + let content = new StringContent ("Done! " + content) + let resp = new HttpResponseMessage (HttpStatusCode.OK) + resp.Content <- content + return resp + } + + use client = HttpClientMock.make (Uri "https://example.com") proc + let api = PureGymApi.make client + + let result = api.CreateUserSerialisedIntBody(3).Result + + result |> shouldEqual "Done! 3" + + [] + let ``Body param of primitive: Uri`` () = + let proc (message : HttpRequestMessage) : HttpResponseMessage Async = + async { + message.Method |> shouldEqual HttpMethod.Post + let! content = message.Content.ReadAsStringAsync () |> Async.AwaitTask + let content = new StringContent ("Done! " + content) + let resp = new HttpResponseMessage (HttpStatusCode.OK) + resp.Content <- content + return resp + } + + use client = HttpClientMock.make (Uri "https://example.com") proc + let api = PureGymApi.make client + + let result = api.CreateUserSerialisedUrlBody(Uri "https://mything.com/blah").Result + + result |> shouldEqual "Done! \"https://mything.com/blah\"" diff --git a/WoofWare.Myriad.Plugins/HttpClientGenerator.fs b/WoofWare.Myriad.Plugins/HttpClientGenerator.fs index 48325fd..982da34 100644 --- a/WoofWare.Myriad.Plugins/HttpClientGenerator.fs +++ b/WoofWare.Myriad.Plugins/HttpClientGenerator.fs @@ -481,11 +481,6 @@ module internal HttpClientGenerator = ) ] | BodyParamMethods.Serialise ty -> - let typeIdent = - match SynType.stripOptionalParen ty with - | SynType.LongIdent (SynLongIdent.SynLongIdent (ident, _, _)) -> ident - | _ -> failwith $"Unable to identify type %+A{ty}" - [ Let ( "queryParams", @@ -496,11 +491,7 @@ module internal HttpClientGenerator = ), SynExpr.CreateParen ( SynExpr.CreateIdent bodyParamName - |> SynExpr.pipeThroughFunction ( - SynExpr.CreateLongIdent ( - SynLongIdent.CreateFromLongIdent (typeIdent @ [ Ident.Create "toJsonNode" ]) - ) - ) + |> SynExpr.pipeThroughFunction (JsonSerializeGenerator.serializeNode ty) |> SynExpr.pipeThroughFunction ( SynExpr.createLambda "node"