PostWith меняет Content-Type моего запроса?

Независимо от того, какое значение я ввожу в качестве "Content-Type" моего запроса, исходящий запрос, который я отправляю, заменяет его на "application/x-www-form-urlencoded". Приложение, которое я пытаюсь открыть, ожидает "application/json". Мой код, в основном, ниже.

{-# LANGUAGE OverloadedStrings #-}

import Network.Wreq

...

submissionResources = ["https://widgets.example.com/v2/widgets/request"]

sendWidgetToEndpoint submissionResources workingToken key widgetArray = do
    let opts            = defaults & header "Content-Type"  .~ ["application/json"]
                                   & header "apikey"        .~ [key]
                                   & header "Authorization" .~ [workingToken]
        endPointURL     = head submissionResources 
        widgetId        = widgetArray !! 0
        numberOfWidgets = widgetArray !! 1
        widgetText      = widgetArray !! 2
    submissionResult <- postWith opts endPointURL [ "widgetId"     := widgetId
                                                  , "numWidgets"   := numberOfWidgets
                                                  , "widgetText"   := widgetText
                                                  ]
    return submissionResult

Моя проблема в том, что я продолжаю возвращаться Status {statusCode = 415, statusMessage = "Unsupported Media Type"}с этой конечной точки, и я уверен, что это связано с тем, что отправляемый мной запрос имеет приоритет над "Content-Type" в моем заголовке. Я пробовал использовать "application / json" и "text/plain", но ответ, который я получаю, всегда указывает мне, что все отправленные мной заголовки выглядят так, как ожидалось, за исключением Content-Type, который неизменно становится "application /x-www. -form-urlencoded".

Как я могу гарантировать, что wreq сохраняет Content-Type: application/json в моем заголовке запроса?

РЕДАКТИРОВАТЬ: Я определяю, какие заголовки были в моем исходном запросе, по тому, что сервер API сообщает мне в своем ответе мне.

1 ответ

Решение

Тип последнего аргумента для postWith в вашем фрагменте [FormParam], и именно этот тип заставляет Content-Type кодировать URL-адрес.

Чтобы отправить JSON, отправьте что-нибудь типа Value или Encoding (из Data.Aeson).

import Data.Aeson (pairs, (.=))

  ...
  -- also remove the "Content-Type" field from opts
  submissionResult <- postWith opts endpointURL $ pairs
    ( "widgetId" .= widgetId <>
      "numWidgets" .= numberOfWidgets <>
      "widgetText" .= widgetText )
  ...

Content-Type устанавливается полезной нагрузкой, которую вы передаете postWith, через Postableпример. Если вы хотите использовать еще один заголовок Content-Type, определите свой собственный тип с помощьюPostableэкземпляр, где вы устанавливаете соответствующий Content-Type. Вы также можете не устанавливать Content-Type вPostable Например, вы можете установить его с помощью параметров.

Другие вопросы по тегам