haskell-servant / servant

Servat is a Haskell DSL for describing, serving, querying, mocking, documenting web applications and more!
https://docs.servant.dev/
1.83k stars 414 forks source link

(servant-foreign / servant-js) missing instances for PlainText content-type #509

Open rvion opened 8 years ago

rvion commented 8 years ago

ghc gives

No instance for servant-foreign-0.6.1:Servant.Foreign.Internal.NotFound
  arising from a use of ‘jsForAPI’
In the second argument of ‘($)’, namely ‘jsForAPI api vanillaJS’
In the first argument of ‘(:<|>)’, namely
  ‘(return $ jsForAPI api vanillaJS)’
In the second argument of ‘(:<|>)’, namely
  ‘(return $ jsForAPI api vanillaJS)
   :<|> (return $ decodeUtf8 . toStrict . encode . toSwagger $ api)’

when I try to make js output for ("api" :> Get '[PlainText] Text)

jkarni commented 8 years ago

Hm, I know very little about servant-js/servant-foreign. It seems JSON is the only supported content-type? @dredozubov and @freezeboy probably know better, though.

codedmart commented 8 years ago

@jkarni is right, currently JSON only is supported https://github.com/haskell-servant/servant/blob/master/servant-js/src/Servant/JS/Vanilla.hs#L37-L38

freezeboy commented 8 years ago

Yup, maybe we can add more instances, at least the plain text and CSV (cassava) are easily doable

dredozubov commented 8 years ago

I can confirm, only JSON is currently supported and it shouldn't be hard to add more content-types.

phadej commented 7 years ago

Should there be some kind type class tying content types and lang?

Also it would be great to be able to use servant-foreign on api with not JSON endpoints. Should we add API filtering type family?

NorfairKing commented 7 years ago

+1

NorfairKing commented 7 years ago

Any progress here?

alpmestan commented 7 years ago

No, nobody has yet done the work of adding support for other content types to -foreign/-js. This task is up for grabs.

tmbull commented 7 years ago

I just ran into this issue today while trying to use servant-elm to generate a client for an API that returns a csv. I would be happy to help, but I might need a pointer in the right direction as I don't have any experience with servant-foreign.

alpmestan commented 7 years ago

So this would require changing two instances, the one for Verb and the one for ReqBody. Let's look at the latter, for now. It's here.

You can see that at the very beginning there's Elem JSON list, which enforces that JSON is somewhere in the content types list (the ... in ReqBody '[...] a). And then we just don't use that fact. It's just that you can see that we update a field using lens in that req value, but don't tell anyone that we're dealing with a JSON request body, it's just assumed by default. The gist of the task is therefore to 1/ lift the Elem JSON list constraint by... 2/ adding the appropriate bits of information in this type, so as to attach the content type(s) that can be used for sending a request body to that endpoint.

Then any library that uses servant-foreign to generate foreign code that can query an API is free to just say "I can only handle JSON, do you support JSON?" or "give by any content type, I can encode my user's data in it just fine, try me!" or anywhere in the middle. The key part is just in making the supported content types for request and response bodies part of what servant-foreign collects.

Let me know if you have more specific questions.

tmbull commented 7 years ago

@alpmestan Thanks for the reply. Makes sense to me. I'll give it a try and let you know if I run into any more questions.