Search code examples
restdrupaldrupal-7

Consuming a rest api with Drupal


I am currently maintaining a drupal 7 site. Although I already gained some experience with Drupal my knowledge is still rather low-level and doesn't go beyond installing and configuring modules.

My site is pretty much a metadata repository. People fill in forms about datasets. My problem is probably rather basic (or maybe not - it's hard to say). I need to implement an external file repository. The data repository provides a REST API that should allow the users to upload files to their repository using my drupal site.

After uploading a file the data repository then provides a permanent identifier that I have to save in addition to the other fields.

Now I'm looking for the best way to build a very simple UI that allows users to upload their files to the repository without leaving my drupal site (e.g. while they are in the process of filling in the fields). I also need the liberty to form the URLs needed myself as commands for the API as there are many options that need to be declared. For instance I need to provide a certain token in my URLs for the data repository to be able to identify who's uploading.

I already did some research and found modules like:

https://www.drupal.org/project/wsclient
https://www.drupal.org/project/chr
https://www.drupal.org/project/rest_client

or these topics:

http://drupal.stackexchange.com/questions/42103/how-do-i-consume-rest-as-a-client

https://www.drupal.org/node/1114312

However, I still wasn't able to find out what the best strategy is to implement that. What I need are tips on what the best way is to do that. Currently I don't really know what I'm looking for.

Also I do realise that the are drupal forums where I could ask a question like this, but I have far more better experiences with stackoverflow.

I'd appreciate any help. Thanks


Solution

  • Sorry for answering my own question, but based on the information I got from here: https://drupal.stackexchange.com/questions/42103/how-do-i-consume-rest-as-a-client I was able to solve the problem.

    I wrote a custom drupal module that communicates with the API. Drupal 7 comes with its own function for https requests: https://api.drupal.org/api/drupal/includes%21common.inc/function/drupal_http_request/7.x However, it wasn't enough for my needs as I also neeeded to transfer data, so I ended up using the php library curl (https://curl.haxx.se/), which was built for exactly that purpose. Basically, you install curl on your server where your drupal installation is also running on. Somewhere in your custom module, preferably in a config menu, you can check if the installation was succesful using something like this:

    function _is_curl_installed() {
      if  (in_array  ('curl', get_loaded_extensions())) {
        return true;
      }
      else {
        return false;
      }
    }
    
    if (_is_curl_installed()) {
      drupal_set_message(t('Curl is installed.'));
    } else {
      drupal_set_message(t('Curl is NOT installed.'), 'error');
    }
    

    Drupal should be able to recognise curl automatically after the installation.

    And here is one example for a rest call in drupal using curl (based on this answer how to upload file using curl with php). Keep in mind that the syntax using '@' is outdated and that drupal will complain about it. In my example I used "new CURLFile".

    $request = curl_init($deposit_url);
    curl_setopt($request, CURLOPT_POST, true);
    $cfile = new CURLFile($file_realpath,'application/octet-stream', $base_file_name);
    curl_setopt(
      $request,
      // the content of the array depends on the API you are communicating with
      CURLOPT_POSTFIELDS,
      array(
        'file' => $cfile,
        'access_token' => $temp_token,
        'verify' => false,
      ));
    
    
     curl_setopt($request, CURLOPT_RETURNTRANSFER, true);
     $output= curl_exec($request);
     // output the response
     // drupal_set_message(t('The curl output [1] is '.$output));
     curl_close($request);
    

    I hope this is helpful to someone.

    EDIT: I released a contributed module that solves the described problem: https://www.drupal.org/project/b2share