POST JSON para API usando Rails e HTTParty

106

Gostaria que um usuário do meu aplicativo ruby ​​on rails pudesse enviar um tíquete ao meu sistema de gerenciamento de tíquetes externo, squishlist.com. Eles têm uma API e as instruções a seguir. Você precisa se autenticar e obter um token e, em seguida, enviar o tíquete com o token. De squishlist.

# get the token

https://api.squishlist.com/auth/?cfg=testcorp&user_key=privatekey&api_key=TEST-KEY-12345
  => {"token": "authtoken",
      "expires": "2010-06-16 13:31:56"}

# and then the ticket with the token

https://api.squishlist.com/rest/?cfg=testcorp&token=authtoken&method=squish.issue.submit&prj=demo
  POST data: {'issue_type': 1, 'subject': 'Hello, world.', 4: 'Open', 5: 10}

Para fins de teste, criei um controlador, rota e visualização (página) para teste. No meu controlador, tenho o seguinte

require 'httparty'
require 'json'

class SubmitticketController < ApplicationController

    def submit_a_ticket

        @cfg = 'xxxsupport'
        @user_key = '4787fsdbbfbfsdbhbfad5aba91129a3f1ed1b743321f7b'
        @api_key = 'MrUser411'
        @project = 'excelm-manoke'
        @url_new_string = 'https://api.squishlist.com/auth/?cfg='+@cfg+'&user_key='+@user_key+'&api_key='+@api_key
        # https://api.squishlist.com/auth/?cfg=xxxsupport&user_key=4787fsdbbfbfsdbhbfad5aba91129a3f1ed1b743321f7b&api_key=MrUser411  - this is what is created by @url_new_string
        response =  HTTParty.get(@url_new_string.to_str)  #submit the string to get the token
        @parsed_and_a_hash = JSON.parse(response)
        @token = @parsed_and_a_hash["token"]


        #make a new string with the token

        @urlstring_to_post = 'https://api.squishlist.com/rest/?cfg='+@cfg+'&token='+@token+'&method=squish.issue.submit&prj='+@project

        #submit and get a result

        @result = HTTParty.post(@urlstring_to_post.to_str, :body => {:subject => 'This is the screen name', :issue_type => 'Application Problem', :status => 'Open', :priority => 'Normal', :description => 'This is the description for the problem'})

    end

end

E então eu tenho uma página que vou para ver o resultado das ações dos controladores e tem o seguinte código.

<p><%= @result %></p>

Sei que está funcionando em geral por causa das respostas que recebi ao longo do caminho. Meu json é diferente do exemplo por causa dos campos que defini no squishlist. Alguém pode me ajudar nessa questão?

Acho que o verdadeiro problema é que não consigo ver como o json se parece e se está nem perto de combinar. Eu realmente não sei muito sobre json. Devo usar algo que possa ser fácil. Devo usar ajax para enviar isso. Qualquer ajuda é muito apreciada. Eu amo a comunidade aqui.

Homer Jon
fonte

Respostas:

257

Resolvi isso adicionando .to_jsonalgumas informações de cabeçalho

@result = HTTParty.post(@urlstring_to_post.to_str, 
    :body => { :subject => 'This is the screen name', 
               :issue_type => 'Application Problem', 
               :status => 'Open', 
               :priority => 'Normal', 
               :description => 'This is the description for the problem'
             }.to_json,
    :headers => { 'Content-Type' => 'application/json' } )
Homer Jon
fonte
9
Além disso, algumas APIs como a "API GitLab" são sensíveis ao cabeçalho "Aceitar". Portanto, o cabeçalho deve ser :headers => { 'Content-Type' => 'application/json', 'Accept' => 'application/json'}. Observação: o cabeçalho não deve ser convertido para JSON, é esperado que seja um hash
Devaroop
Implantei um motor Rails (empacotado como uma gema) que é realmente útil para depurar APIs em rails. Você só precisa montar o motor e ir até a url que você especificou, ou seja, “localhost: 3000 / api_explorer” para vê-lo. É uma forma de documentar uma API também, lendo a especificação de webservices de um arquivo. A gema se chama 'api_explorer' e o repo é github.com/toptierlabs/api_explorer Quaisquer comentários ou ajuda para melhorar a API são bem-vindos. :)
Tony
6
É simplesmente bobo que isso não esteja na documentação.
Tyler Collier
Obrigado! Isso funcionou muito bem! Mas a pergunta: como você incluiria uma matriz JSON?
Ruben Martinez Jr.
1
Deseja enviar dados de coleta como registros de 90k como no formato acima. Posso enviar dados inteiros em uma única chamada de API? por favor, deixe-me saber seus comentários
Raju Akula
13

A :query_string_normalizeropção também está disponível, que substituirá o normalizador padrãoHashConversions.to_params(query)

query_string_normalizer: ->(query){query.to_json}
Brian McNabb
fonte
Impressionante! Isso permite armazenar o hash, request.options[:body]mas enviar a string correta. Esta deve ser a verdadeira resposta à pergunta.
freemanoid
A opção também pode ser definida como padrão na classe, incluindo HTTParty com o método de classe query_string_normalizer, consulte: ruby-doc.org/gems/docs/h/httparty2-0.7.10/HTTParty/…
Fryie
Também pode ser necessário definir o cabeçalho do tipo de conteúdo: ruby-doc.org/gems/docs/h/httparty2-0.7.10/HTTParty/…
Fryie
1
query_string_normalizerdeve ser usado para strings de consulta, não para postar dados.
josephrider
Os links para ruby-doc.orgestão inoperantes, a documentação está em httparty doc
yacc