Arquivo da categoria: REST

HTTP Posts in Ruby

Sometimes I need to make simple HTTP posts in a Ruby script. Using a 3rd party library may be too clunky for such a simple script.

This post helps a lot, but it doesn’t cover all my needs. Specifically, when working with the Switchvox API, the API methods are expected to be a JSON parameter.

Let’s start by imply posting some JSON.

Post some JSON

<code class="prettyprint prettyprinted"><span class="kwd">require</span> <span class="str">'net/http'</span>
<span class="kwd">require</span> <span class="str">'uri'</span>
<span class="kwd">require</span> <span class="str">'json'</span><span class="pln">

uri </span><span class="pun">=</span><span class="pln"> URI</span><span class="pun">.</span><span class="pln">parse</span><span class="pun">(</span><span class="str">"//localhost:3000/users"</span><span class="pun">)</span><span class="pln">

header </span><span class="pun">=</span> <span class="pun">{</span><span class="str">'Content-Type'</span><span class="pun">:</span> <span class="str">'text/json'</span><span class="pun">}</span><span class="pln">
user </span><span class="pun">=</span> <span class="pun">{</span><span class="pln">user</span><span class="pun">:</span> <span class="pun">{</span><span class="pln">
                   name</span><span class="pun">:</span> <span class="str">'Bob'</span><span class="pun">,</span><span class="pln">
                   email</span><span class="pun">:</span> <span class="str">'bob@example.com'</span>
                      <span class="pun">}</span>
            <span class="pun">}</span>

<span class="com"># Create the HTTP objects</span><span class="pln">
http </span><span class="pun">=</span> <span class="typ">Net</span><span class="pun">::</span><span class="pln">HTTP</span><span class="pun">.</span><span class="kwd">new</span><span class="pun">(</span><span class="pln">uri</span><span class="pun">.</span><span class="pln">host</span><span class="pun">,</span><span class="pln"> uri</span><span class="pun">.</span><span class="pln">port</span><span class="pun">)</span><span class="pln">
request </span><span class="pun">=</span> <span class="typ">Net</span><span class="pun">::</span><span class="pln">HTTP</span><span class="pun">::</span><span class="typ">Post</span><span class="pun">.</span><span class="kwd">new</span><span class="pun">(</span><span class="pln">uri</span><span class="pun">.</span><span class="pln">request_uri</span><span class="pun">,</span><span class="pln"> header</span><span class="pun">)</span><span class="pln">
request</span><span class="pun">.</span><span class="pln">body </span><span class="pun">=</span><span class="pln"> user</span><span class="pun">.</span><span class="pln">to_json

</span><span class="com"># Send the request</span><span class="pln">
response </span><span class="pun">=</span><span class="pln"> http</span><span class="pun">.</span><span class="pln">request</span><span class="pun">(</span><span class="pln">request</span><span class="pun">)</span></code>

This will simply submit a POST request with the JSON as the body.

But, there were some methods that required a file be submitted with the JSON? Things get a little more complicated when you do this, but it is still manageable.

Post a file with some JSON

<code class="prettyprint prettyprinted"><span class="kwd">require</span> <span class="str">'net/http'</span>
<span class="kwd">require</span> <span class="str">'uri'</span>
<span class="kwd">require</span> <span class="str">'json'</span>
<span class="kwd">require</span> <span class="str">'mime/types'</span><span class="pln">

uri </span><span class="pun">=</span><span class="pln"> URI</span><span class="pun">.</span><span class="pln">parse</span><span class="pun">(</span><span class="str">"//localhost:3000/users"</span><span class="pun">)</span><span class="pln">
BOUNDARY </span><span class="pun">=</span> <span class="str">"AaB03x"</span><span class="pln">

header </span><span class="pun">=</span> <span class="pun">{</span><span class="str">"Content-Type"</span><span class="pun">:</span> <span class="str">"multipart/form-data, boundary=#{BOUNDARY}"</span><span class="pun">}</span><span class="pln">
user </span><span class="pun">=</span> <span class="pun">{</span><span class="pln">user</span><span class="pun">:</span> <span class="pun">{</span><span class="pln">
                   name</span><span class="pun">:</span> <span class="str">'Bob'</span><span class="pun">,</span><span class="pln">
                   email</span><span class="pun">:</span> <span class="str">'bob@example.com'</span>
                      <span class="pun">}</span>
            <span class="pun">}</span><span class="pln">
file </span><span class="pun">=</span> <span class="str">"test_file.xml"</span>

<span class="com"># We're going to compile all the parts of the body into an array, then join them into one single string</span>
<span class="com"># This method reads the given file into memory all at once, thus it might not work well for large files</span><span class="pln">
post_body </span><span class="pun">=</span> <span class="pun">[]</span>

<span class="com"># Add the file Data</span><span class="pln">
post_body </span><span class="pun">&lt;&lt;</span> <span class="str">"--#{BOUNDARY}\r\n"</span><span class="pln">
post_body </span><span class="pun">&lt;&lt;</span> <span class="str">"Content-Disposition: form-data; name=\"user[][image]\"; filename=\"#{File.bsename(file)}\"\r\n"</span><span class="pln">
post_body </span><span class="pun">&lt;&lt;</span> <span class="str">"Content-Type: #{MIME::Types.type_for(file)}\r\n\r\n"</span><span class="pln">
post_body </span><span class="pun">&lt;&lt;</span> <span class="typ">File</span><span class="pun">.</span><span class="pln">read</span><span class="pun">(</span><span class="pln">file</span><span class="pun">)</span>

<span class="com"># Add the JSON</span><span class="pln">
post_body </span><span class="pun">&lt;&lt;</span> <span class="str">"--#{BOUNDARY}\r\n"</span><span class="pln">
post_body </span><span class="pun">&lt;&lt;</span> <span class="str">"Content-Disposition: form-data; name=\"user[]\"\r\n\r\n"</span><span class="pln">
post_body </span><span class="pun">&lt;&lt;</span><span class="pln"> user</span><span class="pun">.</span><span class="pln">to_json
post_body </span><span class="pun">&lt;&lt;</span> <span class="str">"\r\n\r\n--#{BOUNDARY}--\r\n"</span>

<span class="com"># Create the HTTP objects</span><span class="pln">
http </span><span class="pun">=</span> <span class="typ">Net</span><span class="pun">::</span><span class="pln">HTTP</span><span class="pun">.</span><span class="kwd">new</span><span class="pun">(</span><span class="pln">uri</span><span class="pun">.</span><span class="pln">host</span><span class="pun">,</span><span class="pln"> uri</span><span class="pun">.</span><span class="pln">port</span><span class="pun">)</span><span class="pln">
request </span><span class="pun">=</span> <span class="typ">Net</span><span class="pun">::</span><span class="pln">HTTP</span><span class="pun">::</span><span class="typ">Post</span><span class="pun">.</span><span class="kwd">new</span><span class="pun">(</span><span class="pln">uri</span><span class="pun">.</span><span class="pln">request_uri</span><span class="pun">,</span><span class="pln"> header</span><span class="pun">)</span><span class="pln">
request</span><span class="pun">.</span><span class="pln">body </span><span class="pun">=</span><span class="pln"> post_body</span><span class="pun">.</span><span class="kwd">join</span>

<span class="com"># Send the request</span><span class="pln">
response </span><span class="pun">=</span><span class="pln"> http</span><span class="pun">.</span><span class="pln">request</span><span class="pun">(</span><span class="pln">request</span><span class="pun">)</span></code>

And there you have it! A multipart HTTP Post in Ruby without an external library. You can probably see how you could add multiple files and sets JSON objects.

Is it worth not using a 3rd party library and doing it yourself?

//coderwall.com/p/c-mu-a/http-posts-in-ruby

Salvando imagens Base64 via Web Service REST – Java/Jersey

...
import java.io.ByteArrayInputStrem;
import Javax.ws.rs.FormParam;
import org.apache.commons.io.IOUtils;
...
public class CarResource {
  ...
  @Post
  @Path("/postPhotoBase64")
  @Cunsumes(MediaType.APPLICATION_FORM_URLENCODED)
  public Response postPhotoBase64(@FormParam("fileName") String fileName, @FormParam("base64") String base64) {
    ...
    byte[] bytes = Base64.getDecoder().decode(base64);
    InputStream in = new ByteArrayInputStream(bytes);
    File tmpDir = new File(System.getProperty("java.io.tmpdir"), "cars");
    if (!tmpDir.exists()) {
      tmpDir.mkdir();
    }
    File file = new File(tmpDir, "Nome_Arquivo");
    FileOutputStream out = new FileOutputStream(file);
    IOUtils.copy(in, out);
    IOUtils.closeQuietly(out);
  }
}