Open erkez opened 8 years ago
if you have different things, is perhaps using an ADT with different constructors for different cases an option?
data Thing = Number Int | Boolean Bool
different mime types can be generated like this:
type Api = "number" :> Get '[JSON, PlainText, HTML, CSV] Thing
follow the type errors in the instructions in the tutorial to figure out how to implement all the required encodings.
does that help?
Thanks, but I think that is not really what I wanted. Let's say that an API accepts any image content type and you must provide it together with the image data in the body. The content type must be provided by the user when calling a Servant client generated function. Maybe I missed. Is there a way to do it at the moment?
when i have this situation, i make the server offer all content types in the way i described, and let the client pick one via the accept
http header.
i've not used servant-client much, perhaps this is a missing feature. i guess one way this could be done is to translate end-points that respond with more than one content type into functions that have a content type selector argument.
@erkez there's no way of doing that - servant-client currently only uses the first content-type in the list. Changing this wouldn't be too hard (essentially just adding an argument here) but it's not obvious to me how we can make choosing a content-type optional...
On the server side offering all content types is not always an option either. Take that image upload example and think a step further, downloading the image again. You have an image of one content type only, so you can not offer all, just one of several, which one is not known at compile time or to the client (so using different routes is not really an option either). It would be very useful if you could just manually (in the handler) decide which ones to offer instead of hard-coding the Accept header as the only source of this decision.
@taladar That would be nice. Any idea of how that would look and/or work is welcome, same for patches :)
Well, one option would be to have a special return value wrapper that specifies a Content-Type along with the body of the response, overriding the Accept header selection. Another would be to completely remove the Accept-header hard-coding and pass a function handling content type selection to serve/serveWithContext and provide a default implementation that uses the Accept header.
I have run into this issue as well, but it looks like @dzhus has fixed this (based on the issue reference above). Is there a reason why this doesn't seem to have been merged / there doesn't appear to be a PR for it?
Is there a reason why this doesn't seem to have been merged / there doesn't appear to be a PR for it?
I'd guess it's because no one has made effort to.
Indeed! :-)
@dzhus I guess my comment was asking whether you'd want to open a PR for your changes? I think it would be a bit weird for someone else to do that.
Wow, it is 2020 now, this issue is still here.
I try to override the Content-Type
header in Handler:
-- contentType (Proxy :: Proxy IMAGE) = "image/*"
type GetAPI = Capture "id" Int :> Get '[IMAGE] (Headers '[Header "Content-Type" String] ByteString)
get :: Server GetAPI
get id = return $ addHeader "image/jpeg" $ readFile "/www/images/" ++ (show id) ++ ".jpeg"
then I get two Content-Type
headers:
Content-Type: image/*
Content-Type: image/jpeg
I think servant server should not response wildcard Content-Type
header, the wildcard media type is mainly used by client, the server side should be responsible for telling the client the media type of the content it sends.
It may break the servant api design pattern, but it is very useful in practice and is more logical.
I made a patch for Servant.Server.Internal
#1274
@gqk007 Could you please make a separate report as yours is about server behaviour, not how servant-client populates content-type header.
I created a new issue, see #1275.
The library is great! But there is one thing that I've been trying to figure out how to do: setting a content type on servant client depending on the input. How do I let the user define the content type? When I create the client routes, the content type is always defined next to
ReqBody
. Is there any way to do that?A use case is file upload. For example, an avatar could have many different mime type values.