使用http-conduit在Haskell中发送HTTP/POST的基本方法

Jes*_*wak 1 post haskell functional-programming network-programming http

我正在尝试学习如何使用Haskell通过HTTP/POST发送简单的字符串http-conduit(以便它也适用于https),从文件中读取目标URL,但对我来说似乎仍然有点压倒性.

基本上相当于我在这里学习使用Racket: 在Racket中发送HTTP POST

有人可以给我一个小的或最基本的例子吗?

我试过阅读/sf/answers/942595741/

hao*_*hao 8

当然!这里奇怪的Haskell事情是Haskell的记录系统.当您parseUrl使用URL字符串进行调用时,http-conduit会返回一条Request记录,其中填写了一些默认值,但库要求您填写其余部分.

例如,parseUrl始终返回一个RequestHTTP方法设置为GET.我们可以通过使用记录更新语法覆盖该值 - 您可以使用新键和值附加花括号.

{-# 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)
Run Code Online (Sandbox Code Playgroud)

如果你在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 []))]
Run Code Online (Sandbox Code Playgroud)

您还需要OverloadedStrings扩展.没有它,会发生两件事:

  • nakedRequest { method = "POST" }不会进行类型检查,因为库的预期,一个(严格)ByteStringbytestring库.默认情况下,"POST"所有字符串文字都有类型Stringaka [Char].虽然有一个名为packtake String和returns 的函数ByteString,但打开重载字符串要简单得多.编译器会pack代表您自动调用.还有更多的东西; 请参阅Oliver的博客文章了解细节.

  • 另一个不会进行类型检查的表达方式是send "hello there".send期待一个RequestBody.而且有一个函数在某个地方有类型String -> RequestBody,更容易打开重载的字符串并让编译器为你调用它.

  • 是.在这种情况下,您需要将字符串打包成bytestring,然后使用[这些RequestBody构造函数]之一包装bytestring(http://hackage.haskell.org/package/http-client-0.4.24/docs /Network-HTTP-Client-Internal.html#t:RequestBody). (2认同)