You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
On 21 Feb 2018, at 17.05, Nickolay Kudasov ***@***.***> wrote:
yesod-form also has support for file upload (see Cookbook file upload saving files to server).
File upload field is created using fileAFormReq. File info is represented with FileInfo:
data FileInfo = FileInfo
{ fileName :: !Text
, fileContentType :: !Text
, fileSourceRaw :: !(ConduitT () ByteString (ResourceT IO) ())
, fileMove :: !(FilePath -> IO ())
}
They also seem to have 3 options for handling file uploads (on the server):
data FileUpload
= FileUploadMemory !(NWP.BackEnd L.ByteString)
| FileUploadDisk !(InternalState -> NWP.BackEnd FilePath)
| FileUploadSource !(NWP.BackEnd (ConduitT () ByteString (ResourceT IO) ()))
Note the last option which is not available with servant-multipart AFAICT.
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub, or mute the thread.
The more I think about it the more it seems like we should just provide common data types and not use type classes 🙃
For instance we could just provide something like this:
dataMultiPartFormDatafile=MultiPartFormData{mpfdInputs::Form
, mpfdFiles:: [FileDatafile]
}dataFileDatafile=FileData{fdInputName::Text-- input field name
, fdFileName::Text-- user's file name
, fdFileHeaders:: [Header] -- additional file headers
, fdContentType::Text
, fdFileContents::file}--| Locally saved file.newtypeLocalFilePath=LocalFilePathFilePath--| File contents loaded into memory.newtypeFileContents=FileContentsByteString--| Some file that can be read directly or moved (saved) somewhere.-- Particularly useful for server-side handlers to ignore how server handles uploads.dataSomeFile=SomeFile{someFileSorceRaw::ConduitT()ByteString (ResourceTIO) ()-- I don't really know how to convert this into a simpler type
, someFileMove::FilePath->IO()}
The more I think about it the more it seems like we should just provide common data types and not use type classes 🙃
Surely you'll reconsider this once your head is not upside down anymore. =)
More seriously: I do think typeclasses are useful here, as with captures, query params and what not. The handlers are then allowed to only care about the user's "business types" (e.g data User = User { name :: String, profilePic :: FilePath }, where the picture is uploaded with our machinery and the name sent along in the form). I won't fight people to death on this, of course not, but it would be consistent with everything else. Also, do the From/ToMultipart classes have to be parametrized by what's effectively the backend (file) ? Could we not have:
where KnownBackend would be something similar to what we have in servant-multipart ? Again, I'm not too attached to these suggestions, feel free to dismiss them. The most important thing here for me is to have a story for migrating servant-multipart over to whatever we end up settling on by the time it is ready. :)
If I understand it correctly, MultipartBackend instances specify how to obtain MultipartResult tag values. However you can't really use backend to implement a backend-agnostic FromMultipart instance (because you have to know how to break down MultipartResult tag, but you only know how to make one with backend).
Activity
fizruk commentedon Feb 19, 2018
Related work
Server-side:
servant-multipartimplements server-side code for handling multipart/form-data;yesod-formhas support for file uploads (see Cookbook file upload saving files to server).Client-side:
servant-client;http-client'sNetwork.HTTP.Client.MultipartFormData;telegram-api'sServant.Client.MultipartFormData.EDIT: added
yesod-form.fizruk commentedon Feb 21, 2018
yesod-formalso has support for file upload (see Cookbook file upload saving files to server).File upload field is created using
fileAFormReq. File info is represented withFileInfo:They also seem to have 3 options for handling file uploads (on the server):
Note the last option which is not available with
servant-multipartAFAICT.phadej commentedon Feb 21, 2018
fizruk commentedon Feb 21, 2018
The more I think about it the more it seems like we should just provide common data types and not use type classes 🙃
For instance we could just provide something like this:
Now we could provide classes like
However those are multi parameter and without functional dependencies so are likely to only cause confusion.
Alternatively we could limit
filefor client/server:However those look pretty weird to me, especially with IO actions in
IO ByteStringandSomeFile.So for now I think it would be sufficient to just have common datatypes and functions and not introduce type classes for now.
@alpmestan @phadej do you have any thoughts on this?
alpmestan commentedon Feb 21, 2018
Surely you'll reconsider this once your head is not upside down anymore. =)
More seriously: I do think typeclasses are useful here, as with captures, query params and what not. The handlers are then allowed to only care about the user's "business types" (e.g
data User = User { name :: String, profilePic :: FilePath }, where the picture is uploaded with our machinery and the name sent along in the form). I won't fight people to death on this, of course not, but it would be consistent with everything else. Also, do the From/ToMultipart classes have to be parametrized by what's effectively the backend (file) ? Could we not have:where
KnownBackendwould be something similar to what we have in servant-multipart ? Again, I'm not too attached to these suggestions, feel free to dismiss them. The most important thing here for me is to have a story for migrating servant-multipart over to whatever we end up settling on by the time it is ready. :)fizruk commentedon Feb 21, 2018
@alpmestan I think the problem with
KnownBackendis that you can't easily writeAt least I can't figure out how to do that with
servant-multipart's class:If I understand it correctly,
MultipartBackendinstances specify how to obtainMultipartResult tagvalues. However you can't really usebackendto implement a backend-agnosticFromMultipartinstance (because you have to know how to break downMultipartResult tag, but you only know how to make one withbackend).alpmestan commentedon Feb 21, 2018
Hmm, correct, nevermind my suggestion then!