Giter Site home page Giter Site logo

Comments (11)

MangelMaxime avatar MangelMaxime commented on August 20, 2024 1
1. What should we replace the sample calls with `fetchAs` in [the docs](https://safe-stack.github.io/docs/feature-clientserver/) with?
// Cache the customer decoder for size optimisation
// See: https://mangelmaxime.github.io/Thoth/json/v2/decode.html#size-optimization
let customerDecoder = Decode.Auto.generateDecoder<Customer>()

promise {    
    let! customers = Fetch.fetchAs (sprintf "api/customers") (Decode.array customerDecoder) []
    // do more with customers here...
}

2. What needs changing on the server side? I assume that the section Turning on Fable's JSON Converter is now outdated and should be changed to use Thoth as well?

If you want to use the auto decoders in a transparent way from Giraffe then users should use ThothSerializer.

If they want to use manual decoders or if needed, they can read/write the string directly from/into the body. Example

For example

3\. What are the options, pros / cons, when should you use "full" Thoth or Auto decoding etc.?

This part can be opiniated but in IHMO:

If you are sharing your F# types, then you can use auto decoders/encoders with the limitation that you can't auto encode/decode classes.

// This will return None (if you set the json `MaybeClass` to `null` in the json)
type RecordWithOptionalClass =
    { MaybeClass : BaseClass option
      Must : string }

// This will return an Error
type RecordWithRequiredClass =
    { Class : BaseClass
      Must : string }

Use manual decoders/encoders if:

  • You want control the JSON representation
  • Are calling an external services
  • Are using F# on one side and anothers languages on the other side

from docs.

isaacabraham avatar isaacabraham commented on August 20, 2024 1

Great. This seems to also just work, which I somewhat prefer i.e. "i want to fetch some customers from this uri":

fetchAs<Counter []> "/api/customers" (Decode.Auto.generateDecoder())

This even works (as long as there are type hints elsewhere):

fetchAs "/api/customers" (Decode.Auto.generateDecoder())

And I was also able to get this working:

let inline quickFetch route = fetchAs route (Decode.Auto.generateDecoder())
let customers = quickFetch "/api/customers" // could also do quickFetch<Customer []> etc.

Seems you must inline this otherwise Fable complains about the ITypeResolver, but otherwise - any thoughts?

from docs.

isaacabraham avatar isaacabraham commented on August 20, 2024 1

Great, I agree. I'll look to push some updates to the docs this week - if you could review it when it's ready that would be great. @theimowski I'm also preparing a PR to update the template to move over to Thoth completely.

from docs.

theimowski avatar theimowski commented on August 20, 2024 1

I'm wondering whether it makes sense to add to the template an example of fetch with custom Record type instead of an integer?

from docs.

isaacabraham avatar isaacabraham commented on August 20, 2024

@MangelMaxime Thanks for this - very helpful!

Where / what is ThothSerializer? Is that in the Thoth.Json.Giraffe package (if so, I found it!).

But yes, for the basic template I want to just have transparent, auto generated "risky" deserialization. Is there a more lightweight way (even if it's not as performant) where you don't have to create a Decoder explicitly but can just create it inline in the call to fetch?

from docs.

MangelMaxime avatar MangelMaxime commented on August 20, 2024

Yes it's coming from Thoth.Json.Giraffe

Is there a more lightweight way

For now no because with Fable 2 you need to use [<Inject>] ?resolver: ITypeResolver<'T> for Fable to include the TypeInfo in the runtime.

And Fable.PowerPack.Fetch is function based.
We designed the Fable.PowerPack.Fetch so have the experience when using manual or auto decoders. But if you have a suggestion to support both style in a clean way we can discuss it on the PowerPack repo.

from docs.

isaacabraham avatar isaacabraham commented on August 20, 2024

I only thought there was another way because the comment says "cache the decoded for size optimization " - is there another way without caching e.g. is this valid?

let customerDecoder = Decode.Auto.generateDecoder<Customer>()

promise {    
    let! customers = Fetch.fetchAs (sprintf "api/customers") (Decode.Auto.generateDecoder<Customer []> []
    // do more with customers here...
}

from docs.

MangelMaxime avatar MangelMaxime commented on August 20, 2024

Ah yes, it's valid.

from docs.

MangelMaxime avatar MangelMaxime commented on August 20, 2024

I didn't know about the last one.

And I didn't experiment a lot with the auto decoder but it's really nice to see. I personnaly prefer if we show an usage with type hints, because I think it's better to be sure of the return type :)

So in the doc we could show something like::

let! customers = fetchAs<Customers []> "/api/customers" (Decode.Auto.generateDecoder())

// or
let! customers : Customers [] = fetchAs "/api/customers" (Decode.Auto.generateDecoder())

In more complexe example showing the last case can be something interesting. Because from my experience, you end up rewriting the fetch module to make your helpers dedicated to your app.

For example, because I want to support the refreshToken feature in my production I have helpers like:

    let postRecord (url: string) (user : User) (body: string) (properties: RequestProperties list) =
        let httpRequest token =
            let defaultProps =
              [ RequestProperties.Method HttpMethod.POST
                requestHeaders [ ContentType "application/json"
                                 Authorization ("Bearer " + token) ]
                RequestProperties.Body !^(body) ]

            List.append defaultProps properties
            |> fetch url

        httpRequest user.Token
        |> Promise.bind (handleRefreshToken user httpRequest)

So we can imagine the same applied to get quickFetch synthax.

from docs.

MangelMaxime avatar MangelMaxime commented on August 20, 2024

Sure ping me when I need to review it.

from docs.

isaacabraham avatar isaacabraham commented on August 20, 2024

The PR in the template is available here. Docs to follow.

from docs.

Related Issues (20)

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.