HTTP Client for MRuby

mruby, Ruby Leave a comment

As Dorthe pointed out, we are on the road for the next two weeks. So, I thought it might be a good idea to put everything together. In the last blog posts, I described

Now in order to construct an alternative to the JavaScript shell “arangosh” for ArangoDB, what is missing is a HTTP client. The JavaScript shell already has a builtin C++ class, so I decided to use the same class for the Ruby version. In principle it would be possible to use curl or other libraries.

The wrapper is straight forward.

static mrb_value ClientConnection_httpGet (mrb_state* mrb, mrb_value self) {
  char* url;
  /* int res; */
  size_t l;
  struct RData* rdata;
  MRubyClientConnection* connection;
 
 /* res = */ mrb_get_args(mrb, "s", &url, &l);
 
  if (url == 0) {
    return self;
  }
 
  // looking at "mruby.h" I assume that is the way to unwrap the pointer
  rdata = (struct RData*) mrb_object(self);
  connection = (MRubyClientConnection*) rdata->data;
 
  if (connection == NULL) {
    printf("unknown connection (TODO raise error)\n");
    return self;
  }
 
  // check header fields
  map headerFields;
 
  // and execute
  return ClientConnection->getData(url, headerFields);
}
 
static void MR_ArangoConnection_Free (mrb_state* mrb, void* p) {
  printf("free of ArangoCollection called\n");
}
 
static const struct mrb_data_type MR_ArangoConnection_Type = {
  "ArangoConnection", MR_ArangoConnection_Free
};
 
static void InitMRClientConnection (MR_state_t* mrs, MRubyClientConnection* connection) {
  struct RClass *rcl;
  mrb_state* mrb;
 
  mrb = &mrs->_mrb;
 
  rcl = mrb_define_class(&mrs->_mrb, "ArangoConnection", mrs->_mrb.object_class);
 
  mrb_define_method(&mrs->_mrb, rcl, "get", ClientConnection_httpGet, ARGS_REQ(1));
 
  // create the connection variable
  mrb_value arango = mrb_obj_value(Data_Wrap_Struct(&mrs->_mrb, rcl, &MR_ArangoConnection_Type, (void*) connection));
  mrb_gv_set(mrb, mrb_intern(mrb, "$arango"), arango);
}

The whole source code can be found on github in MRClient/arangoirb.cpp. You can either use

brew install --HEAD arangodb

or install everything from scratch.

This defines a class ArangoConnection with a method get and a global variable $arango. This now allows to connection to the ArangoDB server.

fceller@opensuse121:~/ArangoDB> ./arangoirb 
                                   _      _     
  __ _ _ __ __ _ _ __   __ _  ___ (_)_ __| |__  
 / _` | '__/ _` | '_ \ / _` |/ _ \| | '__| '_ \ 
| (_| | | | (_| | | | | (_| | (_) | | |  | |_) |
 \__,_|_|  \__,_|_| |_|\__, |\___/|_|_|  |_.__/ 
                       |___/                    

Welcome to arangoirb 0.5.2. Copyright (c) 2012 triAGENS GmbH.
Using MRUBY 2012-05-16 (a3a9d136aa4835eb50f4be92fbbce1ad503ec4c7) engine. Copyright (c) 2012 mruby developers.
Using READLINE 6.2.

Connected to Arango DB 127.0.0.1:8529 Version 0.5.2
arangoirb> $arango
#
arangoirb> $res = $arango.get "/_api/version"
{"server"=>"arango", "version"=>"0.5.2"}
arangoirb> $res["version"]
"0.5.2"
arangoirb> 
Bye Bye! Auf Wiedersehen! さようなら

The next steps are to add the other methods, make it a bit more like HTTParty, and write the server related functions. I’m not really sure, who a good Ruby interface should look like. So, if you happen to be at NoSQL Matters an Tuesday/Wednesday or at the EuRuKo on Friday/Saturday, please contact us. I would really like to discuss this matter with some Ruby experts.

About Frank Celler

Frank is both entrepreneur and backend developer, developing mostly memory databases for two decades. He is the lead developer of ArangoDB and co-founder of triAGENS. Try to challenge Frank asking him questions on C, C++ and MRuby. Besides Frank organizes Cologne’s nosql group & nosql conferences.