Как отправить JSON как данные формы, используя метод поста Фарадея
Как мне отправить этот JSON в Фарадее, используя метод post с "application/x-www-form-urlencoded" и "multipart/form-data;" заголовки?
message = {
"name":"John",
"age":30,
"cars": {
"car1":"Ford",
"car2":"BMW",
"car3":"Fiat"
}
}
Я пробовал:
conn = Faraday.new(url: "http://localhost:8081") do |f|
f.request :multipart
f.request :url_encoded
f.adapter :net_http
end
conn.post("/", message)
Этот запрос cURL работает
curl -X POST \
http://localhost:8081 \
-H 'Content-Type: application/x-www-form-urlencoded' \
-H 'content-type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW' \
-F 'message=2018-12-27 12:52' \
-F source=RDW \
-F object_type=Responses
Но я не совсем понимаю, как заставить это работать в Фарадее. Кроме того, данные в запросе cURL не являются вложенным JSON, поэтому мне нужно иметь возможность динамически создавать тело запроса, так как я не буду заранее знать точную структуру JSON.
И, пожалуйста, задавайте любые вопросы, если вам нужно больше деталей или ясности.
Спасибо!
1 ответ
Тип содержимого по умолчанию для POST x-www-form-urlencoded
поэтому хеш будет автоматически закодирован. Для JSON такой автоматической обработки данных не существует, поэтому второй приведенный ниже пример передает строковое представление хэша.
Faraday.new(url: 'http://localhost:8081').post('/endpoint', {foo: 1, bar: 2})
# => POST http://localhost:8081/endpoint
# with body 'bar=2&foo=1'
# including header 'Content-Type'=>'application/x-www-form-urlencoded'
Faraday.new(url: 'http://localhost:8081').post('/endpoint', {foo: 1, bar: 2}.to_json, {'Content-Type'=>'application/json'})
# => POST http://localhost:8081/endpoint
# with body '{"foo":1,"bar":2}'
# including header 'Content-Type'=>'application/json'
Я не уверен, что вы собираетесь делать, но вы могли бы отправить что-то вроде следующего
Faraday.new(url: 'http://localhost:8081').post('/endpoint', {foo: 1, bar: 2}.to_json)
# => POST http://localhost:8081/endpoint
# with body '{"foo":1,"bar":2}'
# including header 'Content-Type'=>'application/x-www-form-urlencoded'
Однако это будет интерпретировано как {"{\"foo\":1,\"bar\":2}" => nil}
в рубине. Если вы анализируете данные на другом конце, вы можете заставить их работать, но всегда сложнее бороться с соглашением.
Для запросов POST Фарадей хочет, чтобы данные формы были строкой JSON, а не хешем Ruby. Это легко сделать с помощью gem-кода json Hash#to_json
метод так:
require 'json'
url = 'http://localhost:8081'
form_data = {
name: 'John',
age: '30',
cars: {
car1: 'Ford',
car2: 'BMW',
car3: 'Fiat'
}
}.to_json
headers = {}
Faraday.post(url, form_data, headers)
или в вашем случае просто:
conn = Faraday.new(url: "http://localhost:8081") do |f|
f.request :multipart
f.request :url_encoded
f.adapter :net_http
end
# exact same code, except just need to call rrequire json and call to_json here
require 'json'
conn.post("/", message.to_json)