Closed tysonzero closed 5 years ago
See servant-client-ghcjs
package in the repository (not yet published)
Yeah I know about servant-client-ghcjs
, I mentioned it in the question, just wanted to see if I could use a single package both in the browser (ghcjs
) and on the server (ghc
). It also would be nice to use a package that's on hackage / stackage / nixpkgs
.
A single package would be the simplest for users, but I think it's a bit of a nightmare for the implementors (haven't worked on servant-client-ghcjs myself, but I've seen others struggle with this very idea, because you then have to stuff everything under common types/functions, which is not necessarily desirable). It should definitely be on hckage though, yes, but it's not well tested and doesn't get a lot of love. I think we don't even check it in CI yet because of how complicated it is to have CI run over it while staying in the free tier of travis, IIRC. So yeah, this package really needs someone or several someones who care about getting servant-client to work nicely with ghcjs, I think. @FPtje is I think one of the few persons who've worked on this, in case you want to get in touch and discuss the current state of things etc.
servant-client-ghcjs
works, but there are some development challenges. For one, there are tests, but they're in a separate repository (https://github.com/FPtje/servant-client-ghcjs-test) since the tests involve both a server and a client application. Running a test is done by starting the test server, going to the page in a browser and checking the output of the console.
It should be possible to test using nodeJS, which should make it easier to automate the test, though I haven't looked at that yet.
The biggest practical issue we have with servant-client-ghcjs
is that the sending and receiving of binary data isn't supported, though that's fixed in #938.
Other than that servant-client-ghcjs
has some serious things going for it. We can re-use the API specification and even the client functions in servers, regular clients and browser clients. That and it abstracts the browser's XHR mechanism, which is super convenient.
@FPtje Ah ok that all makes sense, nice work!
So if you can use servant-client-ghcjs
in servers and regular-clients, I assume that means it works with ghc
. At which point what is the difference between it and servant-client
? Is it something to do with the mechanism by which each does api requests, sockets vs http requests or similar, in which case would a name change be appropriate?
No, that's not what I mean. I mean that we can define client functions in haskell files that are compiled by both ghc and ghcjs. On ghc we can call those client functions using servant-client
, on ghcjs we can call them using servant-client-ghcjs
. servant-client
doesn't compile on ghcjs, and servant-client-ghcjs
doesn't compile on ghc. Sorry if that was unclear.
servant-client-ghcjs
very specifically uses Javascript's Xhr mechanism. servant-client
(through a library) sends the http requests using system sockets.
@tysonzero Just to clarify, there are 3 packages at play here:
servant-client-core
: defines the HTTP client lib agnostic code that lets us derive client functions for a given API type, parametrized by the monad (= http client backend, more or less) in which we run them.servant-client
: implements the http-client
backend for servant-client-core
, this is the package most people end up using for deriving haskell functions.servant-client-ghcjs
: implements the "ghcjs" backend (through Xhr) for servant-client-core
.You can derive client functions "polymorphic in the backend" using servant-client-core
and I think this is what @FPtje is alluding to in the comment above. Or you can conditionally import one backend or the other depending on the compiler of the current module, perhaps. Anyway, you probably get the idea. There's one backend-agnostic package, 2 distinct backends.
Thanks for the elaboration, that makes sense. On a side note is it true that servant-client
does work for ghcjs
as long as you use it with node
/ something with access to sockets?
If ghcjs has the correct stubs for the network
library then the answer is yes. but I'm not sure if it does.
There is servant-client-ghcjs
I'm currently getting a
uncaught exception in Haskell thread: ReferenceError: h$hsnet_getaddrinfo is not defined
error when usingservant-client-0.11
.Some research seems to indicate that
servant-client
doesn't work in the browser. Is there any chance it can be made to work in the browser so that I can use the same client functions when compiling with bothghc
andghcjs
, and if not would it be possible for the error message to be more clear, likeservant-client not supported in browser, please use servant-client-ghcjs
.