thoth-org / thoth.json.giraffe Goto Github PK
View Code? Open in Web Editor NEWHome Page: https://thoth-org.github.io/Thoth.Json/#Giraffe
Home Page: https://thoth-org.github.io/Thoth.Json/#Giraffe
I'm working on a SAFE Template application v1.01.
I ran a Paket update on my project, which updated Thoth.Json.Net to v3.0.0
This is the error I got back when trying to run my application.
An exception of type 'System.MissingMethodException' occurred in Giraffe.dll but was not handled in user code: 'Method not found: 'System.String Auto.toString(Int32, System.Object, Microsoft.FSharp.Core.FSharpOption`1<Boolean>)'.'
at Thoth.Json.Giraffe.ThothSerializer.Giraffe-Serialization-Json-IJsonSerializer-SerializeToBytes[T](T o)
at Giraffe.ResponseWriters.HttpContext.WriteJsonAsync[T](HttpContext this, T dataObj)
I think this is due to a breaking API change that Thoth.Json.Giraffe 1.1 depends upon, when updating to Thoth.Json.Giraffe 2.0.0-beta-001 and Thoth.Json.Net 3.0 to see if that would allow a workaround that did not work.
Because of this I have rolled back to Thoth.Json.Net 2.5 in order to get it working again.
If you need me to provide a more complete Repro I am happy to provide that.
Sorry for creating an empty issue earlier not sure why it did that.
When using the ThothSerializer in Giraffe, attempting to deserialize an empty request body generates an exception from Newtonsoft.Json with Error reading JToken from JsonReader
. The default Giraffe serializer (Utf8Json) returns null for the same case.
This happens whether I use ctx.BindJsonAsync
, Controller.getJson
, or ThothSerializer.ReadBody
. For ReadBody, I would prefer this to just be an Error allowing me to return a 403 to the client.
Hello,
Would it be possible to remove the setStatusCode to 200 from ThothSerializer.RespondRawJson? Or create a new method which do not set the code?
In the case of api it's useful to return a json associated with a 400 or a 404.
I am getting this error:
Cannot generate auto encoder for System.Collections.Generic.IEnumerable`1[[System.String,
System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]. Please pass an
extra encoder.</h3>
There was a similar error reported in Thoth.Json:
Maybe that same resolution can also be pulled into Thoth.Json.Giraffe? Or I am doing something wrong?
I have added Thoth.Json.Giraffe as my serializer like this:
services.AddSingleton<Giraffe.Serialization.Json.IJsonSerializer>(Thoth.Json.Giraffe.ThothSerializer())
My workaround was to make sure all collection types were list
, which is fine with me.
Unhandled exception. System.AggregateException: Some services are not able to be constructed (Error while validating the service descriptor 'ServiceType: Giraffe.Json+ISerializer Lifetime: Singleton ImplementationType: Thoth.Json.Giraffe.ThothSerializer': Unable to resolve service for type 'Microsoft.FSharp.Core.FSharpOption`1[Thoth.Json.Net.CaseStrategy]' while attempting to activate 'Thoth.Json.Giraffe.ThothSerializer'.)
[server] ---> System.InvalidOperationException: Error while validating the service descriptor 'ServiceType: Giraffe.Json+ISerializer Lifetime: Singleton ImplementationType: Thoth.Json.Giraffe.ThothSerializer': Unable to resolve service for type 'Microsoft.FSharp.Core.FSharpOption`1[Thoth.Json.Net.CaseStrategy]' while attempting to activate 'Thoth.Json.Giraffe.ThothSerializer'.
Here is my original code.
services.AddSingleton<Json.ISerializer, ThothSerializer>() |> ignore
Is there any thing more I need to do? Other than providing in service injector ?
It would be really nice to have some tests to check that Thoth.Json.Giraffe works.
The tests can be really basic at first:
Hi, I'm new to fsharp and the ecosystem. I'm trying to get the following working with Satrun framework.
I want to have json responses that either have a payload or error like so:
{ "data": {...}}
{ "errors": [{"field_a": "field_a_error"}, {"field_b": "field_b_error"}]}
I modeled it as following with custom coders:
type ApiResponse<'t> =
| ApiData of 't
| ApiError of list<string * VError>
static member Encoder =
function
| ApiData d ->
let encoder = Encode.Auto.generateEncoderCached<'t>()
Encode.object ["data", encoder(d)]
| ApiError errors ->
let encoder = Encode.Auto.generateEncoderCached<VError>()
let jsonErrors = List.map (fun err -> Encode.object [(fst err), encoder (snd err)]) errors
Encode.object ["errors", Encode.list jsonErrors]
static member Decoder: Decoder<ApiResponse<'t>> =
let dataDecoder =
Decode.object (fun get ->
Decode.Auto.generateDecoderCached<'t>()
|> get.Required.Field "data"
|> ApiData)
let errorsListDecoder = Decode.Auto.generateDecoderCached<VError>() |> Decode.keyValuePairs
let errorsDecoder =
Decode.object (fun get ->
errorsListDecoder
|> get.Required.Field "errors"
|> ApiError)
Decode.oneOf [dataDecoder; errorsDecoder]
I used custom coders because the default serialization of union types wasn't very desirable to me.
I've added the custom coders as extra and added them to ThothSerializer like so:
let extraCoders =
Extra.empty
|> Extra.withCustom ApiResponse.Encoder ApiResponse.Decoder
let app =
application {
url ("http://0.0.0.0:" + port.ToString() + "/")
use_router webApp
memory_cache
use_static publicPath
use_json_serializer (Thoth.Json.Giraffe.ThothSerializer(SnakeCase, extraCoders))
use_gzip
}
However when I return an ApiResponse<'t>
from an endpoint it is still using the default serialization.
let createProduct tenantId =
fun next ctx -> task {
let! productDto = Controller.getModel<Product.CreateDto> ctx
match saveProduct productDto with
| Success product ->
let res = product |> ApiData
return! json res next ctx
| Failure errors ->
let res = errors |> ApiError
return! json res next ctx
}
Did I miss something?
Hi,
I can't figure out how to work with PATCH requests, where you want to update just the specified fields of an entity.
Problems arise when I want to update an optional value and I need to distinguish between the field not being present in the json and specifically setting null as a value.
I'm using Saturn/Giraffe/Thoth.Json.Giraffe.
If there is no supported way of doing this, I thought about representing my changes in JSON Patch format. That should be easier to handle. (http://jsonpatch.com)
Any suggestions?
Deserialize<'T>(json: string)
can deserialize date type string as string, but Deserialize<'T>(bytes: byte[])
and DeserializeAsync<'T>(stream: Stream)
will fail because Newtonsoft.Json parse date type string as date type by default.
e.g.
Error at:
$
Expecting a string but instead got: "2020-01-01T00:00:00Z"
Can we please add jsonReader.DateParseHandling <- DateParseHandling.None
to both Deserialize<'T>(bytes: byte[])
and DeserializeAsync<'T>(stream: Stream)
? Because Deserialize<'T>(json: string) uses Decode.fromString, which already has DateParseHandling.None
applied.
@MangelMaxime I am happy to submit a PR if you are OK with this fix.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.