Giter Site home page Giter Site logo

thoth.json.giraffe's People

Contributors

benniecopeland avatar dependabot[bot] avatar forki avatar johannesegger avatar mangelmaxime avatar maxdeg avatar yang-qu avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

thoth.json.giraffe's Issues

Updating to Thoth.Json 3.0 breaks serialisation

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.

Deserializer throws exception when request body is empty.

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.

Remove setStatusCode from ThothSerializer.RespondRawJson

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.

Cannot generate auto encoder for System.Collections.Generic.IEnumerable

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:

thoth-org/Thoth.Json#26

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.

Issue while integrating with Giraffe

 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 ?

Add tests

It would be really nice to have some tests to check that Thoth.Json.Giraffe works.

The tests can be really basic at first:

  1. Starting a Giraffe server
  2. Execute a request to the server
  3. Check that the result is correct

Usage of extracoders in Giraffe

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?

How to handle PATCH-style requests

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 date type string as string

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.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.