Comments (11)
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
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.
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.
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.
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.
@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.
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.
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.
Ah yes, it's valid.
from docs.
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.
Sure ping me when I need to review it.
from docs.
The PR in the template is available here. Docs to follow.
from docs.
Related Issues (20)
- feature request for documentation: add test examples HOT 2
- Client side F# debugging in VS Code HOT 8
- "Serve a file from the back-end" example not working HOT 6
- Upgrade upload/download binary content recipes to use latest Fable Remoting capabilities. HOT 3
- Code examples should include which libraries they are using
- Broken links on "Package my SAFE app for deployment" HOT 1
- Feature request for documentation: add hosting "how do I"'s HOT 1
- Debug instructions for VS Code incorrect HOT 2
- Add IE11 support recipe HOT 6
- NET6 HOT 4
- Mistake in Client tests recipe? HOT 1
- Azure Type Provider warning may be outdated HOT 2
- Add article for implementing DI in the Server
- Create a recipe to migrate to tailwind. HOT 2
- upload-file-from-client instructions fail HOT 2
- Move to GH Actions? HOT 5
- How do I set the return URI for the Azure AD login to the client port during the dev phase? HOT 1
- Fable Forms questions / optimisations HOT 1
- Define and apply standard formatting
- SAFE v5 updates HOT 7
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from docs.