![](/img/trans.png)
[英]How can I post FileInfo to a web service using Yesod and Http-Conduit?
[英]Basic way of sending HTTP/POST in Haskell using http-conduit
我正在嘗試學習如何使用Haskell和http-conduit
通過HTTP / POST發送簡單的字符串(以便它也可以與https一起使用),從文件中讀取目標網址,但對我來說似乎仍然有些不知所措。
基本上等同於我在這里學到的關於Racket的知識: 在Racket中發送HTTP POST
有人可以給我一個小的或最基本的例子嗎?
當然! 需要注意的怪異的Haskell事情是Haskell的記錄系統。 當您使用URL字符串調用parseUrl
時, http-conduit
會向您返回一個Request
記錄,其中填充了一些默認值,但是庫希望您填寫其余的值。
例如, parseUrl
始終返回HTTP方法設置為GET的Request
。 我們需要使用記錄更新語法來覆蓋該值,在這種情況下,您需要在花括號后面附加新的鍵和值。
{-# LANGUAGE OverloadedStrings #-}
module Lib where
import Data.Aeson
import Network.HTTP.Client
buildRequest :: String -> RequestBody -> IO Request
buildRequest url body = do
nakedRequest <- parseRequest url
return (nakedRequest { method = "POST", requestBody = body })
send :: RequestBody -> IO ()
send s = do
manager <- newManager defaultManagerSettings
request <- buildRequest "http://httpbin.org/post" s
response <- httpLbs request manager
let Just obj = decode (responseBody response)
print (obj :: Object)
如果您在GHCi中運行此程序,則應該能夠將POST發送到httpbin:
λ> :set -XOverloadedStrings
λ> send "hello there"
fromList [("origin",String "<snip>")
,("args",Object (fromList []))
,("json",Null)
,("data",String "hello there")
,("url",String "http://httpbin.org/post")
,("headers",Object (fromList [("Accept-Encoding",String "gzip")
,("Host",String "httpbin.org")
,("Content-Length",String "11")]))
,("files",Object (fromList []))
,("form",Object (fromList []))]
您還需要OverloadedStrings擴展。 沒有它,將發生兩件事:
nakedRequest { method = "POST" }
將不會進行類型檢查,因為該庫需要bytestring
nakedRequest { method = "POST" }
庫中的(嚴格) ByteString
。 默認情況下, "POST"
和所有字符串文字的類型均為String
aka [Char]
。 雖然有一個名為pack
的函數接受String
並返回ByteString
,但是打開重載的字符串要簡單得多。 編譯器會自動代表您調用pack
。 不僅如此,還有更多。 有關細節的詳細信息,請參見Oliver的博客文章 。
不會進行類型檢查的另一個表達式是send "hello there"
。 send
期望一個RequestBody
。 再說一次,某個地方的函數的類型為String -> RequestBody
,打開重載的字符串並讓編譯器為您調用它要容易得多。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.