How to use external JSON API to create/update node's fields? I have a content type: siteinfo.

This content type has multiple fields: text, entity reference etc.

I want to use an external API to automatically fill some fields of the created node.

The API I want to use says that:


  API returns consistent and well-structured data in XML &amp; JSON
  format. Returned data contains parsed fields that can easily be
  used by your application. This is a RESTful based API.



And this is the API's output:

{
    "status": 1,
    "api_query": "siteinfo",
    "whois_record": {
        "domain_name": "example.com",
        "query_time": "2016-05-05 14:01:12",
        "create_date": "1995-08-14",
        "update_date": "2015-08-14",
        "expiry_date": "2016-08-13",
        "domain_registrar": {
            "iana_id": 376,
            "registrar_name": "RESERVED-INTERNET ASSIGNED NUMBERS AUTHORITY",
            "whois_server": "whois.iana.org",
            "referral_url": "http://res-dom.iana.org"
        },
        "name_servers": [
            "a.iana-servers.net",
            "b.iana-servers.net"
        ],
    },
}






How can I use this external API?
If there's no complicated authentication/request method for the service (e.g. a simple HTTP GET for http://service.example.com/api/siteinfo/1), then a combination of Feeds, Feeds extensible parsers, &amp; Libraries with the JMESPath library installed works great here. 

The Feeds module has an HTTP fetcher that can be used in conjunction with the JSON JMESPath parser that allows you to enter JMESPath queries for each field you want parse and insert/update into a node (e.g. in the parser settings you'd could put "@" (root) as the Context &amp; "whois_record. domain_name" if you wanted to map that object's property to a node field).

In this solution, Feeds is handling the import/update bookkeeping while you're tasked with figuring out the correct queries to parse the data. If you go this path, it's very helpful to study JMESPath syntax while using the Feeds Import Preview module to test your imports before execution.

If you need your URL to vary for each import, you can wrap a programmatic invocation of a Feeds import into a function and call it for each imported URL in a drush eval or some other arbitrary location in your environment. For example:

//$url = Is your imported feed.
//$my_feed = Your imported feed machine name 
//(i.e. the MY_FEED_MACHINE_NAME in http://example.com/import/MY_FEED_MACHINE_NAME)
function MYMODULE_import_feed($url, $my_feed) {
  $feeds_source = feeds_source($my_feed);
  $feeds_config = $feeds_source-&gt;getConfigFor($feeds_source-&gt;importer-&gt;fetcher);
  $feeds_config['source'] = $url;
  $feeds_source-&gt;setConfigFor($feeds_source-&gt;importer-&gt;fetcher, $feeds_config);
  $feeds_source-&gt;save();
  $feeds_source-&gt;startImport();
}

//Example execution 
function MYMODULE_cron() {
  $import_titles = array('title_1', 'title_2');
  foreach ($import_titles as $title) {
    MYMODULE_import_feed("http://service.example.com/api/siteinfo/$title",'MY_FEED_MACHINE_NAME');
  }
}